Changes in / [b5ec090:56e5b24]


Ignore:
Files:
10 edited

Legend:

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

    rb5ec090 r56e5b24  
    33% Just a little knot to tie the paper together.
    44
    5 In the previous chapters, this thesis presents the design and implementation
     5In the previous chapters this thesis presents the design and implementation
    66of \CFA's exception handling mechanism (EHM).
    77Both the design and implementation are based off of tools and
    88techniques developed for other programming languages but they were adapted to
    99better fit \CFA's feature set and add a few features that do not exist in
    10 other EHMs,
     10other EHMs;
    1111including conditional matching, default handlers for unhandled exceptions
    1212and cancellation though coroutines and threads back to the program main stack.
  • doc/theses/andrew_beach_MMath/existing.tex

    rb5ec090 r56e5b24  
    66compatibility with C and its programmers.  \CFA is designed to have an
    77orthogonal feature-set based closely on the C programming paradigm
    8 (non-object-oriented), and these features can be added incrementally to an
    9 existing C code-base,
    10 allowing programmers to learn \CFA on an as-needed basis.
     8(non-object-oriented) and these features can be added incrementally to an
     9existing C code-base allowing programmers to learn \CFA on an as-needed basis.
    1110
    1211Only those \CFA features pertaining to this thesis are discussed.
     
    4645\CFA adds a reference type to C as an auto-dereferencing pointer.
    4746They work very similarly to pointers.
    48 Reference-types are written the same way as pointer-types, but each
     47Reference-types are written the same way as a pointer-type but each
    4948asterisk (@*@) is replaced with a ampersand (@&@);
    50 this includes cv-qualifiers (\snake{const} and \snake{volatile})
    51 %\todo{Should I go into even more detail on cv-qualifiers.}
    52 and multiple levels of reference.
    53 
    54 Generally, references act like pointers with an implicit dereferencing
     49this includes cv-qualifiers and multiple levels of reference.
     50
     51Generally, references act like pointers with an implicate dereferencing
    5552operation added to each use of the variable.
    5653These automatic dereferences may be disabled with the address-of operator
     
    8683Mutable references may be assigned to by converting them to a pointer
    8784with a @&@ and then assigning a pointer to them, as in @&ri = &j;@ above.
     85% ???
    8886
    8987\section{Operators}
     
    9593For example,
    9694infixed multiplication is @?*?@, while prefix dereference is @*?@.
    97 This syntax makes it easy to tell the difference between prefix operations
    98 (such as @++?@) and postfix operations (@?++@).
     95This syntax make it easy to tell the difference between prefix operations
     96(such as @++?@) and post-fix operations (@?++@).
    9997
    10098As an example, here are the addition and equality operators for a point type.
     
    106104}
    107105\end{cfa}
    108 Note that this syntax works effectively as a textual transformation;
     106Note that this syntax works effectively but a textual transformation,
    109107the compiler converts all operators into functions and then resolves them
    110108normally. This means any combination of types may be used,
     
    115113%\subsection{Constructors and Destructors}
    116114In \CFA, constructors and destructors are operators, which means they are
    117 functions with special operator names, rather than type names as in \Cpp.
     115functions with special operator names rather than type names in \Cpp.
    118116Both constructors and destructors can be implicity called by the compiler,
    119117however the operator names allow explicit calls.
     
    139137@b@ because of the explicit call and @a@ implicitly.
    140138@c@ will be initalized with the second constructor.
    141 Currently, there is no general way to skip initialization.
     139Currently, there is no general way to skip initialation.
    142140% I don't use @= anywhere in the thesis.
    143141
     
    204202do_twice(i);
    205203\end{cfa}
    206 Any value with a type fulfilling the assertion may be passed as an argument to
     204Any object with a type fulfilling the assertion may be passed as an argument to
    207205a @do_twice@ call.
    208206
     
    224222function. The matched assertion function is then passed as a function pointer
    225223to @do_twice@ and called within it.
    226 The global definition of @do_once@ is ignored, however if @quadruple@ took a
     224The global definition of @do_once@ is ignored, however if quadruple took a
    227225@double@ argument, then the global definition would be used instead as it
    228226would then be a better match.\cite{Moss19}
    229227
    230228To avoid typing long lists of assertions, constraints can be collected into
    231 a convenient package called a @trait@, which can then be used in an assertion
     229convenient a package called a @trait@, which can then be used in an assertion
    232230instead of the individual constraints.
    233231\begin{cfa}
     
    243241functions and variables, and are usually used to create a shorthand for, and
    244242give descriptive names to, common groupings of assertions describing a certain
    245 functionality, like @summable@, @listable@, \etc.
     243functionality, like @sumable@, @listable@, \etc.
    246244
    247245Polymorphic structures and unions are defined by qualifying an aggregate type
    248246with @forall@. The type variables work the same except they are used in field
    249 declarations instead of parameters, returns and local variable declarations.
     247declarations instead of parameters, returns, and local variable declarations.
    250248\begin{cfa}
    251249forall(dtype T)
     
    263261
    264262\section{Control Flow}
    265 \CFA has a number of advanced control-flow features: @generator@, @coroutine@,
    266 @monitor@, @mutex@ parameters, and @thread@.
     263\CFA has a number of advanced control-flow features: @generator@, @coroutine@, @monitor@, @mutex@ parameters, and @thread@.
    267264The two features that interact with
    268265the exception system are @coroutine@ and @thread@; they and their supporting
     
    271268\subsection{Coroutine}
    272269A coroutine is a type with associated functions, where the functions are not
    273 required to finish execution when control is handed back to the caller.
    274 Instead,
     270required to finish execution when control is handed back to the caller. Instead
    275271they may suspend execution at any time and be resumed later at the point of
    276 last suspension.
    277 Coroutine
     272last suspension. (Generators are stackless and coroutines are stackful.) These
    278273types are not concurrent but share some similarities along with common
    279 underpinnings, so they are combined with the \CFA threading library.
    280 % I had mention of generators, but they don't actually matter here.
     274underpinnings, so they are combined with the \CFA threading library. Further
     275discussion in this section only refers to the coroutine because generators are
     276similar.
    281277
    282278In \CFA, a coroutine is created using the @coroutine@ keyword, which is an
     
    326322\end{cfa}
    327323
    328 When the main function returns, the coroutine halts and can no longer be
     324When the main function returns the coroutine halts and can no longer be
    329325resumed.
    330326
    331327\subsection{Monitor and Mutex Parameter}
    332 Concurrency does not guarantee ordering; without ordering, results are
     328Concurrency does not guarantee ordering; without ordering results are
    333329non-deterministic. To claw back ordering, \CFA uses monitors and @mutex@
    334330(mutual exclusion) parameters. A monitor is another kind of aggregate, where
     
    336332@mutex@ parameters.
    337333
    338 A function that requires deterministic (ordered) execution acquires mutual
     334A function that requires deterministic (ordered) execution, acquires mutual
    339335exclusion on a monitor object by qualifying an object reference parameter with
    340 the @mutex@ qualifier.
     336@mutex@.
    341337\begin{cfa}
    342338void example(MonitorA & mutex argA, MonitorB & mutex argB);
     
    348344
    349345\subsection{Thread}
    350 Functions, generators and coroutines are sequential, so there is only a single
     346Functions, generators, and coroutines are sequential so there is only a single
    351347(but potentially sophisticated) execution path in a program. Threads introduce
    352348multiple execution paths that continue independently.
    353349
    354350For threads to work safely with objects requires mutual exclusion using
    355 monitors and mutex parameters. For threads to work safely with other threads
     351monitors and mutex parameters. For threads to work safely with other threads,
    356352also requires mutual exclusion in the form of a communication rendezvous, which
    357353also supports internal synchronization as for mutex objects. For exceptions,
  • doc/theses/andrew_beach_MMath/features.tex

    rb5ec090 r56e5b24  
    55and begins with a general overview of EHMs. It is not a strict
    66definition of all EHMs nor an exhaustive list of all possible features.
    7 However, it does cover the most common structure and features found in them.
     7However it does cover the most common structure and features found in them.
    88
    99\section{Overview of EHMs}
     
    4242
    4343The @try@ statements of \Cpp, Java and Python are common examples. All three
    44 also show another common feature of handlers: they are grouped by the guarded
     44also show another common feature of handlers, they are grouped by the guarded
    4545region.
    4646
     
    101101between different sub-hierarchies.
    102102This design is used in \CFA even though it is not a object-orientated
    103 language, so different tools are used to create the hierarchy.
     103language; so different tools are used to create the hierarchy.
    104104
    105105% Could I cite the rational for the Python IO exception rework?
     
    118118For effective exception handling, additional information is often passed
    119119from the raise to the handler and back again.
    120 So far, only communication of the exception's identity is covered.
     120So far, only communication of the exceptions' identity is covered.
    121121A common communication method for adding information to an exception
    122122is putting fields into the exception instance
     
    129129\section{Virtuals}
    130130\label{s:virtuals}
    131 %\todo{Maybe explain what "virtual" actually means.}
    132131Virtual types and casts are not part of \CFA's EHM nor are they required for
    133132an EHM.
     
    153152% A type's descendants are its children and its children's descendants.
    154153
    155 For the purposes of illustration, a proposed, but unimplemented, syntax
     154For the purposes of illustration, a proposed -- but unimplemented syntax --
    156155will be used. Each virtual type is represented by a trait with an annotation
    157156that makes it a virtual type. This annotation is empty for a root type, which
     
    178177\end{minipage}
    179178
    180 Every virtual type also has a list of virtual members and a unique id.
    181 Both are stored in a virtual table.
     179Every virtual type also has a list of virtual members and a unique id,
     180both are stored in a virtual table.
    182181Every instance of a virtual type also has a pointer to a virtual table stored
    183182in it, although there is no per-type virtual table as in many other languages.
    184183
    185 The list of virtual members is accumulated from the root type down the tree.
    186 Every virtual type
     184The list of virtual members is built up down the tree. Every virtual type
    187185inherits the list of virtual members from its parent and may add more
    188186virtual members to the end of the list which are passed on to its children.
     
    200198% Consider adding a diagram, but we might be good with the explanation.
    201199
    202 As @child_type@ is a child of @root_type@, it has the virtual members of
     200As @child_type@ is a child of @root_type@ it has the virtual members of
    203201@root_type@ (@to_string@ and @size@) as well as the one it declared
    204202(@irrelevant_function@).
     
    208206The names ``size" and ``align" are reserved for the size and alignment of the
    209207virtual type, and are always automatically initialized as such.
    210 The other special case is uses of the trait's polymorphic argument
     208The other special case are uses of the trait's polymorphic argument
    211209(@T@ in the example), which are always updated to refer to the current
    212 virtual type. This allows functions that refer to the polymorphic argument
     210virtual type. This allows functions that refer to to polymorphic argument
    213211to act as traditional virtual methods (@to_string@ in the example), as the
    214212object can always be passed to a virtual method in its virtual table.
    215213
    216 Up until this point, the virtual system is similar to ones found in
    217 object-oriented languages, but this is where \CFA diverges.
     214Up until this point the virtual system is similar to ones found in
     215object-oriented languages but this is where \CFA diverges.
    218216Objects encapsulate a single set of methods in each type,
    219217universally across the entire program,
     
    225223
    226224In \CFA, types do not encapsulate any code.
    227 Whether or not a type satisfies any given assertion, and hence any trait, is
     225Whether or not satisfies any given assertion, and hence any trait, is
    228226context sensitive. Types can begin to satisfy a trait, stop satisfying it or
    229227satisfy the same trait at any lexical location in the program.
    230 In this sense, a type's implementation in the set of functions and variables
     228In this sense, an type's implementation in the set of functions and variables
    231229that allow it to satisfy a trait is ``open" and can change
    232230throughout the program.
     
    250248\end{cfa}
    251249
    252 Like any variable, they may be forward declared with the @extern@ keyword.
     250Like any variable they may be forward declared with the @extern@ keyword.
    253251Forward declaring virtual tables is relatively common.
    254252Many virtual types have an ``obvious" implementation that works in most
     
    261259Initialization is automatic.
    262260The type id and special virtual members ``size" and ``align" only depend on
    263 the virtual type, which is fixed given the type of the virtual table, and
     261the virtual type, which is fixed given the type of the virtual table and
    264262so the compiler fills in a fixed value.
    265 The other virtual members are resolved using the best match to the member's
     263The other virtual members are resolved, using the best match to the member's
    266264name and type, in the same context as the virtual table is declared using
    267265\CFA's normal resolution rules.
    268266
    269 While much of the virtual infrastructure has been created,
    270 it is currently only used
     267While much of the virtual infrastructure is created, it is currently only used
    271268internally for exception handling. The only user-level feature is the virtual
    272269cast, which is the same as the \Cpp \code{C++}{dynamic_cast}.
     
    277274Note, the syntax and semantics matches a C-cast, rather than the function-like
    278275\Cpp syntax for special casts. Both the type of @EXPRESSION@ and @TYPE@ must be
    279 pointers to virtual types.
     276a pointer to a virtual type.
    280277The cast dynamically checks if the @EXPRESSION@ type is the same or a sub-type
    281278of @TYPE@, and if true, returns a pointer to the
    282279@EXPRESSION@ object, otherwise it returns @0p@ (null pointer).
    283 This allows the expression to be used as both a cast and a type check.
    284280
    285281\section{Exceptions}
    286282
    287283The syntax for declaring an exception is the same as declaring a structure
    288 except the keyword:
     284except the keyword that is swapped out:
    289285\begin{cfa}
    290286exception TYPE_NAME {
     
    293289\end{cfa}
    294290
    295 Fields are filled in the same way as a structure as well. However, an extra
     291Fields are filled in the same way as a structure as well. However an extra
    296292field is added that contains the pointer to the virtual table.
    297293It must be explicitly initialized by the user when the exception is
     
    303299
    304300\begin{minipage}[t]{0.4\textwidth}
    305 Header (.hfa):
     301Header:
    306302\begin{cfa}
    307303exception Example {
     
    314310\end{minipage}
    315311\begin{minipage}[t]{0.6\textwidth}
    316 Implementation (.cfa):
     312Source:
    317313\begin{cfa}
    318314vtable(Example) example_base_vtable
     
    323319%\subsection{Exception Details}
    324320This is the only interface needed when raising and handling exceptions.
    325 However, it is actually a shorthand for a more complex
    326 trait-based interface.
     321However it is actually a short hand for a more complex
     322trait based interface.
    327323
    328324The language views exceptions through a series of traits.
     
    340336completing the virtual system). The imaginary assertions would probably come
    341337from a trait defined by the virtual system, and state that the exception type
    342 is a virtual type,
    343 that that the type is a descendant of @exception_t@ (the base exception type)
     338is a virtual type, is a descendant of @exception_t@ (the base exception type)
    344339and allow the user to find the virtual table type.
    345340
     
    360355};
    361356\end{cfa}
    362 Both traits ensure a pair of types is an exception type and
    363 its virtual table type,
     357Both traits ensure a pair of types is an exception type, its virtual table
     358type
    364359and defines one of the two default handlers. The default handlers are used
    365 as fallbacks and are discussed in detail in \autoref{s:ExceptionHandling}.
     360as fallbacks and are discussed in detail in \vref{s:ExceptionHandling}.
    366361
    367362However, all three of these traits can be tricky to use directly.
    368363While there is a bit of repetition required,
    369364the largest issue is that the virtual table type is mangled and not in a user
    370 facing way. So, these three macros are provided to wrap these traits to
     365facing way. So these three macros are provided to wrap these traits to
    371366simplify referring to the names:
    372367@IS_EXCEPTION@, @IS_TERMINATION_EXCEPTION@ and @IS_RESUMPTION_EXCEPTION@.
     
    376371The second (optional) argument is a parenthesized list of polymorphic
    377372arguments. This argument is only used with polymorphic exceptions and the
    378 list is passed to both types.
     373list is be passed to both types.
    379374In the current set-up, the two types always have the same polymorphic
    380 arguments, so these macros can be used without losing flexibility.
    381 
    382 For example, consider a function that is polymorphic over types that have a
     375arguments so these macros can be used without losing flexibility.
     376
     377For example consider a function that is polymorphic over types that have a
    383378defined arithmetic exception:
    384379\begin{cfa}
     
    393388These twin operations are the core of \CFA's exception handling mechanism.
    394389This section covers the general patterns shared by the two operations and
    395 then goes on to cover the details of each individual operation.
     390then goes on to cover the details each individual operation.
    396391
    397392Both operations follow the same set of steps.
     
    412407\label{s:Termination}
    413408Termination handling is the familiar kind of handling
    414 used in most programming
     409and used in most programming
    415410languages with exception handling.
    416411It is a dynamic, non-local goto. If the raised exception is matched and
     
    488483Since it is so general, a more specific handler can be defined,
    489484overriding the default behaviour for the specific exception types.
    490 %\todo{Examples?}
    491485
    492486\subsection{Resumption}
     
    548542@EXCEPTION_TYPE@$_i$ is matched and @NAME@$_i$ is bound to the exception,
    549543@HANDLER_BLOCK@$_i$ is executed right away without first unwinding the stack.
    550 After the block has finished running, control jumps to the raise site, where
     544After the block has finished running control jumps to the raise site, where
    551545the just handled exception came from, and continues executing after it,
    552546not after the try statement.
    553 %\todo{Examples?}
    554547
    555548\subsubsection{Resumption Marking}
     
    558551not unwind the stack. A side effect is that, when a handler is matched
    559552and run, its try block (the guarded statements) and every try statement
    560 searched before it are still on the stack. Their presence can lead to
     553searched before it are still on the stack. There presence can lead to
    561554the recursive resumption problem.\cite{Buhr00a}
    562555% Other possible citation is MacLaren77, but the form is different.
     
    592585\end{center}
    593586
    594 There are other sets of marking rules that could be used.
    595 For instance, marking just the handlers that caught the exception
     587There are other sets of marking rules that could be used,
     588for instance, marking just the handlers that caught the exception,
    596589would also prevent recursive resumption.
    597 However, the rules selected mirror what happens with termination,
     590However, the rules selected mirrors what happens with termination,
    598591so this reduces the amount of rules and patterns a programmer has to know.
    599592
     
    635628// Handle a failure relating to f2 further down the stack.
    636629\end{cfa}
    637 In this example, the file that experienced the IO error is used to decide
     630In this example the file that experienced the IO error is used to decide
    638631which handler should be run, if any at all.
    639632
     
    664657
    665658\subsection{Comparison with Reraising}
    666 In languages without conditional catch -- that is, no ability to match an
    667 exception based on something other than its type -- it can be mimicked
     659In languages without conditional catch, that is no ability to match an
     660exception based on something other than its type, it can be mimicked
    668661by matching all exceptions of the right type, checking any additional
    669662conditions inside the handler and re-raising the exception if it does not
     
    671664
    672665Here is a minimal example comparing both patterns, using @throw;@
    673 (no operand) to start a re-raise.
     666(no argument) to start a re-raise.
    674667\begin{center}
    675668\begin{tabular}{l r}
     
    699692\end{tabular}
    700693\end{center}
    701 At first glance, catch-and-reraise may appear to just be a quality-of-life
     694At first glance catch-and-reraise may appear to just be a quality of life
    702695feature, but there are some significant differences between the two
    703 strategies.
     696stratagies.
    704697
    705698A simple difference that is more important for \CFA than many other languages
    706 is that the raise site changes with a re-raise, but does not with a
     699is that the raise site changes, with a re-raise but does not with a
    707700conditional catch.
    708701This is important in \CFA because control returns to the raise site to run
    709 the per-site default handler. Because of this, only a conditional catch can
     702the per-site default handler. Because of this only a conditional catch can
    710703allow the original raise to continue.
    711704
     
    760753%   } else throw;
    761754% }
    762 In similar simple examples, translating from re-raise to conditional catch
    763 takes less code but it does not have a general, trivial solution either.
     755In similar simple examples translating from re-raise to conditional catch
     756takes less code but it does not have a general trivial solution either.
    764757
    765758So, given that the two patterns do not trivially translate into each other,
    766759it becomes a matter of which on should be encouraged and made the default.
    767 From the premise that if a handler could handle an exception then it
     760From the premise that if a handler that could handle an exception then it
    768761should, it follows that checking as many handlers as possible is preferred.
    769 So, conditional catch and checking later handlers is a good default.
     762So conditional catch and checking later handlers is a good default.
    770763
    771764\section{Finally Clauses}
    772765\label{s:FinallyClauses}
    773 Finally clauses are used to perform unconditional cleanup when leaving a
     766Finally clauses are used to preform unconditional clean-up when leaving a
    774767scope and are placed at the end of a try statement after any handler clauses:
    775768\begin{cfa}
     
    789782Execution of the finally block should always finish, meaning control runs off
    790783the end of the block. This requirement ensures control always continues as if
    791 the finally clause is not present, \ie finally is for cleanup, not changing
     784the finally clause is not present, \ie finally is for cleanup not changing
    792785control flow.
    793786Because of this requirement, local control flow out of the finally block
    794787is forbidden. The compiler precludes any @break@, @continue@, @fallthru@ or
    795788@return@ that causes control to leave the finally block. Other ways to leave
    796 the finally block, such as a @longjmp@ or termination are much harder to check,
    797 and at best require additional run-time overhead, and so are only
     789the finally block, such as a long jump or termination are much harder to check,
     790and at best requiring additional run-time overhead, and so are only
    798791discouraged.
    799792
    800 Not all languages with unwinding have finally clauses. Notably, \Cpp does
     793Not all languages with unwinding have finally clauses. Notably \Cpp does
    801794without it as destructors, and the RAII design pattern, serve a similar role.
    802795Although destructors and finally clauses can be used for the same cases,
     
    805798Destructors take more work to create, but if there is clean-up code
    806799that needs to be run every time a type is used, they are much easier
    807 to set up for each use. % It's automatic.
    808 On the other hand, finally clauses capture the local context, so are easy to
    809 use when the cleanup is not dependent on the type of a variable or requires
     800to set-up for each use. % It's automatic.
     801On the other hand finally clauses capture the local context, so is easy to
     802use when the clean-up is not dependent on the type of a variable or requires
    810803information from multiple variables.
    811804
     
    814807Cancellation is a stack-level abort, which can be thought of as as an
    815808uncatchable termination. It unwinds the entire current stack, and if
    816 possible, forwards the cancellation exception to a different stack.
     809possible forwards the cancellation exception to a different stack.
    817810
    818811Cancellation is not an exception operation like termination or resumption.
    819812There is no special statement for starting a cancellation; instead the standard
    820 library function @cancel_stack@ is called, passing an exception. Unlike a
    821 raise, this exception is not used in matching, only to pass information about
     813library function @cancel_stack@ is called passing an exception. Unlike a
     814raise, this exception is not used in matching only to pass information about
    822815the cause of the cancellation.
    823816Finally, as no handler is provided, there is no default handler.
    824817
    825 After @cancel_stack@ is called, the exception is copied into the EHM's memory
     818After @cancel_stack@ is called the exception is copied into the EHM's memory
    826819and the current stack is unwound.
    827820The behaviour after that depends on the kind of stack being cancelled.
    828821
    829822\paragraph{Main Stack}
    830 The main stack is the one used by
    831 the program's main function at the start of execution,
     823The main stack is the one used by the program main at the start of execution,
    832824and is the only stack in a sequential program.
    833 After the main stack is unwound, there is a program-level abort.
     825After the main stack is unwound there is a program-level abort.
    834826
    835827The first reason for this behaviour is for sequential programs where there
    836 is only one stack, and hence no stack to pass information to.
     828is only one stack, and hence to stack to pass information to.
    837829Second, even in concurrent programs, the main stack has no dependency
    838830on another stack and no reliable way to find another living stack.
     
    850842and an implicit join (from a destructor call). The explicit join takes the
    851843default handler (@defaultResumptionHandler@) from its calling context while
    852 the implicit join provides its own, which does a program abort if the
     844the implicit join provides its own; which does a program abort if the
    853845@ThreadCancelled@ exception cannot be handled.
    854846
  • doc/theses/andrew_beach_MMath/future.tex

    rb5ec090 r56e5b24  
    33
    44The following discussion covers both possible interesting research
    5 that could follow from this work as well as simple implementation
     5that could follow from this work as long as simple implementation
    66improvements.
    77
     
    1010\CFA is a developing programming language. As such, there are partially or
    1111unimplemented features (including several broken components)
    12 that I had to work around while building the EHM largely in
     12that I had to workaround while building the EHM largely in
    1313the \CFA language (some C components). Below are a few of these issues
    1414and how implementing/fixing them would affect the EHM.
    15 In addition, there are some simple improvements that had no interesting
     15In addition there are some simple improvements that had no interesting
    1616research attached to them but would make using the language easier.
    1717\begin{itemize}
     
    2828Termination handlers cannot use local control-flow transfers, \eg by @break@,
    2929@return@, \etc. The reason is that current code generation hoists a handler
    30 into a nested function for convenience (versus assembly-code generation at the
     30into a nested function for convenience (versus assemble-code generation at the
    3131try statement). Hence, when the handler runs, it can still access local
    3232variables in the lexical scope of the try statement. Still, it does mean
    3333that seemingly local control flow is not in fact local and crosses a function
    3434boundary.
    35 Making the termination handler's code within the surrounding
     35Making the termination handlers code within the surrounding
    3636function would remove this limitation.
    3737% Try blocks are much more difficult to do practically (requires our own
    3838% assembly) and resumption handlers have some theoretical complexity.
    3939\item
    40 There is no detection of colliding unwinds. It is possible for cleanup code
    41 run during an unwind to trigger another unwind that escapes the cleanup code
    42 itself, such as a termination exception caught further down the stack or a
     40There is no detection of colliding unwinds. It is possible for clean-up code
     41run during an unwind to trigger another unwind that escapes the clean-up code
     42itself; such as a termination exception caught further down the stack or a
    4343cancellation. There do exist ways to handle this case, but currently there is
    4444no detection and the first unwind will simply be forgotten, often leaving
     
    6464Other features of the virtual system could also remove some of the
    6565special cases around exception virtual tables, such as the generation
    66 of the @msg@ function.
     66of the @msg@ function, could be removed.
    6767
    6868The full virtual system might also include other improvement like associated
     
    7474\section{Additional Raises}
    7575Several other kinds of exception raises were considered beyond termination
    76 (@throw@), resumption (@throwResume@), and re-raise.
     76(@throw@), resumption (@throwResume@), and reraise.
    7777
    7878The first is a non-local/concurrent raise providing asynchronous exceptions,
     
    110110passed on.
    111111
    112 Checked exceptions were never seriously considered for this project
     112However checked exceptions were never seriously considered for this project
    113113because they have significant trade-offs in usability and code reuse in
    114114exchange for the increased safety.
     
    116116higher-order functions from the functions the user passed into the
    117117higher-order function. There are no well known solutions to this problem
    118 that were satisfactory for \CFA (which carries some of C's
    119 flexibility-over-safety design) so additional research is needed.
     118that were satisfactory for \CFA (which carries some of C's flexibility
     119over safety design) so additional research is needed.
    120120
    121121Follow-up work might add some form of checked exceptions to \CFA,
     
    140140Zero-cost resumptions is still an open problem. First, because libunwind does
    141141not support a successful-exiting stack-search without doing an unwind.
    142 Workarounds are possible but awkward. Ideally, an extension to libunwind could
     142Workarounds are possible but awkward. Ideally an extension to libunwind could
    143143be made, but that would either require separate maintenance or gaining enough
    144144support to have it folded into the official library itself.
    145145
    146 Also, new techniques to skip previously searched parts of the stack need to be
     146Also new techniques to skip previously searched parts of the stack need to be
    147147developed to handle the recursive resume problem and support advanced algebraic
    148148effects.
  • doc/theses/andrew_beach_MMath/implement.tex

    rb5ec090 r56e5b24  
    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 two public features, virtual
     16While the \CFA virtual system currently has only one public features, virtual
    1717cast and virtual tables,
     18% ??? refs (see the virtual cast feature \vpageref{p:VirtualCast}),
    1819substantial structure is required to support them,
    1920and provide features for exception handling and the standard library.
     
    3435as part of field-by-field construction.
    3536
    36 \subsection{Type ID}
    37 Every virtual type has a unique ID.
     37\subsection{Type Id}
     38Every virtual type has a unique id.
    3839These are used in type equality, to check if the representation of two values
    3940are the same, and to access the type's type information.
     
    4344
    4445Our approach for program uniqueness is using a static declaration for each
    45 type ID, where the run-time storage address of that variable is guaranteed to
     46type id, where the run-time storage address of that variable is guaranteed to
    4647be unique during program execution.
    47 The type ID storage can also be used for other purposes,
     48The type id storage can also be used for other purposes,
    4849and is used for type information.
    4950
    50 The problem is that a type ID may appear in multiple TUs that compose a
    51 program (see \autoref{ss:VirtualTable}), so the initial solution would seem
    52 to be make it external in each translation unit. Hovever, the type ID must
     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
    5354have a declaration in (exactly) one of the TUs to create the storage.
    5455No other declaration related to the virtual type has this property, so doing
    5556this through standard C declarations would require the user to do it manually.
    5657
    57 Instead, the linker is used to handle this problem.
     58Instead the linker is used to handle this problem.
    5859% I did not base anything off of C++17; they are solving the same problem.
    5960A new feature has been added to \CFA for this purpose, the special attribute
    6061\snake{cfa_linkonce}, which uses the special section @.gnu.linkonce@.
    61 When used as a prefix (\eg @.gnu.linkonce.example@), the linker does
     62When used as a prefix (\eg @.gnu.linkonce.example@) the linker does
    6263not combine these sections, but instead discards all but one with the same
    6364full name.
    6465
    65 So, each type ID must be given a unique section name with the \snake{linkonce}
    66 prefix. Luckily, \CFA already has a way to get unique names, the name mangler.
     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.
    6768For example, this could be written directly in \CFA:
    6869\begin{cfa}
     
    7374__attribute__((section(".gnu.linkonce._X1fFv___1"))) void _X1fFv___1() {}
    7475\end{cfa}
    75 This is done internally to access the name mangler.
     76This is done internally to access the name manglers.
    7677This attribute is useful for other purposes, any other place a unique
    7778instance required, and should eventually be made part of a public and
     
    8081\subsection{Type Information}
    8182
    82 There is data stored at the type ID's declaration, the type information.
    83 The type information currently is only the parent's type ID or, if the
     83There is data stored at the type id's declaration, the type information.
     84The type information currently is only the parent's type id or, if the
    8485type has no parent, the null pointer.
    85 The ancestors of a virtual type are found by traversing type IDs through
     86The ancestors of a virtual type are found by traversing type ids through
    8687the type information.
    8788An example using helper macros looks like:
     
    104105\item
    105106Generate a new structure definition to store the type
    106 information. The layout is the same in each case, just the parent's type ID,
     107information. The layout is the same in each case, just the parent's type id,
    107108but the types used change from instance to instance.
    108109The generated name is used for both this structure and, if relevant, the
     
    114115\item
    115116The definition is generated and initialized.
    116 The parent ID is set to the null pointer or to the address of the parent's
     117The parent id is set to the null pointer or to the address of the parent's
    117118type information instance. Name resolution handles the rest.
    118119\item
     
    150151file as if it was a forward declaration, except no definition is required.
    151152
    152 This technique is used for type ID instances. A link-once definition is
     153This technique is used for type-id instances. A link-once definition is
    153154generated each time the structure is seen. This will result in multiple
    154155copies but the link-once attribute ensures all but one are removed for a
     
    167168\subsection{Virtual Table}
    168169\label{ss:VirtualTable}
    169 %\todo{Clarify virtual table type vs. virtual table instance.}
    170 Each virtual type has a virtual table type that stores its type ID and
     170Each virtual type has a virtual table type that stores its type id and
    171171virtual members.
    172172Each virtual type instance is bound to a table instance that is filled with
     
    176176
    177177The layout always comes in three parts (see \autoref{f:VirtualTableLayout}).
    178 The first section is just the type ID at the head of the table. It is always
     178The first section is just the type id at the head of the table. It is always
    179179there to ensure that it can be found even when the accessing code does not
    180180know which virtual type it has.
    181 The second section is all the virtual members of the parent, in the same
     181The second section are all the virtual members of the parent, in the same
    182182order as they appear in the parent's virtual table. Note that the type may
    183183change slightly as references to the ``this" change. This is limited to
     
    199199This, combined with the fixed offset to the virtual table pointer, means that
    200200for any virtual type, it is always safe to access its virtual table and,
    201 from there, it is safe to check the type ID to identify the exact type of the
     201from there, it is safe to check the type id to identify the exact type of the
    202202underlying object, access any of the virtual members and pass the object to
    203203any of the method-like virtual members.
     
    207207the context of the declaration.
    208208
    209 The type ID is always fixed, with each virtual table type having
    210 exactly one possible type ID.
     209The type id is always fixed; with each virtual table type having
     210exactly one possible type id.
    211211The virtual members are usually filled in by type resolution.
    212212The best match for a given name and type at the declaration site is used.
    213213There are two exceptions to that rule: the @size@ field, the type's size,
    214 is set using a @sizeof@ expression, and the @align@ field, the
     214is set using a @sizeof@ expression and the @align@ field, the
    215215type's alignment, is set using an @alignof@ expression.
    216216
    217217Most of these tools are already inside the compiler. Using simple
    218 code transformations early on in compilation allows most of that work to be
     218code transformations early on in compilation, allows most of that work to be
    219219handed off to the existing tools. \autoref{f:VirtualTableTransformation}
    220 shows an example transformation; this example shows an exception virtual table.
     220shows an example transformation, this example shows an exception virtual table.
    221221It also shows the transformation on the full declaration.
    222222For a forward declaration, the @extern@ keyword is preserved and the
     
    312312        struct __cfavir_type_id * const * child );
    313313\end{cfa}
    314 The type ID for the target type of the virtual cast is passed in as
     314The type id for the target type of the virtual cast is passed in as
    315315@parent@ and
    316316the cast target is passed in as @child@.
     
    322322The virtual cast either returns the original pointer or the null pointer
    323323as the new type.
    324 The function does the parent check and returns the appropriate value.
    325 The parent check is a simple linear search of the child's ancestors using the
     324So the function does the parent check and returns the appropriate value.
     325The parent check is a simple linear search of child's ancestors using the
    326326type information.
    327327
     
    329329% The implementation of exception types.
    330330
    331 Creating exceptions can be roughly divided into two parts:
     331Creating exceptions can roughly divided into two parts,
    332332the exceptions themselves and the virtual system interactions.
    333333
     
    361361
    362362All types associated with a virtual type,
    363 the types of the virtual table and the type ID,
     363the types of the virtual table and the type id,
    364364are generated when the virtual type (the exception) is first found.
    365 The type ID (the instance) is generated with the exception, if it is
     365The type id (the instance) is generated with the exception, if it is
    366366a monomorphic type.
    367 However, if the exception is polymorphic, then a different type ID has to
     367However, if the exception is polymorphic, then a different type id has to
    368368be generated for every instance. In this case, generation is delayed
    369369until a virtual table is created.
     
    372372When a virtual table is created and initialized, two functions are created
    373373to fill in the list of virtual members.
    374 The first is the @copy@ function that adapts the exception's copy constructor
     374The first is a copy function that adapts the exception's copy constructor
    375375to work with pointers, avoiding some issues with the current copy constructor
    376376interface.
    377 Second is the @msg@ function that returns a C-string with the type's name,
     377Second is the msg function that returns a C-string with the type's name,
    378378including any polymorphic parameters.
    379379
     
    402402
    403403% Discussing multiple frame stack unwinding:
    404 Unwinding across multiple stack frames is more complex, because that
     404Unwinding across multiple stack frames is more complex because that
    405405information is no longer contained within the current function.
    406406With separate compilation,
    407407a function does not know its callers nor their frame layout.
    408408Even using the return address, that information is encoded in terms of
    409 actions in code, intermixed with the actions required to finish the function.
     409actions in code, intermixed with the actions required finish the function.
    410410Without changing the main code path it is impossible to select one of those
    411411two groups of actions at the return site.
    412412
    413 The traditional unwinding mechanism for C is implemented by saving a snapshot
    414 of a function's state with @setjmp@ and restoring that snapshot with
     413The traditional unwinding mechanism for C is implemented by saving a snap-shot
     414of a function's state with @setjmp@ and restoring that snap-shot with
    415415@longjmp@. This approach bypasses the need to know stack details by simply
    416 reseting to a snapshot of an arbitrary but existing function frame on the
    417 stack. It is up to the programmer to ensure the snapshot is valid when it is
    418 reset and that all required cleanup from the unwound stacks is performed.
     416reseting to a snap-shot of an arbitrary but existing function frame on the
     417stack. It is up to the programmer to ensure the snap-shot is valid when it is
     418reset and that all required clean-up from the unwound stacks is performed.
    419419This approach is fragile and requires extra work in the surrounding code.
    420420
    421421With respect to the extra work in the surrounding code,
    422 many languages define cleanup actions that must be taken when certain
    423 sections of the stack are removed, such as when the storage for a variable
     422many languages define clean-up actions that must be taken when certain
     423sections of the stack are removed. Such as when the storage for a variable
    424424is removed from the stack, possibly requiring a destructor call,
    425425or when a try statement with a finally clause is
    426426(conceptually) popped from the stack.
    427 None of these cases should be handled by the user -- that would contradict the
    428 intention of these features -- so they need to be handled automatically.
     427None of these cases should be handled by the user --- that would contradict the
     428intention of these features --- so they need to be handled automatically.
    429429
    430430To safely remove sections of the stack, the language must be able to find and
    431 run these cleanup actions even when removing multiple functions unknown at
     431run these clean-up actions even when removing multiple functions unknown at
    432432the beginning of the unwinding.
    433433
     
    529529provided storage object. It has two public fields: the @exception_class@,
    530530which is described above, and the @exception_cleanup@ function.
    531 The cleanup function is used by the EHM to clean up the exception. If it
     531The clean-up function is used by the EHM to clean-up the exception, if it
    532532should need to be freed at an unusual time, it takes an argument that says
    533533why it had to be cleaned up.
     
    551551of the most recent stack frame. It continues to call personality functions
    552552traversing the stack from newest to oldest until a function finds a handler or
    553 the end of the stack is reached. In the latter case,
    554 @_Unwind_RaiseException@ returns @_URC_END_OF_STACK@.
    555 
    556 Second, when a handler is matched, @_Unwind_RaiseException@
    557 moves to the cleanup phase and walks the stack a second time.
     553the end of the stack is reached. In the latter case, raise exception returns
     554@_URC_END_OF_STACK@.
     555
     556Second, when a handler is matched, raise exception moves to the clean-up
     557phase and walks the stack a second time.
    558558Once again, it calls the personality functions of each stack frame from newest
    559559to oldest. This pass stops at the stack frame containing the matching handler.
    560 If that personality function has not installed a handler, it is an error.
    561 
    562 If an error is encountered, @_Unwind_RaiseException@ returns either
     560If that personality function has not install a handler, it is an error.
     561
     562If an error is encountered, raise exception returns either
    563563@_URC_FATAL_PHASE1_ERROR@ or @_URC_FATAL_PHASE2_ERROR@ depending on when the
    564564error occurred.
     
    571571        _Unwind_Stop_Fn, void *);
    572572\end{cfa}
    573 It also unwinds the stack but it does not use the search phase. Instead,
    574 another
     573It also unwinds the stack but it does not use the search phase. Instead another
    575574function, the stop function, is used to stop searching. The exception is the
    576 same as the one passed to @_Unwind_RaiseException@.
    577 The extra arguments are the stop
     575same as the one passed to raise exception. The extra arguments are the stop
    578576function and the stop parameter. The stop function has a similar interface as a
    579577personality function, except it is also passed the stop parameter.
     
    723721one list per stack, with the
    724722list head stored in the exception context. Within each linked list, the most
    725 recently thrown exception is at the head, followed by older thrown
     723recently thrown exception is at the head followed by older thrown
    726724exceptions. This format allows exceptions to be thrown, while a different
    727725exception is being handled. The exception at the head of the list is currently
     
    734732exception into managed memory. After the exception is handled, the free
    735733function is used to clean up the exception and then the entire node is
    736 passed to @free@, returning the memory back to the heap.
     734passed to free, returning the memory back to the heap.
    737735
    738736\subsection{Try Statements and Catch Clauses}
     
    759757The three functions passed to try terminate are:
    760758\begin{description}
    761 \item[try function:] This function is the try block. It is where all the code
     759\item[try function:] This function is the try block, it is where all the code
    762760from inside the try block is placed. It takes no parameters and has no
    763761return value. This function is called during regular execution to run the try
     
    768766from the conditional part of each handler and runs each check, top to bottom,
    769767in turn, to see if the exception matches this handler.
    770 The match is performed in two steps: first, a virtual cast is used to check
     768The match is performed in two steps, first a virtual cast is used to check
    771769if the raised exception is an instance of the declared exception type or
    772770one of its descendant types, and then the condition is evaluated, if
    773771present.
    774772The match function takes a pointer to the exception and returns 0 if the
    775 exception is not handled here. Otherwise, the return value is the ID of the
     773exception is not handled here. Otherwise the return value is the id of the
    776774handler that matches the exception.
    777775
     
    784782\end{description}
    785783All three functions are created with GCC nested functions. GCC nested functions
    786 can be used to create closures;
     784can be used to create closures,
    787785in other words,
    788 functions that can refer to variables in their lexical scope even though
     786functions that can refer to variables in their lexical scope even
    789787those variables are part of a different function.
    790788This approach allows the functions to refer to all the
     
    871869At each node, the EHM checks to see if the try statement the node represents
    872870can handle the exception. If it can, then the exception is handled and
    873 the operation finishes; otherwise, the search continues to the next node.
     871the operation finishes, otherwise the search continues to the next node.
    874872If the search reaches the end of the list without finding a try statement
    875873with a handler clause
     
    881879if the exception is handled and false otherwise.
    882880The handler function checks each of its internal handlers in order,
    883 top-to-bottom, until it finds a match. If a match is found that handler is
     881top-to-bottom, until it funds a match. If a match is found that handler is
    884882run, after which the function returns true, ignoring all remaining handlers.
    885883If no match is found the function returns false.
    886 The match is performed in two steps. First a virtual cast is used to see
     884The match is performed in two steps, first a virtual cast is used to see
    887885if the raised exception is an instance of the declared exception type or one
    888 of its descendant types, if so, then the second step is to see if the
    889 exception passes the custom predicate
     886of its descendant types, if so then it is passed to the custom predicate
    890887if one is defined.
    891888% You need to make sure the type is correct before running the predicate
     
    939936% Recursive Resumption Stuff:
    940937\autoref{f:ResumptionMarking} shows search skipping
    941 (see \autoref{s:ResumptionMarking}), which ignores parts of
     938(see \vpageref{s:ResumptionMarking}), which ignores parts of
    942939the stack
    943940already examined, and is accomplished by updating the front of the list as
     
    954951This structure also supports new handlers added while the resumption is being
    955952handled. These are added to the front of the list, pointing back along the
    956 stack -- the first one points over all the checked handlers --
     953stack --- the first one points over all the checked handlers ---
    957954and the ordering is maintained.
    958955
     
    982979%\autoref{code:cleanup}
    983980A finally clause is handled by converting it into a once-off destructor.
    984 The code inside the clause is placed into a GCC nested-function
     981The code inside the clause is placed into GCC nested-function
    985982with a unique name, and no arguments or return values.
    986983This nested function is
    987984then set as the cleanup function of an empty object that is declared at the
    988985beginning of a block placed around the context of the associated try
    989 statement, as shown in \autoref{f:FinallyTransformation}.
     986statement (see \autoref{f:FinallyTransformation}).
    990987
    991988\begin{figure}
     
    10271024% Stack selections, the three internal unwind functions.
    10281025
    1029 Cancellation also uses libunwind to do its stack traversal and unwinding.
    1030 However, it uses a different primary function: @_Unwind_ForcedUnwind@. Details
    1031 of its interface can be found in Section~\vref{s:ForcedUnwind}.
     1026Cancellation also uses libunwind to do its stack traversal and unwinding,
     1027however it uses a different primary function: @_Unwind_ForcedUnwind@. Details
     1028of its interface can be found in the Section~\vref{s:ForcedUnwind}.
    10321029
    10331030The first step of cancellation is to find the cancelled stack and its type:
  • doc/theses/andrew_beach_MMath/intro.tex

    rb5ec090 r56e5b24  
    2525All types of exception handling link a raise with a handler.
    2626Both operations are usually language primitives, although raises can be
    27 treated as a function that takes an exception argument.
    28 Handlers are more complex, as they are added to and removed from the stack
    29 during execution, must specify what they can handle and must give the code to
     27treated as a primitive function that takes an exception argument.
     28Handlers are more complex as they are added to and removed from the stack
     29during execution, must specify what they can handle and give the code to
    3030handle the exception.
    3131
     
    4141\input{termination}
    4242\end{center}
    43 %\todo{What does the right half of termination.fig mean?}
    4443
    4544Resumption exception handling searches the stack for a handler and then calls
     
    4746The handler is run on top of the existing stack, often as a new function or
    4847closure capturing the context in which the handler was defined.
    49 After the handler has finished running, it returns control to the function
     48After the handler has finished running it returns control to the function
    5049that preformed the raise, usually starting after the raise.
    5150\begin{center}
     
    5453
    5554Although a powerful feature, exception handling tends to be complex to set up
    56 and expensive to use,
     55and expensive to use
    5756so it is often limited to unusual or ``exceptional" cases.
    58 The classic example is error handling; exceptions can be used to
     57The classic example is error handling, exceptions can be used to
    5958remove error handling logic from the main execution path, and pay
    6059most of the cost only when the error actually occurs.
     
    6463The \CFA EHM implements all of the common exception features (or an
    6564equivalent) found in most other EHMs and adds some features of its own.
    66 The design of all the features had to be adapted to \CFA's feature set, as
     65The design of all the features had to be adapted to \CFA's feature set as
    6766some of the underlying tools used to implement and express exception handling
    6867in other languages are absent in \CFA.
    69 Still, the resulting syntax resembles that of other languages:
     68Still the resulting syntax resembles that of other languages:
    7069\begin{cfa}
    7170try {
     
    8988covering both changes to the compiler and the run-time.
    9089In addition, a suite of test cases and performance benchmarks were created
    91 alongside the implementation.
     90along side the implementation.
    9291The implementation techniques are generally applicable in other programming
    9392languages and much of the design is as well.
     
    101100\item Implementing stack unwinding and the \CFA EHM, including updating
    102101the \CFA compiler and the run-time environment.
    103 \item Designing and implementing a prototype virtual system.
     102\item Designed and implemented a prototype virtual system.
    104103% I think the virtual system and per-call site default handlers are the only
    105104% "new" features, everything else is a matter of implementation.
    106105\item Creating tests to check the behaviour of the EHM.
    107 \item Creating benchmarks to check the performance of the EHM,
     106\item Creating benchmarks to check the performances of the EHM,
    108107as compared to other languages.
    109108\end{enumerate}
     
    111110The rest of this thesis is organized as follows.
    112111The current state of exceptions is covered in \autoref{s:background}.
    113 The existing state of \CFA is covered in \autoref{c:existing}.
     112The existing state of \CFA is also covered in \autoref{c:existing}.
    114113New EHM features are introduced in \autoref{c:features},
    115114covering their usage and design.
     
    138137inheriting from
    139138\code{C++}{std::exception}.
    140 Although there is a special catch-all syntax (@catch(...)@), there are no
     139Although there is a special catch-all syntax (@catch(...)@) there are no
    141140operations that can be performed on the caught value, not even type inspection.
    142 Instead, the base exception-type \code{C++}{std::exception} defines common
     141Instead the base exception-type \code{C++}{std::exception} defines common
    143142functionality (such as
    144143the ability to describe the reason the exception was raised) and all
     
    149148
    150149Java was the next popular language to use exceptions.\cite{Java8}
    151 Its exception system largely reflects that of \Cpp, except that it requires
     150Its exception system largely reflects that of \Cpp, except that requires
    152151you throw a child type of \code{Java}{java.lang.Throwable}
    153152and it uses checked exceptions.
    154153Checked exceptions are part of a function's interface,
    155154the exception signature of the function.
    156 Every exception that could be raised from a function, either directly or
     155Every function that could be raised from a function, either directly or
    157156because it is not handled from a called function, is given.
    158157Using this information, it is possible to statically verify if any given
    159 exception is handled, and guarantee that no exception will go unhandled.
     158exception is handled and guarantee that no exception will go unhandled.
    160159Making exception information explicit improves clarity and safety,
    161160but can slow down or restrict programming.
     
    170169recovery or repair. In theory that could be good enough to properly handle
    171170the exception, but more often is used to ignore an exception that the       
    172 programmer does not feel is worth the effort of handling, for instance if
     171programmer does not feel is worth the effort of handling it, for instance if
    173172they do not believe it will ever be raised.
    174 If they are incorrect, the exception will be silenced, while in a similar
     173If they are incorrect the exception will be silenced, while in a similar
    175174situation with unchecked exceptions the exception would at least activate   
    176 the language's unhandled exception code (usually, a program abort with an
     175the language's unhandled exception code (usually program abort with an 
    177176error message).
    178177
    179178%\subsection
    180179Resumption exceptions are less popular,
    181 although resumption is as old as termination; that is, few
     180although resumption is as old as termination; hence, few
    182181programming languages have implemented them.
    183182% http://bitsavers.informatik.uni-stuttgart.de/pdf/xerox/parc/techReports/
     
    187186included in the \Cpp standard.
    188187% https://en.wikipedia.org/wiki/Exception_handling
    189 Since then, resumptions have been ignored in main-stream programming languages.
     188Since then resumptions have been ignored in main-stream programming languages.
    190189However, resumption is being revisited in the context of decades of other
    191190developments in programming languages.
    192191While rejecting resumption may have been the right decision in the past,
    193192the situation has changed since then.
    194 Some developments, such as the functional programming equivalent to resumptions,
     193Some developments, such as the function programming equivalent to resumptions,
    195194algebraic effects\cite{Zhang19}, are enjoying success.
    196 A complete reexamination of resumption is beyond this thesis,
    197 but their reemergence is enough reason to try them in \CFA.
     195A complete reexamination of resumptions is beyond this thesis,
     196but there reemergence is enough to try them in \CFA.
    198197% Especially considering how much easier they are to implement than
    199198% termination exceptions and how much Peter likes them.
     
    209208
    210209%\subsection
    211 More recently exceptions, seem to be vanishing from newer programming
     210More recently exceptions seem to be vanishing from newer programming
    212211languages, replaced by ``panic".
    213212In Rust, a panic is just a program level abort that may be implemented by
     
    219218
    220219%\subsection
    221 As exception handling's most common use cases are in error handling,
     220While exception handling's most common use cases are in error handling,
    222221here are some other ways to handle errors with comparisons with exceptions.
    223222\begin{itemize}
     
    234233is discarded to avoid this problem.
    235234Checking error codes also bloats the main execution path,
    236 especially if the error is not handled immediately and has to be passed
     235especially if the error is not handled immediately hand has to be passed
    237236through multiple functions before it is addressed.
    238237
    239238\item\emph{Special Return with Global Store}:
    240239Similar to the error codes pattern but the function itself only returns
    241 that there was an error,
    242 and stores the reason for the error in a fixed global location.
    243 For example, many routines in the C standard library will only return some
     240that there was an error
     241and store the reason for the error in a fixed global location.
     242For example many routines in the C standard library will only return some
    244243error value (such as -1 or a null pointer) and the error code is written into
    245244the standard variable @errno@.
     
    254253Success is one tag and the errors are another.
    255254It is also possible to make each possible error its own tag and carry its own
    256 additional information, but the two-branch format is easy to make generic
     255additional information, but the two branch format is easy to make generic
    257256so that one type can be used everywhere in error handling code.
    258257
     
    262261% Rust's \code{rust}{Result<T, E>}
    263262The main advantage is that an arbitrary object can be used to represent an
    264 error, so it can include a lot more information than a simple error code.
     263error so it can include a lot more information than a simple error code.
    265264The disadvantages include that the it does have to be checked along the main
    266 execution, and if there aren't primitive tagged unions proper, usage can be
     265execution and if there aren't primitive tagged unions proper usage can be
    267266hard to enforce.
    268267
     
    275274variable).
    276275C++ uses this approach as its fallback system if exception handling fails,
    277 such as \snake{std::terminate} and, for a time,
    278 \snake{std::unexpected}.\footnote{\snake{std::unexpected} was part of the
    279 Dynamic Exception Specification, which has been removed from the standard
    280 as of C++20.\cite{CppExceptSpec}}
     276such as \snake{std::terminate_handler} and, for a time,
     277\snake{std::unexpected_handler}.
    281278
    282279Handler functions work a lot like resumption exceptions,
     
    294291happily making them expensive to use in exchange.
    295292This difference is less important in higher-level scripting languages,
    296 where using exceptions for other tasks is more common.
     293where using exception for other tasks is more common.
    297294An iconic example is Python's
    298 \code{Python}{StopIteration}\cite{PythonExceptions} exception, that
     295\code{Python}{StopIteration}\cite{PythonExceptions} exception that
    299296is thrown by an iterator to indicate that it is exhausted.
    300 When paired with Python's iterator-based for-loop, this will be thrown every
     297When paired with Python's iterator-based for-loop this will be thrown every
    301298time the end of the loop is reached.\cite{PythonForLoop}
  • doc/theses/andrew_beach_MMath/performance.tex

    rb5ec090 r56e5b24  
    55Instead, the focus was to get the features working. The only performance
    66requirement is to ensure the tests for correctness run in a reasonable
    7 amount of time. Hence, only a few basic performance tests were performed to
     7amount of time. Hence, a few basic performance tests were performed to
    88check this requirement.
    99
     
    1313one with termination and one with resumption.
    1414
    15 GCC C++ is the most comparable language because both it and \CFA use the same
     15C++ is the most comparable language because both it and \CFA use the same
    1616framework, libunwind.
    1717In fact, the comparison is almost entirely in quality of implementation.
     
    4646the number used in the timing runs is given with the results per test.
    4747The Java tests run the main loop 1000 times before
    48 beginning the actual test to ``warm up" the JVM.
     48beginning the actual test to ``warm-up" the JVM.
    4949% All other languages are precompiled or interpreted.
    5050
     
    5454unhandled exceptions in \Cpp and Java as that would cause the process to
    5555terminate.
    56 Luckily, performance on the ``give up and kill the process" path is not
     56Luckily, performance on the ``give-up and kill the process" path is not
    5757critical.
    5858
     
    7676using gcc-10 10.3.0 as a backend.
    7777g++-10 10.3.0 is used for \Cpp.
    78 Java tests are complied and run with Oracle OpenJDK version 11.0.11.
    79 Python used CPython version 3.8.10.
     78Java tests are complied and run with version 11.0.11.
     79Python used version 3.8.10.
    8080The machines used to run the tests are:
    8181\begin{itemize}[nosep]
     
    8585      \lstinline{@} 2.5 GHz running Linux v5.11.0-25
    8686\end{itemize}
    87 These represent the two major families of hardware architecture.
     87Representing the two major families of hardware architecture.
    8888
    8989\section{Tests}
     
    9393
    9494\paragraph{Stack Traversal}
    95 This group of tests measures the cost of traversing the stack
     95This group measures the cost of traversing the stack,
    9696(and in termination, unwinding it).
    9797Inside the main loop is a call to a recursive function.
     
    147147This group of tests measures the cost for setting up exception handling,
    148148if it is
    149 not used because the exceptional case did not occur.
     149not used (because the exceptional case did not occur).
    150150Tests repeatedly cross (enter, execute and leave) a try statement but never
    151151perform a raise.
     
    222222for that language and the result is marked N/A.
    223223There are also cases where the feature is supported but measuring its
    224 cost is impossible. This happened with Java, which uses a JIT that optimizes
    225 away the tests and cannot be stopped.\cite{Dice21}
     224cost is impossible. This happened with Java, which uses a JIT that optimize
     225away the tests and it cannot be stopped.\cite{Dice21}
    226226These tests are marked N/C.
    227227To get results in a consistent range (1 second to 1 minute is ideal,
     
    230230results and has a value in the millions.
    231231
    232 An anomaly in some results came from \CFA's use of GCC nested functions.
     232An anomaly in some results came from \CFA's use of gcc nested functions.
    233233These nested functions are used to create closures that can access stack
    234234variables in their lexical scope.
    235 However, if they do so, then they can cause the benchmark's run time to
     235However, if they do so, then they can cause the benchmark's run-time to
    236236increase by an order of magnitude.
    237237The simplest solution is to make those values global variables instead
    238 of function-local variables.
     238of function local variables.
    239239% Do we know if editing a global inside nested function is a problem?
    240240Tests that had to be modified to avoid this problem have been marked
     
    312312\CFA, \Cpp and Java.
    313313% To be exact, the Match All and Match None cases.
    314 %\todo{Not true in Python.}
    315314The most likely explanation is that, since exceptions
    316315are rarely considered to be the common case, the more optimized languages
     
    347346Performance is similar to Empty Traversal in all languages that support finally
    348347clauses. Only Python seems to have a larger than random noise change in
    349 its run time and it is still not large.
     348its run-time and it is still not large.
    350349Despite the similarity between finally clauses and destructors,
    351 finally clauses seem to avoid the spike that run time destructors have.
     350finally clauses seem to avoid the spike that run-time destructors have.
    352351Possibly some optimization removes the cost of changing contexts.
    353352
     
    357356This results in a significant jump.
    358357
    359 Other languages experience a small increase in run time.
     358Other languages experience a small increase in run-time.
    360359The small increase likely comes from running the checks,
    361360but they could avoid the spike by not having the same kind of overhead for
     
    363362
    364363\item[Cross Handler]
    365 Here, \CFA falls behind \Cpp by a much more significant margin.
    366 This is likely due to the fact that \CFA has to insert two extra function
    367 calls, while \Cpp does not have to execute any other instructions.
     364Here \CFA falls behind \Cpp by a much more significant margin.
     365This is likely due to the fact \CFA has to insert two extra function
     366calls, while \Cpp does not have to do execute any other instructions.
    368367Python is much further behind.
    369368
     
    376375\item[Conditional Match]
    377376Both of the conditional matching tests can be considered on their own.
    378 However, for evaluating the value of conditional matching itself, the
     377However for evaluating the value of conditional matching itself, the
    379378comparison of the two sets of results is useful.
    380 Consider the massive jump in run time for \Cpp going from match all to match
     379Consider the massive jump in run-time for \Cpp going from match all to match
    381380none, which none of the other languages have.
    382 Some strange interaction is causing run time to more than double for doing
     381Some strange interaction is causing run-time to more than double for doing
    383382twice as many raises.
    384 Java and Python avoid this problem and have similar run time for both tests,
     383Java and Python avoid this problem and have similar run-time for both tests,
    385384possibly through resource reuse or their program representation.
    386 However, \CFA is built like \Cpp, and avoids the problem as well.
    387 This matches
     385However \CFA is built like \Cpp and avoids the problem as well, this matches
    388386the pattern of the conditional match, which makes the two execution paths
    389387very similar.
     
    393391\subsection{Resumption \texorpdfstring{(\autoref{t:PerformanceResumption})}{}}
    394392
    395 Moving on to resumption, there is one general note:
     393Moving on to resumption, there is one general note,
    396394resumption is \textit{fast}. The only test where it fell
    397395behind termination is Cross Handler.
    398396In every other case, the number of iterations had to be increased by a
    399 factor of 10 to get the run time in an appropriate range
     397factor of 10 to get the run-time in an appropriate range
    400398and in some cases resumption still took less time.
    401399
     
    410408
    411409\item[D'tor Traversal]
    412 Resumption does have the same spike in run time that termination has.
    413 The run time is actually very similar to Finally Traversal.
     410Resumption does have the same spike in run-time that termination has.
     411The run-time is actually very similar to Finally Traversal.
    414412As resumption does not unwind the stack, both destructors and finally
    415413clauses are run while walking down the stack during the recursive returns.
     
    418416\item[Finally Traversal]
    419417Same as D'tor Traversal,
    420 except termination did not have a spike in run time on this test case.
     418except termination did not have a spike in run-time on this test case.
    421419
    422420\item[Other Traversal]
     
    429427The only test case where resumption could not keep up with termination,
    430428although the difference is not as significant as many other cases.
    431 It is simply a matter of where the costs come from:
    432 both termination and resumption have some work to set up or tear down a
     429It is simply a matter of where the costs come from,
     430both termination and resumption have some work to set-up or tear-down a
    433431handler. It just so happens that resumption's work is slightly slower.
    434432
     
    436434Resumption shows a slight slowdown if the exception is not matched
    437435by the first handler, which follows from the fact the second handler now has
    438 to be checked. However, the difference is not large.
     436to be checked. However the difference is not large.
    439437
    440438\end{description}
     
    450448More experiments could try to tease out the exact trade-offs,
    451449but the prototype's only performance goal is to be reasonable.
    452 It is already in that range, and \CFA's fixup routine simulation is
     450It has already in that range, and \CFA's fixup routine simulation is
    453451one of the faster simulations as well.
    454 Plus, exceptions add features and remove syntactic overhead,
    455 so even at similar performance, resumptions have advantages
     452Plus exceptions add features and remove syntactic overhead,
     453so even at similar performance resumptions have advantages
    456454over fixup routines.
  • doc/theses/andrew_beach_MMath/uw-ethesis-frontpgs.tex

    rb5ec090 r56e5b24  
    137137This thesis covers the design and implementation of the \CFA EHM,
    138138along with a review of the other required \CFA features.
    139 The EHM includes common features of termination exception handling,
    140 which abandons and recovers from an operation,
    141 and similar support for resumption exception handling,
    142 which repairs and continues with an operation.
     139The EHM includes common features of termination exception handling and
     140similar support for resumption exception handling.
    143141The design of both has been adapted to utilize other tools \CFA provides,
    144142as well as fit with the assertion based interfaces of the language.
     
    146144The EHM has been implemented into the \CFA compiler and run-time environment.
    147145Although it has not yet been optimized, performance testing has shown it has
    148 comparable performance to other EHMs,
     146comparable performance to other EHM's,
    149147which is sufficient for use in current \CFA programs.
    150148
  • doc/theses/andrew_beach_MMath/uw-ethesis.bib

    rb5ec090 r56e5b24  
    4040}
    4141
    42 @misc{CppExceptSpec,
    43     author={C++ Community},
    44     key={Cpp Reference Exception Specification},
    45     howpublished={\href{https://en.cppreference.com/w/cpp/language/except_spec}{https://\-en.cppreference.com/\-w/\-cpp/\-language/\-except\_spec}},
    46     addendum={Accessed 2021-09-08},
    47 }
    48 
    4942@misc{RustPanicMacro,
    5043    author={The Rust Team},
  • src/Parser/parser.yy

    rb5ec090 r56e5b24  
    1010// Created On       : Sat Sep  1 20:22:55 2001
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Sep 11 08:20:44 2021
    13 // Update Count     : 5040
     12// Last Modified On : Sun Aug  8 09:14:44 2021
     13// Update Count     : 5038
    1414//
    1515
     
    24462446        | simple_assignment_operator initializer        { $$ = $1 == OperKinds::Assign ? $2 : $2->set_maybeConstructed( false ); }
    24472447        | '=' VOID                                                                      { $$ = new InitializerNode( true ); }
    2448         | '{' initializer_list_opt comma_opt '}'        { $$ = new InitializerNode( $2, true ); }
    24492448        ;
    24502449
     
    24602459        | designation initializer                                       { $$ = $2->set_designators( $1 ); }
    24612460        | initializer_list_opt ',' initializer          { $$ = (InitializerNode *)( $1->set_last( $3 ) ); }
    2462         | initializer_list_opt ',' designation initializer { $$ = (InitializerNode *)($1->set_last( $4->set_designators( $3 ) )); }
     2461        | initializer_list_opt ',' designation initializer
     2462                { $$ = (InitializerNode *)($1->set_last( $4->set_designators( $3 ) )); }
    24632463        ;
    24642464
Note: See TracChangeset for help on using the changeset viewer.