- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/andrew_beach_MMath/features.tex
r93d0ed3 rf42a6b8 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 alanguage.18 be the only two pieces of the EHM that have any syntax in the language. 19 19 20 20 \paragraph{Raise} 21 The raise is the starting point for exception handling 22 by raising an exception, which passes it to21 The raise is the starting point for exception handling. It marks the beginning 22 of exception handling 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 of Python. In real systems,a raise may27 p erform some other work (such as memory management) but for the26 the \code{Python}{raise} statement from Python. In real systems a raise may 27 preform 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 rimary purpose of an EHM is to run some user code to handle a raised32 exception. This code is given, with some other information, in a handler.31 The purpose of most exception operations is to run some user code to handle 32 that 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 it guards,and an exception label/condition that matches36 the raised exception.35 region of code they guard and an exception label/condition that matches 36 certain exceptions. 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 define a rule to pick one, such as ``best match" or ``first found".40 EHMs will 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 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} 43 also show another common feature of handlers, they are grouped by the guarded 44 region. 53 45 54 46 \subsection{Propagation} 55 47 After an exception is raised comes what is usually the biggest step for the 56 EHM: finding and setting up the handler for execution. The propagation from raise to48 EHM: finding and setting up the handler. The propagation from raise to 57 49 handler can be broken up into three different tasks: searching for a handler, 58 50 matching against the handler and installing the handler. … … 60 52 \paragraph{Searching} 61 53 The EHM begins by searching for handlers that might be used to handle 62 the exception. The search is restricted to63 handlers that have the raise site in their guarded54 the exception. Searching is usually independent of the exception that was 55 thrown as it looks for handlers that have the raise site in their guarded 64 56 region. 65 57 The search includes handlers in the current function, as well as any in … … 67 59 68 60 \paragraph{Matching} 69 Each handler found ismatched with the raised exception. The exception70 label defines a condition that is used with theexception and decides if61 Each handler found has to be matched with the raised exception. The exception 62 label defines a condition that is used with exception and decides if 71 63 there is a match or not. 64 72 65 In languages where the first match is used, this step is intertwined with 73 searching; a match check is p erformed immediately after the search finds74 a handler.66 searching; a match check is preformed immediately after the search finds 67 a possible handler. 75 68 76 69 \paragraph{Installing} 77 After a handler is chosen ,it must be made ready to run.70 After a handler is chosen it must be made ready to run. 78 71 The implementation can vary widely to fit with the rest of the 79 72 design of the EHM. The installation step might be trivial or it could be … … 82 75 83 76 If a matching handler is not guaranteed to be found, the EHM needs a 84 different course of action for th is case.77 different course of action for the case where no handler matches. 85 78 This situation only occurs with unchecked exceptions as checked exceptions 86 (such as in Java) are guaranteed to find a matching handler.87 Th eunhandled action is usually very general, such as aborting the program.79 (such as in Java) can make the guarantee. 80 This unhandled action is usually very general, such as aborting the program. 88 81 89 82 \paragraph{Hierarchy} … … 92 85 exception hierarchy is a natural extension of the object hierarchy. 93 86 94 Consider the following exception hierarchy:87 Consider the following hierarchy of exceptions: 95 88 \begin{center} 96 89 \input{exception-hierarchy} 97 90 \end{center} 91 98 92 A handler labeled with any given exception can handle exceptions of that 99 93 type or any child type of that exception. The root of the exception hierarchy 100 (here \code{C}{exception}) acts as a catch-all, leaf types catch single types ,94 (here \code{C}{exception}) acts as a catch-all, leaf types catch single types 101 95 and the exceptions in the middle can be used to catch different groups of 102 96 related exceptions. 103 97 104 98 This system has some notable advantages, such as multiple levels of grouping, 105 the ability for libraries to add new exception types ,and the isolation99 the ability for libraries to add new exception types and the isolation 106 100 between different sub-hierarchies. 107 101 This design is used in \CFA even though it is not a object-orientated … … 116 110 is usually set up to do most of the work. 117 111 118 The EHM can return control to many different places, where112 The EHM can return control to many different places, 119 113 the most common are after the handler definition (termination) 120 114 and after the raise (resumption). … … 123 117 For effective exception handling, additional information is often passed 124 118 from the raise to the handler and back again. 125 So far , only communication of the exception's identity iscovered.126 A common communication method for passing more informationis putting fields into the exception instance119 So far only communication of the exceptions' identity has been covered. 120 A common communication method is putting fields into the exception instance 127 121 and giving the handler access to them. 128 Using reference fields pointing to data at the raise location allowsdata to be122 Passing the exception by reference instead of by value can allow data to be 129 123 passed in both directions. 130 124 131 125 \section{Virtuals} 132 \label{s:Virtuals}133 126 Virtual types and casts are not part of \CFA's EHM nor are they required for 134 an EHM.135 However, one of the best ways to support an exception hierarchy127 any EHM. 128 However, it is one of the best ways to support an exception hierarchy 136 129 is via a virtual hierarchy and dispatch system. 137 Ideally, the virtual system should have been part of \CFA before the work 130 131 Ideally, the virtual system would have been part of \CFA before the work 138 132 on exception handling began, but unfortunately it was not. 139 133 Hence, only the features and framework needed for the EHM were 140 designed and implemented for this thesis. Other features were considered to ensure that134 designed and implemented. Other features were considered to ensure that 141 135 the structure could accommodate other desirable features in the future 142 but are not implemented.143 The rest of this section only discusses the implemented subset of the144 virtual -system design.136 but they were not implemented. 137 The rest of this section will only discuss the implemented subset of the 138 virtual system design. 145 139 146 140 The virtual system supports multiple ``trees" of types. Each tree is … … 149 143 number of children. 150 144 Any type that belongs to any of these trees is called a virtual type. 151 For example, the following hypothetical syntax creates two virtual-type trees. 152 \begin{flushleft} 153 \lstDeleteShortInline@ 154 \begin{tabular}{@{\hspace{20pt}}l@{\hspace{20pt}}l} 155 \begin{cfa} 156 vtype V0, V1(V0), V2(V0); 157 vtype W0, W1(W0), W2(W1); 158 \end{cfa} 159 & 160 \raisebox{-0.6\totalheight}{\input{vtable}} 161 \end{tabular} 162 \lstMakeShortInline@ 163 \end{flushleft} 145 164 146 % A type's ancestors are its parent and its parent's ancestors. 165 147 % The root type has no ancestors. 166 148 % A type's descendants are its children and its children's descendants. 167 Every virtual type (tree node) has a pointer to a virtual table with a unique 168 @Id@ and a list of virtual members (see \autoref{s:VirtualSystem} for 169 details). Children inherit their parent's list of virtual members but may add 170 and/or replace members. For example, 171 \begin{cfa} 172 vtable W0 | { int ?<?( int, int ); int ?+?( int, int ); } 173 vtable W1 | { int ?+?( int, int ); int w, int ?-?( int, int ); } 174 \end{cfa} 175 creates a virtual table for @W0@ initialized with the matching @<@ and @+@ 176 operations visible at this declaration context. Similarly, @W1@ is initialized 177 with @<@ from inheritance with @W0@, @+@ is replaced, and @-@ is added, where 178 both operations are matched at this declaration context. It is important to 179 note that these are virtual members, not virtual methods of object-orientated 180 programming, and can be of any type. Finally, trait names can be used to 181 specify the list of virtual members. 182 183 \PAB{Need to look at these when done. 149 150 Every virtual type also has a list of virtual members. Children inherit 151 their parent's list of virtual members but may add new members to it. 152 It is important to note that these are virtual members, not virtual methods 153 of object-orientated programming, and can be of any type. 184 154 185 155 \CFA still supports virtual methods as a special case of virtual members. … … 189 159 as if it were a method. 190 160 \todo{Clarify (with an example) virtual methods.} 191 }% 161 162 Each virtual type has a unique id. 163 This id and all the virtual members are combined 164 into a virtual table type. Each virtual type has a pointer to a virtual table 165 as a hidden field. 166 \todo{Might need a diagram for virtual structure.} 192 167 193 168 Up until this point the virtual system is similar to ones found in 194 object-orientated languages but this is where \CFA diverges. Objects encapsulate a 195 single set of methods in each type, universally across the entire program, 196 and indeed all programs that use that type definition. Even if a type inherits and adds methods, it still encapsulate a 197 single set of methods. In this sense, 198 object-oriented types are ``closed" and cannot be altered. 199 200 In \CFA, types do not encapsulate any code. Traits are local for each function and 201 types can satisfy a local trait, stop satisfying it or, satisfy the same 202 trait in a different way at any lexical location in the program where a function is call. 203 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. 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. 204 178 This capability means it is impossible to pick a single set of functions 205 that represent a type's implementation across aprogram.179 that represent the type's implementation across the program. 206 180 207 181 \CFA side-steps this issue by not having a single virtual table for each 208 182 type. A user can define virtual tables that are filled in at their 209 183 declaration and given a name. Anywhere that name is visible, even if it is 210 defined locally inside a function \PAB{What does this mean?(although that means it does not have a211 static lifetime) }, it can be used.184 defined locally inside a function (although that means it does not have a 185 static lifetime), it can be used. 212 186 Specifically, a virtual type is ``bound" to a virtual table that 213 187 sets the virtual members for that object. The virtual members can be accessed … … 247 221 completing the virtual system). The imaginary assertions would probably come 248 222 from a trait defined by the virtual system, and state that the exception type 249 is a virtual type, is a descendant of @exception_t@ (the base exception type) ,223 is a virtual type, is a descendant of @exception_t@ (the base exception type) 250 224 and note its virtual table type. 251 225 … … 267 241 \end{cfa} 268 242 Both traits ensure a pair of types are an exception type, its virtual table 269 type ,243 type 270 244 and defines one of the two default handlers. The default handlers are used 271 245 as fallbacks and are discussed in detail in \vref{s:ExceptionHandling}. … … 276 250 facing way. So these three macros are provided to wrap these traits to 277 251 simplify referring to the names: 278 @IS_EXCEPTION@, @IS_TERMINATION_EXCEPTION@ ,and @IS_RESUMPTION_EXCEPTION@.252 @IS_EXCEPTION@, @IS_TERMINATION_EXCEPTION@ and @IS_RESUMPTION_EXCEPTION@. 279 253 280 254 All three take one or two arguments. The first argument is the name of the … … 298 272 \CFA provides two kinds of exception handling: termination and resumption. 299 273 These twin operations are the core of \CFA's exception handling mechanism. 300 This section coversthe general patterns shared by the two operations and301 then go es on to cover the details ofeach individual operation.274 This section will cover the general patterns shared by the two operations and 275 then go on to cover the details each individual operation. 302 276 303 277 Both operations follow the same set of steps. 304 First, a user raisesan exception.305 Second,the exception propagates up the stack.306 Third, if a handler is found,the exception is caught and the handler is run.278 Both start with the user preforming a raise on an exception. 279 Then the exception propagates up the stack. 280 If a handler is found the exception is caught and the handler is run. 307 281 After that control continues at a raise-dependent location. 308 Fourth, if a handler is not found,a default handler is run and, if it returns, then control282 If the search fails a default handler is run and, if it returns, then control 309 283 continues after the raise. 310 284 311 %This general description covers what the two kinds have in common.312 The differences in the two operations include how propagation is performed, where execution continues313 after an exception is caught and handled ,and which default handler is run.285 This general description covers what the two kinds have in common. 286 Differences include how propagation is preformed, where exception continues 287 after an exception is caught and handled and which default handler is run. 314 288 315 289 \subsection{Termination} 316 290 \label{s:Termination} 317 Termination handling is the familiar EHMand used in most programming291 Termination handling is the familiar kind and used in most programming 318 292 languages with exception handling. 319 293 It is a dynamic, non-local goto. If the raised exception is matched and … … 334 308 @is_termination_exception@ at the call site. 335 309 Through \CFA's trait system, the trait functions are implicitly passed into the 336 throw code for use bythe EHM.310 throw code and the EHM. 337 311 A new @defaultTerminationHandler@ can be defined in any scope to 338 change the throw's behaviour when a handler is not found(see below).312 change the throw's behaviour (see below). 339 313 340 314 The throw copies the provided exception into managed memory to ensure … … 346 320 % How to say propagation starts, its first sub-step is the search. 347 321 Then propagation starts with the search. \CFA uses a ``first match" rule so 348 matching is p erformed with the copied exception as the search key.349 It starts from the raise in the throwing function and proceeds towards thebase of the stack,322 matching is preformed with the copied exception as the search continues. 323 It starts from the throwing function and proceeds towards base of the stack, 350 324 from callee to caller. 351 At each stack frame, a check is made for termination handlers defined by the325 At each stack frame, a check is made for resumption handlers defined by the 352 326 @catch@ clauses of a @try@ statement. 353 327 \begin{cfa} … … 361 335 \end{cfa} 362 336 When viewed on its own, a try statement simply executes the statements 363 in the \snake{GUARDED_BLOCK},and when those are finished,337 in \snake{GUARDED_BLOCK} and when those are finished, 364 338 the try statement finishes. 365 339 … … 367 341 invoked functions, all the handlers in these statements are included in the 368 342 search path. 369 Hence, if a termination exception is raised ,these handlers may be matched343 Hence, if a termination exception is raised these handlers may be matched 370 344 against the exception and may handle it. 371 345 372 346 Exception matching checks the handler in each catch clause in the order 373 347 they appear, top to bottom. If the representation of the raised exception type 374 is the same or a descendant of @EXCEPTION_TYPE@$_i$ ,then @NAME@$_i$348 is the same or a descendant of @EXCEPTION_TYPE@$_i$ then @NAME@$_i$ 375 349 (if provided) is 376 350 bound to a pointer to the exception and the statements in @HANDLER_BLOCK@$_i$ … … 378 352 freed and control continues after the try statement. 379 353 380 If no termination handler is found during the search ,then the default handler381 (\defaultTerminationHandler) visible at the raise statement is called.382 Through \CFA's trait system the best match at the raise statement isused.354 If no termination handler is found during the search then the default handler 355 (\defaultTerminationHandler) visible at the raise statement is run. 356 Through \CFA's trait system the best match at the raise statement will be used. 383 357 This function is run and is passed the copied exception. 384 If the default handler finishes,control continues after the raise statement.358 If the default handler is run control continues after the raise statement. 385 359 386 360 There is a global @defaultTerminationHandler@ that is polymorphic over all 387 361 termination exception types. 362 Since it is so general a more specific handler can be 363 defined and is used for those types, effectively overriding the handler 364 for a particular exception type. 388 365 The global default termination handler performs a cancellation 389 (see \vref{s:Cancellation} for the justification) on the current stack with the copied exception. 390 Since it is so general, a more specific handler is usually 391 defined, possibly with a detailed message, and used for specific exception type, effectively overriding the default handler. 366 (see \vref{s:Cancellation}) on the current stack with the copied exception. 392 367 393 368 \subsection{Resumption} 394 369 \label{s:Resumption} 395 370 396 Resumption exception handling is the less familar EHM,but is371 Resumption exception handling is less common than termination but is 397 372 just as old~\cite{Goodenough75} and is simpler in many ways. 398 373 It is a dynamic, non-local function call. If the raised exception is 399 matched ,a closure is taken from up the stack and executed,374 matched a closure is taken from up the stack and executed, 400 375 after which the raising function continues executing. 401 376 The common uses for resumption exceptions include … … 403 378 function once the error is corrected, and 404 379 ignorable events, such as logging where nothing needs to happen and control 405 should always continue from the raise point.380 should always continue from the same place. 406 381 407 382 A resumption raise is started with the @throwResume@ statement: … … 417 392 the exception system while handling the exception. 418 393 419 At run-time, no exception copy is made , since420 resumption does not unwind the stack nor otherwise remove values from the421 current scope, so there is no need to manage memory to keep th e exceptionin scope.422 423 The n propagation starts with the search. Itstarts from the raise in the394 At run-time, no exception copy is made. 395 Resumption does not unwind the stack nor otherwise remove values from the 396 current scope, so there is no need to manage memory to keep things in scope. 397 398 The EHM then begins propagation. The search starts from the raise in the 424 399 resuming function and proceeds towards the base of the stack, 425 400 from callee to caller. … … 435 410 } 436 411 \end{cfa} 437 % PAB, you say this above.438 % When a try statement is executed, it simply executes the statements in the439 % @GUARDED_BLOCK@ and then finishes.440 %441 % However, while the guarded statements are being executed, including any442 % invoked functions, all the handlers in these statements are included in the443 % search path.444 % Hence, if a resumption exception is raised, these handlers may be matched445 % against the exception and may handle it.446 %447 % Exception matching checks the handler in each catch clause in the order448 % they appear, top to bottom. If the representation of the raised exception type449 % is the same or a descendant of @EXCEPTION_TYPE@$_i$, then @NAME@$_i$450 % (if provided) is bound to a pointer to the exception and the statements in451 % @HANDLER_BLOCK@$_i$ are executed.452 % If control reaches the end of the handler, execution continues after the453 % the raise statement that raised the handled exception.454 %455 % Like termination, if no resumption handler is found during the search,456 % then the default handler (\defaultResumptionHandler) visible at the raise457 % statement is called. It will use the best match at the raise sight according458 % to \CFA's overloading rules. The default handler is459 % passed the exception given to the raise. When the default handler finishes460 % execution continues after the raise statement.461 %462 % There is a global @defaultResumptionHandler{} is polymorphic over all463 % resumption exceptions and performs a termination throw on the exception.464 % The \defaultTerminationHandler{} can be overridden by providing a new465 % function that is a better match.466 467 The @GUARDED_BLOCK@ and its associated nested guarded statements work the same468 for resumption as for termination, as does exception matching at each469 @catchResume@. Similarly, if no resumption handler is found during the search,470 then the currently visible default handler (\defaultResumptionHandler) is471 called and control continues after the raise statement if it returns. Finally,472 there is also a global @defaultResumptionHandler@, which can be overridden,473 that is polymorphic over all resumption exceptions but performs a termination474 throw on the exception rather than a cancellation.475 476 Throwing the exception in @defaultResumptionHandler@ has the positive effect of477 walking the stack a second time for a recovery handler. Hence, a programmer has478 two chances for help with a problem, fixup or recovery, should either kind of479 handler appear on the stack. However, this dual stack walk leads to following480 apparent anomaly:481 \begin{cfa}482 try {483 throwResume E;484 } catch (E) {485 // this handler runs486 }487 \end{cfa}488 because the @catch@ appears to handle a @throwResume@, but a @throwResume@ only489 matches with @catchResume@. The anomaly results because the unmatched490 @catchResuem@, calls @defaultResumptionHandler@, which in turn throws @E@.491 492 412 % I wonder if there would be some good central place for this. 493 Note , terminationand resumption handlers may be used together413 Note that termination handlers and resumption handlers may be used together 494 414 in a single try statement, intermixing @catch@ and @catchResume@ freely. 495 415 Each type of handler only interacts with exceptions from the matching 496 416 kind of raise. 417 When a try statement is executed, it simply executes the statements in the 418 @GUARDED_BLOCK@ and then finishes. 419 420 However, while the guarded statements are being executed, including any 421 invoked functions, all the handlers in these statements are included in the 422 search path. 423 Hence, if a resumption exception is raised these handlers may be matched 424 against the exception and may handle it. 425 426 Exception matching checks the handler in each catch clause in the order 427 they appear, top to bottom. If the representation of the raised exception type 428 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 in 430 @HANDLER_BLOCK@$_i$ are executed. 431 If control reaches the end of the handler, execution continues after the 432 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 raise 436 statement is called. It will use the best match at the raise sight according 437 to \CFA's overloading rules. The default handler is 438 passed the exception given to the raise. When the default handler finishes 439 execution continues after the raise statement. 440 441 There is a global \defaultResumptionHandler{} is polymorphic over all 442 resumption exceptions and preforms a termination throw on the exception. 443 The \defaultTerminationHandler{} can be overridden by providing a new 444 function that is a better match. 497 445 498 446 \subsubsection{Resumption Marking} 499 447 \label{s:ResumptionMarking} 500 448 A key difference between resumption and termination is that resumption does 501 not unwind the stack. A side effect is that,when a handler is matched502 and run , its try block (the guarded statements) and every try statement449 not unwind the stack. A side effect that is that when a handler is matched 450 and run it's try block (the guarded statements) and every try statement 503 451 searched before it are still on the stack. There presence can lead to 504 the \emph{recursive resumption problem}.452 the recursive resumption problem. 505 453 506 454 The recursive resumption problem is any situation where a resumption handler … … 516 464 When this code is executed, the guarded @throwResume@ starts a 517 465 search and matches the handler in the @catchResume@ clause. This 518 call is placed on the stack above the try-block. Now the second raise in the handler519 searches the same try block , matches,and puts another instance of the466 call is placed on the stack above the try-block. The second raise then 467 searches the same try block and puts another instance of the 520 468 same handler on the stack leading to infinite recursion. 521 469 522 While this situation is trivial and easy to avoid, much more complex cycles can 523 form with multiple handlers and different exception types. The key point is 524 that the programmer's intuition expects every raise in a handler to start 525 searching \emph{below} the @try@ statement, making it difficult to understand 526 and fix the problem. 527 528 To prevent all of these cases, each try statement is ``marked" from the 529 time the exception search reaches it to either when a matching handler 530 completes or when the search reaches the base 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 531 476 of the stack. 532 477 While a try statement is marked, its handlers are never matched, effectively … … 540 485 for instance, marking just the handlers that caught the exception, 541 486 would also prevent recursive resumption. 542 However, the rule selected mirrors what happens with termination, 543 and hence, matches programmer intuition that a raise searches below a try. 544 545 In detail, the marked try statements are the ones that would be removed from 546 the stack for a termination exception, \ie those on the stack 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 547 491 between the handler and the raise statement. 548 492 This symmetry applies to the default handler as well, as both kinds of … … 578 522 // Only handle IO failure for f3. 579 523 } 580 // Handle a failure relating to f2 further down the stack.524 // Can't handle a failure relating to f2 here. 581 525 \end{cfa} 582 526 In this example the file that experienced the IO error is used to decide … … 609 553 610 554 \subsection{Comparison with Reraising} 611 Without conditional catch, the only approach to match in more detail is to reraise 612 the exception after it has been caught, if it could not be handled. 613 \begin{center} 614 \begin{tabular}{l|l} 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: 615 562 \begin{cfa} 616 563 try { 617 do_work_may_throw(); 618 } catch(excep_t * ex; can_handle(ex)) { 619 620 handle(ex); 621 622 623 564 do_work_may_throw(); 565 } catch(exception_t * exc ; can_handle(exc)) { 566 handle(exc); 624 567 } 625 568 \end{cfa} 626 & 569 627 570 \begin{cfa} 628 571 try { 629 630 } catch(excep _t * ex) {631 if (can_handle(ex)) {632 handle(ex);633 634 635 572 do_work_may_throw(); 573 } catch(exception_t * exc) { 574 if (can_handle(exc)) { 575 handle(exc); 576 } else { 577 throw; 578 } 636 579 } 637 580 \end{cfa} 638 \end{tabular} 639 \end{center} 640 Notice catch-and-reraise increases complexity by adding additional data and 641 code to the exception process. Nevertheless, catch-and-reraise can simulate 642 conditional catch straightforwardly, when exceptions are disjoint, \ie no 643 inheritance. 644 645 However, catch-and-reraise simulation becomes unusable for exception inheritance. 646 \begin{flushleft} 647 \begin{cfa}[xleftmargin=6pt] 648 exception E1; 649 exception E2(E1); // inheritance 650 \end{cfa} 651 \begin{tabular}{l|l} 652 \begin{cfa} 653 try { 654 ... foo(); ... // raise E1/E2 655 ... bar(); ... // raise E1/E2 656 } catch( E2 e; e.rtn == foo ) { 657 ... 658 } catch( E1 e; e.rtn == foo ) { 659 ... 660 } catch( E1 e; e.rtn == bar ) { 661 ... 662 } 663 664 \end{cfa} 665 & 666 \begin{cfa} 667 try { 668 ... foo(); ... 669 ... bar(); ... 670 } catch( E2 e ) { 671 if ( e.rtn == foo ) { ... 672 } else throw; // reraise 673 } catch( E1 e ) { 674 if (e.rtn == foo) { ... 675 } else if (e.rtn == bar) { ... 676 else throw; // reraise 677 } 678 \end{cfa} 679 \end{tabular} 680 \end{flushleft} 681 The derived exception @E2@ must be ordered first in the catch list, otherwise 682 the base exception @E1@ catches both exceptions. In the catch-and-reraise code 683 (right), the @E2@ handler catches exceptions from both @foo@ and 684 @bar@. However, the reraise misses the following catch clause. To fix this 685 problem, an enclosing @try@ statement is need to catch @E2@ for @bar@ from the 686 reraise, and its handler must duplicate the inner handler code for @bar@. To 687 generalize, this fix for any amount of inheritance and complexity of try 688 statement requires a technique called \emph{try-block 689 splitting}~\cite{Krischer02}, which is not discussed in this thesis. It is 690 sufficient to state that conditional catch is more expressive than 691 catch-and-reraise in terms of complexity. 692 693 \begin{comment} 694 That is, they have the same behaviour in isolation. 581 That is, they will have the same behaviour in isolation. 695 582 Two things can expose differences between these cases. 696 583 697 584 One is the existence of multiple handlers on a single try statement. 698 A reraise skips all later handlers for atry statement but a conditional585 A reraise skips all later handlers on this try statement but a conditional 699 586 catch does not. 700 %Hence, if an earlier handler contains a reraise later handlers are701 %implicitly skipped, with a conditional catch they are not.587 Hence, if an earlier handler contains a reraise later handlers are 588 implicitly skipped, with a conditional catch they are not. 702 589 Still, they are equivalently powerful, 703 590 both can be used two mimic the behaviour of the other, … … 750 637 % `exception_ptr current_exception() noexcept;` 751 638 % https://www.python.org/dev/peps/pep-0343/ 752 \end{comment}753 639 754 640 \section{Finally Clauses} … … 766 652 The @FINALLY_BLOCK@ is executed when the try statement is removed from the 767 653 stack, including when the @GUARDED_BLOCK@ finishes, any termination handler 768 finishes ,or during an unwind.654 finishes or during an unwind. 769 655 The only time the block is not executed is if the program is exited before 770 656 the stack is unwound. … … 782 668 783 669 Not all languages with unwinding have finally clauses. Notably \Cpp does 784 without it as des tructors, and the RAII design pattern, serve a similar role.785 Although destructors and finally clauses can be used forthe same cases,670 without it as descructors, and the RAII design pattern, serve a similar role. 671 Although destructors and finally clauses can be used in the same cases, 786 672 they have their own strengths, similar to top-level function and lambda 787 673 functions with closures. 788 Destructors take more work for their creation, but if there is clean-up code789 that needs to be run every time a type is used , they are much easier674 Destructors take more work for their first use, but if there is clean-up code 675 that needs to be run every time a type is used they soon become much easier 790 676 to set-up. 791 677 On the other hand finally clauses capture the local context, so is easy to 792 678 use when the clean-up is not dependent on the type of a variable or requires 793 679 information from multiple variables. 680 % To Peter: I think these are the main points you were going for. 794 681 795 682 \section{Cancellation} … … 804 691 raise, this exception is not used in matching only to pass information about 805 692 the cause of the cancellation. 806 Finaly, since a cancellation only unwinds and forwards, there is no default handler. 693 (This also means matching cannot fail so there is no default handler.) 807 694 808 695 After @cancel_stack@ is called the exception is copied into the EHM's memory … … 815 702 After the main stack is unwound there is a program-level abort. 816 703 817 The reasons for this semantics in a sequential program is that there is no more code to execute.818 Th is semantics also applies to concurrent programs, too, even if threads are running.819 That is, if any threads starts a cancellation, it implies all threads terminate. 820 Keeping the same behaviour in sequential and concurrent programs is simple.704 There are two reasons for these semantics. 705 The 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. 821 708 Also, even in concurrent programs there may not currently be any other stacks 822 709 and even if other stacks do exist, main has no way to know where they are. … … 863 750 caller's context and passes it to the internal report. 864 751 865 A coroutine onlyknows of two other coroutines, its starter and its last resumer.752 A coroutine knows of two other coroutines, its starter and its last resumer. 866 753 The starter has a much more distant connection, while the last resumer just 867 754 (in terms of coroutine state) called resume on this coroutine, so the message … … 871 758 cascade an error across any number of coroutines, cleaning up each in turn, 872 759 until the error is handled or a thread stack is reached. 873 874 \PAB{Part of this I do not understand. A cancellation cannot be caught. But you875 talk about handling a cancellation in the last sentence. Which is correct?}
Note: See TracChangeset
for help on using the changeset viewer.