Changeset aa173d8 for doc/theses
- Timestamp:
- Aug 5, 2021, 8:29:35 PM (3 years ago)
- Branches:
- ADT, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 7780bd2
- Parents:
- d89d150
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/andrew_beach_MMath/features.tex
rd89d150 raa173d8 16 16 throw/catch as a particular kind of raise/handle. 17 17 These are the two parts that the user writes and may 18 be the only two pieces of the EHM that have any syntax in thelanguage.18 be the only two pieces of the EHM that have any syntax in a language. 19 19 20 20 \paragraph{Raise} 21 The raise is the starting point for exception handling . It marks the beginning22 of exception handlingby raising an exception, which passes it to21 The raise is the starting point for exception handling 22 by raising an exception, which passes it to 23 23 the EHM. 24 24 25 25 Some well known examples include the @throw@ statements of \Cpp and Java and 26 the \code{Python}{raise} statement from Python. In real systemsa raise may27 p reform some other work (such as memory management) but for the26 the \code{Python}{raise} statement of Python. In real systems, a raise may 27 perform some other work (such as memory management) but for the 28 28 purposes of this overview that can be ignored. 29 29 30 30 \paragraph{Handle} 31 The p urpose of most exception operations is to run some user code to handle32 thatexception. This code is given, with some other information, in a handler.31 The primary purpose of an EHM is to run some user code to handle a raised 32 exception. This code is given, with some other information, in a handler. 33 33 34 34 A handler has three common features: the previously mentioned user code, a 35 region of code they guardand an exception label/condition that matches36 certain exceptions.35 region of code it guards, and an exception label/condition that matches 36 the raised exception. 37 37 Only raises inside the guarded region and raising exceptions that match the 38 38 label can be handled by a given handler. 39 39 If multiple handlers could can handle an exception, 40 EHMs willdefine a rule to pick one, such as ``best match" or ``first found".40 EHMs define a rule to pick one, such as ``best match" or ``first found". 41 41 42 42 The @try@ statements of \Cpp, Java and Python are common examples. All three 43 also show another common feature of handlers, they are grouped by the guarded 44 region. 43 show the common features of guarded region, raise, matching and handler. 44 \begin{cfa} 45 try { // guarded region 46 ... 47 throw exception; // raise 48 ... 49 } catch( exception ) { // matching condition, with exception label 50 ... // handler code 51 } 52 \end{cfa} 45 53 46 54 \subsection{Propagation} 47 55 After an exception is raised comes what is usually the biggest step for the 48 EHM: finding and setting up the handler . The propagation from raise to56 EHM: finding and setting up the handler for execution. The propagation from raise to 49 57 handler can be broken up into three different tasks: searching for a handler, 50 58 matching against the handler and installing the handler. … … 52 60 \paragraph{Searching} 53 61 The EHM begins by searching for handlers that might be used to handle 54 the exception. Searching is usually independent of the exception that was55 thrown as it looks forhandlers that have the raise site in their guarded62 the exception. The search is restricted to 63 handlers that have the raise site in their guarded 56 64 region. 57 65 The search includes handlers in the current function, as well as any in … … 59 67 60 68 \paragraph{Matching} 61 Each handler found has to bematched with the raised exception. The exception62 label defines a condition that is used with exception and decides if69 Each handler found is matched with the raised exception. The exception 70 label defines a condition that is used with the exception and decides if 63 71 there is a match or not. 64 65 72 In languages where the first match is used, this step is intertwined with 66 searching; a match check is p reformed immediately after the search finds67 a possiblehandler.73 searching; a match check is performed immediately after the search finds 74 a handler. 68 75 69 76 \paragraph{Installing} 70 After a handler is chosen it must be made ready to run.77 After a handler is chosen, it must be made ready to run. 71 78 The implementation can vary widely to fit with the rest of the 72 79 design of the EHM. The installation step might be trivial or it could be … … 75 82 76 83 If a matching handler is not guaranteed to be found, the EHM needs a 77 different course of action for th e case where no handler matches.84 different course of action for this case. 78 85 This situation only occurs with unchecked exceptions as checked exceptions 79 (such as in Java) can make the guarantee.80 Th isunhandled action is usually very general, such as aborting the program.86 (such as in Java) are guaranteed to find a matching handler. 87 The unhandled action is usually very general, such as aborting the program. 81 88 82 89 \paragraph{Hierarchy} … … 85 92 exception hierarchy is a natural extension of the object hierarchy. 86 93 87 Consider the following hierarchy of exceptions:94 Consider the following exception hierarchy: 88 95 \begin{center} 89 96 \input{exception-hierarchy} 90 97 \end{center} 91 92 98 A handler labeled with any given exception can handle exceptions of that 93 99 type or any child type of that exception. The root of the exception hierarchy 94 (here \code{C}{exception}) acts as a catch-all, leaf types catch single types 100 (here \code{C}{exception}) acts as a catch-all, leaf types catch single types, 95 101 and the exceptions in the middle can be used to catch different groups of 96 102 related exceptions. 97 103 98 104 This system has some notable advantages, such as multiple levels of grouping, 99 the ability for libraries to add new exception types and the isolation105 the ability for libraries to add new exception types, and the isolation 100 106 between different sub-hierarchies. 101 107 This design is used in \CFA even though it is not a object-orientated … … 110 116 is usually set up to do most of the work. 111 117 112 The EHM can return control to many different places, 118 The EHM can return control to many different places, where 113 119 the most common are after the handler definition (termination) 114 120 and after the raise (resumption). … … 117 123 For effective exception handling, additional information is often passed 118 124 from the raise to the handler and back again. 119 So far only communication of the exceptions' identity has beencovered.120 A common communication method is putting fields into the exception instance125 So far, only communication of the exception's identity is covered. 126 A common communication method for passing more information is putting fields into the exception instance 121 127 and giving the handler access to them. 122 Passing the exception by reference instead of by value can allowdata to be128 Using reference fields pointing to data at the raise location allows data to be 123 129 passed in both directions. 124 130 125 131 \section{Virtuals} 126 132 Virtual types and casts are not part of \CFA's EHM nor are they required for 127 an yEHM.128 However, it isone of the best ways to support an exception hierarchy133 an EHM. 134 However, one of the best ways to support an exception hierarchy 129 135 is via a virtual hierarchy and dispatch system. 130 136 131 Ideally, the virtual system would have been part of \CFA before the work137 Ideally, the virtual system should have been part of \CFA before the work 132 138 on exception handling began, but unfortunately it was not. 133 139 Hence, only the features and framework needed for the EHM were 134 designed and implemented . Other features were considered to ensure that140 designed and implemented for this thesis. Other features were considered to ensure that 135 141 the structure could accommodate other desirable features in the future 136 but they were not implemented.137 The rest of this section will only discuss the implemented subset of the138 virtual 142 but are not implemented. 143 The rest of this section only discusses the implemented subset of the 144 virtual-system design. 139 145 140 146 The virtual system supports multiple ``trees" of types. Each tree is … … 152 158 It is important to note that these are virtual members, not virtual methods 153 159 of object-orientated programming, and can be of any type. 160 161 \PAB{Need to look at these when done. 154 162 155 163 \CFA still supports virtual methods as a special case of virtual members. … … 165 173 as a hidden field. 166 174 \todo{Might need a diagram for virtual structure.} 175 }% 167 176 168 177 Up until this point the virtual system is similar to ones found in 169 object-orientated languages but this where \CFA diverges. Objects encapsulate a 170 single set of behaviours in each type, universally across the entire program, 171 and indeed all programs that use that type definition. In this sense, the 172 types are ``closed" and cannot be altered. 173 174 In \CFA, types do not encapsulate any behaviour. Traits are local and 175 types can begin to satisfy a trait, stop satisfying a trait or satisfy the same 176 trait in a different way at any lexical location in the program. 177 In this sense, they are ``open" as they can change at any time. 178 object-orientated languages but this is where \CFA diverges. Objects encapsulate a 179 single set of methods in each type, universally across the entire program, 180 and indeed all programs that use that type definition. Even if a type inherits and adds methods, it still encapsulate a 181 single set of methods. In this sense, 182 object-oriented types are ``closed" and cannot be altered. 183 184 In \CFA, types do not encapsulate any code. Traits are local for each function and 185 types can satisfy a local trait, stop satisfying it or, satisfy the same 186 trait in a different way at any lexical location in the program where a function is call. 187 In this sense, the set of functions/variables that satisfy a trait for a type is ``open" as the set can change at every call site. 178 188 This capability means it is impossible to pick a single set of functions 179 that represent the type's implementation across theprogram.189 that represent a type's implementation across a program. 180 190 181 191 \CFA side-steps this issue by not having a single virtual table for each 182 192 type. A user can define virtual tables that are filled in at their 183 193 declaration and given a name. Anywhere that name is visible, even if it is 184 defined locally inside a function (although that means it does not have a185 static lifetime) , it can be used.194 defined locally inside a function \PAB{What does this mean? (although that means it does not have a 195 static lifetime)}, it can be used. 186 196 Specifically, a virtual type is ``bound" to a virtual table that 187 197 sets the virtual members for that object. The virtual members can be accessed … … 221 231 completing the virtual system). The imaginary assertions would probably come 222 232 from a trait defined by the virtual system, and state that the exception type 223 is a virtual type, is a descendant of @exception_t@ (the base exception type) 233 is a virtual type, is a descendant of @exception_t@ (the base exception type), 224 234 and note its virtual table type. 225 235 … … 241 251 \end{cfa} 242 252 Both traits ensure a pair of types are an exception type, its virtual table 243 type 253 type, 244 254 and defines one of the two default handlers. The default handlers are used 245 255 as fallbacks and are discussed in detail in \vref{s:ExceptionHandling}. … … 250 260 facing way. So these three macros are provided to wrap these traits to 251 261 simplify referring to the names: 252 @IS_EXCEPTION@, @IS_TERMINATION_EXCEPTION@ and @IS_RESUMPTION_EXCEPTION@.262 @IS_EXCEPTION@, @IS_TERMINATION_EXCEPTION@, and @IS_RESUMPTION_EXCEPTION@. 253 263 254 264 All three take one or two arguments. The first argument is the name of the … … 272 282 \CFA provides two kinds of exception handling: termination and resumption. 273 283 These twin operations are the core of \CFA's exception handling mechanism. 274 This section will coverthe general patterns shared by the two operations and275 then go on to cover the detailseach individual operation.284 This section covers the general patterns shared by the two operations and 285 then goes on to cover the details of each individual operation. 276 286 277 287 Both operations follow the same set of steps. 278 Both start with the user preforming a raise onan exception.279 Thenthe exception propagates up the stack.280 If a handler is foundthe exception is caught and the handler is run.288 First, a user raises an exception. 289 Second, the exception propagates up the stack. 290 Third, if a handler is found, the exception is caught and the handler is run. 281 291 After that control continues at a raise-dependent location. 282 If the search failsa default handler is run and, if it returns, then control292 Fourth, if a handler is not found, a default handler is run and, if it returns, then control 283 293 continues after the raise. 284 294 285 This general description covers what the two kinds have in common.286 Differences include how propagation is preformed, where exception continues287 after an exception is caught and handled and which default handler is run.295 %This general description covers what the two kinds have in common. 296 The differences in the two operations include how propagation is performed, where execution continues 297 after an exception is caught and handled, and which default handler is run. 288 298 289 299 \subsection{Termination} 290 300 \label{s:Termination} 291 Termination handling is the familiar kindand used in most programming301 Termination handling is the familiar EHM and used in most programming 292 302 languages with exception handling. 293 303 It is a dynamic, non-local goto. If the raised exception is matched and … … 308 318 @is_termination_exception@ at the call site. 309 319 Through \CFA's trait system, the trait functions are implicitly passed into the 310 throw code andthe EHM.320 throw code for use by the EHM. 311 321 A new @defaultTerminationHandler@ can be defined in any scope to 312 change the throw's behaviour (see below).322 change the throw's behaviour when a handler is not found (see below). 313 323 314 324 The throw copies the provided exception into managed memory to ensure … … 320 330 % How to say propagation starts, its first sub-step is the search. 321 331 Then propagation starts with the search. \CFA uses a ``first match" rule so 322 matching is p reformed with the copied exception as the search continues.323 It starts from the throwing function and proceeds towardsbase of the stack,332 matching is performed with the copied exception as the search key. 333 It starts from the raise in the throwing function and proceeds towards the base of the stack, 324 334 from callee to caller. 325 At each stack frame, a check is made for resumption handlers defined by the335 At each stack frame, a check is made for termination handlers defined by the 326 336 @catch@ clauses of a @try@ statement. 327 337 \begin{cfa} … … 335 345 \end{cfa} 336 346 When viewed on its own, a try statement simply executes the statements 337 in \snake{GUARDED_BLOCK}and when those are finished,347 in the \snake{GUARDED_BLOCK}, and when those are finished, 338 348 the try statement finishes. 339 349 … … 341 351 invoked functions, all the handlers in these statements are included in the 342 352 search path. 343 Hence, if a termination exception is raised these handlers may be matched353 Hence, if a termination exception is raised, these handlers may be matched 344 354 against the exception and may handle it. 345 355 346 356 Exception matching checks the handler in each catch clause in the order 347 357 they appear, top to bottom. If the representation of the raised exception type 348 is the same or a descendant of @EXCEPTION_TYPE@$_i$ then @NAME@$_i$358 is the same or a descendant of @EXCEPTION_TYPE@$_i$, then @NAME@$_i$ 349 359 (if provided) is 350 360 bound to a pointer to the exception and the statements in @HANDLER_BLOCK@$_i$ … … 352 362 freed and control continues after the try statement. 353 363 354 If no termination handler is found during the search then the default handler355 (\defaultTerminationHandler) visible at the raise statement is run.356 Through \CFA's trait system the best match at the raise statement will beused.364 If no termination handler is found during the search, then the default handler 365 (\defaultTerminationHandler) visible at the raise statement is called. 366 Through \CFA's trait system the best match at the raise statement is used. 357 367 This function is run and is passed the copied exception. 358 If the default handler is runcontrol continues after the raise statement.368 If the default handler finishes, control continues after the raise statement. 359 369 360 370 There is a global @defaultTerminationHandler@ that is polymorphic over all 361 371 termination exception types. 362 Since it is so general a more specific handler can be363 defined and is used for those types, effectively overriding the handler364 for a particular exception type.365 372 The global default termination handler performs a cancellation 366 (see \vref{s:Cancellation}) on the current stack with the copied exception. 373 (see \vref{s:Cancellation} for the justification) on the current stack with the copied exception. 374 Since it is so general, a more specific handler is usually 375 defined, possibly with a detailed message, and used for specific exception type, effectively overriding the default handler. 367 376 368 377 \subsection{Resumption} 369 378 \label{s:Resumption} 370 379 371 Resumption exception handling is less common than terminationbut is380 Resumption exception handling is the less familar EHM, but is 372 381 just as old~\cite{Goodenough75} and is simpler in many ways. 373 382 It is a dynamic, non-local function call. If the raised exception is 374 matched a closure is taken from up the stack and executed,383 matched, a closure is taken from up the stack and executed, 375 384 after which the raising function continues executing. 376 385 The common uses for resumption exceptions include … … 378 387 function once the error is corrected, and 379 388 ignorable events, such as logging where nothing needs to happen and control 380 should always continue from the same place.389 should always continue from the raise point. 381 390 382 391 A resumption raise is started with the @throwResume@ statement: … … 392 401 the exception system while handling the exception. 393 402 394 At run-time, no exception copy is made .395 Resumption does not unwind the stack nor otherwise remove values from the396 current scope, so there is no need to manage memory to keep th ingsin scope.397 398 The EHM then begins propagation. The searchstarts from the raise in the403 At run-time, no exception copy is made, since 404 resumption does not unwind the stack nor otherwise remove values from the 405 current scope, so there is no need to manage memory to keep the exception in scope. 406 407 Then propagation starts with the search. It starts from the raise in the 399 408 resuming function and proceeds towards the base of the stack, 400 409 from callee to caller. … … 410 419 } 411 420 \end{cfa} 421 % PAB, you say this above. 422 % When a try statement is executed, it simply executes the statements in the 423 % @GUARDED_BLOCK@ and then finishes. 424 % 425 % However, while the guarded statements are being executed, including any 426 % invoked functions, all the handlers in these statements are included in the 427 % search path. 428 % Hence, if a resumption exception is raised, these handlers may be matched 429 % against the exception and may handle it. 430 % 431 % Exception matching checks the handler in each catch clause in the order 432 % they appear, top to bottom. If the representation of the raised exception type 433 % is the same or a descendant of @EXCEPTION_TYPE@$_i$, then @NAME@$_i$ 434 % (if provided) is bound to a pointer to the exception and the statements in 435 % @HANDLER_BLOCK@$_i$ are executed. 436 % If control reaches the end of the handler, execution continues after the 437 % the raise statement that raised the handled exception. 438 % 439 % Like termination, if no resumption handler is found during the search, 440 % then the default handler (\defaultResumptionHandler) visible at the raise 441 % statement is called. It will use the best match at the raise sight according 442 % to \CFA's overloading rules. The default handler is 443 % passed the exception given to the raise. When the default handler finishes 444 % execution continues after the raise statement. 445 % 446 % There is a global @defaultResumptionHandler{} is polymorphic over all 447 % resumption exceptions and performs a termination throw on the exception. 448 % The \defaultTerminationHandler{} can be overridden by providing a new 449 % function that is a better match. 450 451 The @GUARDED_BLOCK@ and its associated nested guarded statements work the same 452 for resumption as for termination, as does exception matching at each 453 @catchResume@. Similarly, if no resumption handler is found during the search, 454 then the currently visible default handler (\defaultResumptionHandler) is 455 called and control continues after the raise statement if it returns. Finally, 456 there is also a global @defaultResumptionHandler@, which can be overridden, 457 that is polymorphic over all resumption exceptions but performs a termination 458 throw on the exception rather than a cancellation. 459 460 Throwing the exception in @defaultResumptionHandler@ has the positive effect of 461 walking the stack a second time for a recovery handler. Hence, a programmer has 462 two chances for help with a problem, fixup or recovery, should either kind of 463 handler appear on the stack. However, this dual stack walk leads to following 464 apparent anomaly: 465 \begin{cfa} 466 try { 467 throwResume E; 468 } catch (E) { 469 // this handler runs 470 } 471 \end{cfa} 472 because the @catch@ appears to handle a @throwResume@, but a @throwResume@ only 473 matches with @catchResume@. The anomaly results because the unmatched 474 @catchResuem@, calls @defaultResumptionHandler@, which in turn throws @E@. 475 412 476 % I wonder if there would be some good central place for this. 413 Note that termination handlersand resumption handlers may be used together477 Note, termination and resumption handlers may be used together 414 478 in a single try statement, intermixing @catch@ and @catchResume@ freely. 415 479 Each type of handler only interacts with exceptions from the matching 416 480 kind of raise. 417 When a try statement is executed, it simply executes the statements in the418 @GUARDED_BLOCK@ and then finishes.419 420 However, while the guarded statements are being executed, including any421 invoked functions, all the handlers in these statements are included in the422 search path.423 Hence, if a resumption exception is raised these handlers may be matched424 against the exception and may handle it.425 426 Exception matching checks the handler in each catch clause in the order427 they appear, top to bottom. If the representation of the raised exception type428 is the same or a descendant of @EXCEPTION_TYPE@$_i$ then @NAME@$_i$429 (if provided) is bound to a pointer to the exception and the statements in430 @HANDLER_BLOCK@$_i$ are executed.431 If control reaches the end of the handler, execution continues after the432 the raise statement that raised the handled exception.433 434 Like termination, if no resumption handler is found during the search,435 the default handler (\defaultResumptionHandler) visible at the raise436 statement is called. It will use the best match at the raise sight according437 to \CFA's overloading rules. The default handler is438 passed the exception given to the raise. When the default handler finishes439 execution continues after the raise statement.440 441 There is a global \defaultResumptionHandler{} is polymorphic over all442 resumption exceptions and preforms a termination throw on the exception.443 The \defaultTerminationHandler{} can be overridden by providing a new444 function that is a better match.445 481 446 482 \subsubsection{Resumption Marking} 447 483 \label{s:ResumptionMarking} 448 484 A key difference between resumption and termination is that resumption does 449 not unwind the stack. A side effect that is thatwhen a handler is matched450 and run it's try block (the guarded statements) and every try statement485 not unwind the stack. A side effect is that, when a handler is matched 486 and run, its try block (the guarded statements) and every try statement 451 487 searched before it are still on the stack. There presence can lead to 452 the recursive resumption problem.488 the \emph{recursive resumption problem}. 453 489 454 490 The recursive resumption problem is any situation where a resumption handler … … 464 500 When this code is executed, the guarded @throwResume@ starts a 465 501 search and matches the handler in the @catchResume@ clause. This 466 call is placed on the stack above the try-block. The second raise then467 searches the same try block and puts another instance of the502 call is placed on the stack above the try-block. Now the second raise in the handler 503 searches the same try block, matches, and puts another instance of the 468 504 same handler on the stack leading to infinite recursion. 469 505 470 While this situation is trivial and easy to avoid, much more complex cycles 471 can form with multiple handlers and different exception types. 472 473 To prevent all of these cases, a each try statement is ``marked" from the 474 time the exception search reaches it to either when the exception is being 475 handled completes the matching handler or when the search reaches the base 506 While this situation is trivial and easy to avoid, much more complex cycles can 507 form with multiple handlers and different exception types. The key point is 508 that the programmer's intuition expects every raise in a handler to start 509 searching \emph{below} the @try@ statement, making it difficult to understand 510 and fix the problem. 511 512 To prevent all of these cases, each try statement is ``marked" from the 513 time the exception search reaches it to either when a matching handler 514 completes or when the search reaches the base 476 515 of the stack. 477 516 While a try statement is marked, its handlers are never matched, effectively … … 485 524 for instance, marking just the handlers that caught the exception, 486 525 would also prevent recursive resumption. 487 However, these rules mirror what happens with termination. 488 489 The try statements that are marked are the ones that would be removed from 490 the stack if this was a termination exception, that is those on the stack 526 However, the rule selected mirrors what happens with termination, 527 and hence, matches programmer intuition that a raise searches below a try. 528 529 In detail, the marked try statements are the ones that would be removed from 530 the stack for a termination exception, \ie those on the stack 491 531 between the handler and the raise statement. 492 532 This symmetry applies to the default handler as well, as both kinds of … … 522 562 // Only handle IO failure for f3. 523 563 } 524 // Can't handle a failure relating to f2 here.564 // Handle a failure relating to f2 further down the stack. 525 565 \end{cfa} 526 566 In this example the file that experienced the IO error is used to decide … … 553 593 554 594 \subsection{Comparison with Reraising} 555 A more popular way to allow handlers to match in more detail is to reraise 556 the exception after it has been caught, if it could not be handled here. 557 On the surface these two features seem interchangeable. 558 559 If @throw;@ (no argument) starts a termination reraise, 560 which is the same as a raise but reuses the last caught exception, 561 then these two statements have the same behaviour: 562 \begin{cfa} 563 try { 564 do_work_may_throw(); 565 } catch(exception_t * exc ; can_handle(exc)) { 566 handle(exc); 567 } 568 \end{cfa} 569 570 \begin{cfa} 571 try { 572 do_work_may_throw(); 573 } catch(exception_t * exc) { 574 if (can_handle(exc)) { 575 handle(exc); 576 } else { 577 throw; 578 } 579 } 580 \end{cfa} 581 That is, they will have the same behaviour in isolation. 595 Without conditional catch, the only approach to match in more detail is to reraise 596 the exception after it has been caught, if it could not be handled. 597 \begin{center} 598 \begin{tabular}{l|l} 599 \begin{cfa} 600 try { 601 do_work_may_throw(); 602 } catch(excep_t * ex; can_handle(ex)) { 603 604 handle(ex); 605 606 607 608 } 609 \end{cfa} 610 & 611 \begin{cfa} 612 try { 613 do_work_may_throw(); 614 } catch(excep_t * ex) { 615 if (can_handle(ex)) { 616 handle(ex); 617 } else { 618 throw; 619 } 620 } 621 \end{cfa} 622 \end{tabular} 623 \end{center} 624 Notice catch-and-reraise increases complexity by adding additional data and 625 code to the exception process. Nevertheless, catch-and-reraise can simulate 626 conditional catch straightforwardly, when exceptions are disjoint, \ie no 627 inheritance. 628 629 However, catch-and-reraise simulation becomes unusable for exception inheritance. 630 \begin{flushleft} 631 \begin{cfa}[xleftmargin=6pt] 632 exception E1; 633 exception E2(E1); // inheritance 634 \end{cfa} 635 \begin{tabular}{l|l} 636 \begin{cfa} 637 try { 638 ... foo(); ... // raise E1/E2 639 ... bar(); ... // raise E1/E2 640 } catch( E2 e; e.rtn == foo ) { 641 ... 642 } catch( E1 e; e.rtn == foo ) { 643 ... 644 } catch( E1 e; e.rtn == bar ) { 645 ... 646 } 647 648 \end{cfa} 649 & 650 \begin{cfa} 651 try { 652 ... foo(); ... 653 ... bar(); ... 654 } catch( E2 e ) { 655 if ( e.rtn == foo ) { ... 656 } else throw; // reraise 657 } catch( E1 e ) { 658 if (e.rtn == foo) { ... 659 } else if (e.rtn == bar) { ... 660 else throw; // reraise 661 } 662 \end{cfa} 663 \end{tabular} 664 \end{flushleft} 665 The derived exception @E2@ must be ordered first in the catch list, otherwise 666 the base exception @E1@ catches both exceptions. In the catch-and-reraise code 667 (right), the @E2@ handler catches exceptions from both @foo@ and 668 @bar@. However, the reraise misses the following catch clause. To fix this 669 problem, an enclosing @try@ statement is need to catch @E2@ for @bar@ from the 670 reraise, and its handler must duplicate the inner handler code for @bar@. To 671 generalize, this fix for any amount of inheritance and complexity of try 672 statement requires a technique called \emph{try-block 673 splitting}~\cite{Krischer02}, which is not discussed in this thesis. It is 674 sufficient to state that conditional catch is more expressive than 675 catch-and-reraise in terms of complexity. 676 677 \begin{comment} 678 That is, they have the same behaviour in isolation. 582 679 Two things can expose differences between these cases. 583 680 584 681 One is the existence of multiple handlers on a single try statement. 585 A reraise skips all later handlers on thistry statement but a conditional682 A reraise skips all later handlers for a try statement but a conditional 586 683 catch does not. 587 Hence, if an earlier handler contains a reraise later handlers are588 implicitly skipped, with a conditional catch they are not.684 % Hence, if an earlier handler contains a reraise later handlers are 685 % implicitly skipped, with a conditional catch they are not. 589 686 Still, they are equivalently powerful, 590 687 both can be used two mimic the behaviour of the other, … … 637 734 % `exception_ptr current_exception() noexcept;` 638 735 % https://www.python.org/dev/peps/pep-0343/ 736 \end{comment} 639 737 640 738 \section{Finally Clauses} … … 652 750 The @FINALLY_BLOCK@ is executed when the try statement is removed from the 653 751 stack, including when the @GUARDED_BLOCK@ finishes, any termination handler 654 finishes or during an unwind.752 finishes, or during an unwind. 655 753 The only time the block is not executed is if the program is exited before 656 754 the stack is unwound. … … 668 766 669 767 Not all languages with unwinding have finally clauses. Notably \Cpp does 670 without it as des cructors, and the RAII design pattern, serve a similar role.671 Although destructors and finally clauses can be used inthe same cases,768 without it as destructors, and the RAII design pattern, serve a similar role. 769 Although destructors and finally clauses can be used for the same cases, 672 770 they have their own strengths, similar to top-level function and lambda 673 771 functions with closures. 674 Destructors take more work for their first use, but if there is clean-up code675 that needs to be run every time a type is used they soon become much easier772 Destructors take more work for their creation, but if there is clean-up code 773 that needs to be run every time a type is used, they are much easier 676 774 to set-up. 677 775 On the other hand finally clauses capture the local context, so is easy to 678 776 use when the clean-up is not dependent on the type of a variable or requires 679 777 information from multiple variables. 680 % To Peter: I think these are the main points you were going for.681 778 682 779 \section{Cancellation} … … 691 788 raise, this exception is not used in matching only to pass information about 692 789 the cause of the cancellation. 693 (This also means matching cannot fail so there is no default handler.) 790 Finaly, since a cancellation only unwinds and forwards, there is no default handler. 694 791 695 792 After @cancel_stack@ is called the exception is copied into the EHM's memory … … 702 799 After the main stack is unwound there is a program-level abort. 703 800 704 The re are two reasons for these semantics.705 Th e first is that it had to do this abort.706 in a sequential program as there is nothing else to notify and the simplicity 707 of keeping the same behaviour in sequential and concurrent programs is good.801 The reasons for this semantics in a sequential program is that there is no more code to execute. 802 This semantics also applies to concurrent programs, too, even if threads are running. 803 That is, if any threads starts a cancellation, it implies all threads terminate. 804 Keeping the same behaviour in sequential and concurrent programs is simple. 708 805 Also, even in concurrent programs there may not currently be any other stacks 709 806 and even if other stacks do exist, main has no way to know where they are. … … 750 847 caller's context and passes it to the internal report. 751 848 752 A coroutine knows of two other coroutines, its starter and its last resumer.849 A coroutine only knows of two other coroutines, its starter and its last resumer. 753 850 The starter has a much more distant connection, while the last resumer just 754 851 (in terms of coroutine state) called resume on this coroutine, so the message … … 758 855 cascade an error across any number of coroutines, cleaning up each in turn, 759 856 until the error is handled or a thread stack is reached. 857 858 \PAB{Part of this I do not understand. A cancellation cannot be caught. But you 859 talk about handling a cancellation in the last sentence. Which is correct?}
Note: See TracChangeset
for help on using the changeset viewer.