Changeset 1830a86
- Timestamp:
- Feb 16, 2021, 1:07:56 PM (4 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- d0502a3, f6664bf2
- Parents:
- c6640a3
- Location:
- doc/theses/andrew_beach_MMath
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
doc/theses/andrew_beach_MMath/features.tex
rc6640a3 r1830a86 113 113 virtual table type; which usually has a mangled name. 114 114 % Also \CFA's trait system handles functions better than constants and doing 115 % it this way 115 % it this way reduce the amount of boiler plate we need. 116 116 117 117 % I did have a note about how it is the programmer's responsibility to make … … 119 119 % similar system I know of (except Agda's I guess) so I took it out. 120 120 121 \section{Raise} 122 \CFA provides two kinds of exception raise: termination 123 \see{\VRef{s:Termination}} and resumption \see{\VRef{s:Resumption}}, which are 124 specified with the following traits. 121 There are two more traits for exceptions @is_termination_exception@ and 122 @is_resumption_exception@. They are defined as follows: 123 125 124 \begin{cfa} 126 125 trait is_termination_exception( … … 128 127 void defaultTerminationHandler(exceptT &); 129 128 }; 130 \end{cfa} 131 The function is required to allow a termination raise, but is only called if a 132 termination raise does not find an appropriate handler. 133 134 Allowing a resumption raise is similar. 135 \begin{cfa} 129 136 130 trait is_resumption_exception( 137 131 exceptT &, virtualT & | is_exception(exceptT, virtualT)) { … … 139 133 }; 140 134 \end{cfa} 141 The function is required to allow a resumption raise, but is only called if a 142 resumption raise does not find an appropriate handler. 143 144 Finally there are three convenience macros for referring to the these traits: 135 136 In other words they make sure that a given type and virtual type is an 137 exception and defines one of the two default handlers. These default handlers 138 are used in the main exception handling operations \see{Exception Handling} 139 and their use will be detailed there. 140 141 However all three of these traits can be trickly to use directly. 142 There is a bit of repetition required but 143 the largest issue is that the virtual table type is mangled and not in a user 144 facing way. So there are three macros that can be used to wrap these traits 145 when you need to refer to the names: 145 146 @IS_EXCEPTION@, @IS_TERMINATION_EXCEPTION@ and @IS_RESUMPTION_EXCEPTION@. 146 All three traits are hard to use while naming the virtual table as it has an 147 internal mangled name. These macros take the exception name as their first 148 argument and do the mangling. They all take a second argument for polymorphic 149 types which is the parenthesized list of polymorphic arguments. These 150 arguments are passed to both the exception type and the virtual table type as 151 the arguments do have to match. 147 148 All take one or two arguments. The first argument is the name of the 149 exception type. Its unmangled and mangled form are passed to the trait. 150 The second (optional) argument is a parenthesized list of polymorphic 151 arguments. This argument should only with polymorphic exceptions and the 152 list will be passed to both types. 153 In the current set-up the base name and the polymorphic arguments have to 154 match so these macros can be used without losing flexability. 152 155 153 156 For example consider a function that is polymorphic over types that have a … … 158 161 \end{cfa} 159 162 163 \section{Exception Handling} 164 \CFA provides two kinds of exception handling, termination and resumption. 165 These twin operations are the core of the exception handling mechanism and 166 are the reason for the features of exceptions. 167 This section will cover the general patterns shared by the two operations and 168 then go on to cover the details each individual operation. 169 170 Both operations follow the same set of steps to do their operation. They both 171 start with the user preforming a throw on an exception. 172 Then there is the search for a handler, if one is found than the exception 173 is caught and the handler is run. After that control returns to normal 174 execution. 175 176 If the search fails a default handler is run and then control 177 returns to normal execution immediately. That is where the default handlers 178 @defaultTermiationHandler@ and @defaultResumptionHandler@ are used. 179 160 180 \subsection{Termination} 161 181 \label{s:Termination} 162 182 163 Termination raise, called ``throw'', is familiar and used in most programming 164 languages with exception handling. The semantics of termination is: search the 165 stack for a matching handler, unwind the stack frames to the matching handler, 166 execute the handler, and continue execution after the handler. Termination is 167 used when execution \emph{cannot} return to the throw. To continue execution, 168 the program must \emph{recover} in the handler from the failed (unwound) 169 execution at the raise to safely proceed after the handler. 170 171 A termination raise is started with the @throw@ statement: 183 Termination handling is more familiar kind and used in most programming 184 languages with exception handling. 185 It is dynamic, non-local goto. If a throw is successful then the stack will 186 be unwound and control will (usually) continue in a different function on 187 the call stack. They are commonly used when an error has occured and recovery 188 is impossible in the current function. 189 190 % (usually) Control can continue in the current function but then a different 191 % control flow construct should be used. 192 193 A termination throw is started with the @throw@ statement: 172 194 \begin{cfa} 173 195 throw EXPRESSION; … … 180 202 change the throw's behavior (see below). 181 203 182 At runtime, the exception returned by the expression 183 is copied into managed memory (heap) to ensure it remains in 184 scope during unwinding. It is the user's responsibility to ensure the original 185 exception object at the throw is freed when it goes out of scope. Being 186 allocated on the stack is sufficient for this. 187 188 Then the exception system searches the stack starting from the throw and 189 proceeding towards the base of the stack, from callee to caller. At each stack 190 frame, a check is made for termination handlers defined by the @catch@ clauses 191 of a @try@ statement. 204 The throw will copy the provided exception into managed memory. It is the 205 user's responcibility to ensure the original exception is cleaned up if the 206 stack is unwound (allocating it on the stack should be sufficient). 207 208 Then the exception system searches the stack using the copied exception. 209 It starts starts from the throw and proceeds to the base of the stack, 210 from callee to caller. 211 At each stack frame, a check is made for resumption handlers defined by the 212 @catch@ clauses of a @try@ statement. 192 213 \begin{cfa} 193 214 try { 194 215 GUARDED_BLOCK 195 } catch (EXCEPTION_TYPE$\(_1\)$ * NAME$\(_1\)$) { // termination handler 1216 } catch (EXCEPTION_TYPE$\(_1\)$ * NAME$\(_1\)$) { 196 217 HANDLER_BLOCK$\(_1\)$ 197 } catch (EXCEPTION_TYPE$\(_2\)$ * NAME$\(_2\)$) { // termination handler 2218 } catch (EXCEPTION_TYPE$\(_2\)$ * NAME$\(_2\)$) { 198 219 HANDLER_BLOCK$\(_2\)$ 199 220 } 200 221 \end{cfa} 201 The statements in the @GUARDED_BLOCK@ are executed. If those statements, or any 202 functions invoked from those statements, throws an exception, and the exception 222 When viewed on its own a try statement will simply exceute the statements in 223 @GUARDED_BLOCK@ and when those are finished the try statement finishes. 224 225 However, while the guarded statements are being executed, including any 226 functions they invoke, all the handlers following the try block are now 227 or any functions invoked from those 228 statements, throws an exception, and the exception 203 229 is not handled by a try statement further up the stack, the termination 204 230 handlers are searched for a matching exception type from top to bottom. … … 211 237 freed and control continues after the try statement. 212 238 213 The default handler visible at the throw statement is used if no matching 214 termination handler is found after the entire stack is searched. At that point, 215 the default handler is called with a reference to the exception object216 generated at the throw. If the default handler returns, control continues 217 from after the throw statement. This feature allows 218 each exception type to define its own action, such as printing an informative 219 error message, when an exception is not handled in the program. 220 However the default handler for all exception types triggers a cancellation 221 using the exception.239 If no handler is found during the search then the default handler is run. 240 Through \CFA's trait system the best match at the throw sight will be used. 241 This function is run and is passed the copied exception. After the default 242 handler is run control continues after the throw statement. 243 244 There is a global @defaultTerminationHandler@ that cancels the current stack 245 with the copied exception. However it is generic over all exception types so 246 new default handlers can be defined for different exception types and so 247 different exception types can have different default handlers. 222 248 223 249 \subsection{Resumption} 224 250 \label{s:Resumption} 225 251 226 Resumption raise, called ``resume'', is as old as termination 227 raise~\cite{Goodenough75} but is less popular. In many ways, resumption is 228 simpler and easier to understand, as it is simply a dynamic call. 229 The semantics of resumption is: search the stack for a matching handler, 230 execute the handler, and continue execution after the resume. Notice, the stack 231 cannot be unwound because execution returns to the raise point. Resumption is 232 used used when execution \emph{can} return to the resume. To continue 233 execution, the program must \emph{correct} in the handler for the failed 234 execution at the raise so execution can safely continue after the resume. 252 Resumption exception handling is a less common form than termination but is 253 just as old~\cite{Goodenough75} and is in some sense simpler. 254 It is a dynamic, non-local function call. If the throw is successful a 255 closure will be taken from up the stack and executed, after which the throwing 256 function will continue executing. 257 These are most often used when an error occured and if the error is repaired 258 then the function can continue. 235 259 236 260 A resumption raise is started with the @throwResume@ statement: … … 240 264 The semantics of the @throwResume@ statement are like the @throw@, but the 241 265 expression has return a reference a type that satifies the trait 242 @is_resumption_exception@. Like with termination the exception system can243 use these assertions while (throwing/raising/handling)the exception.266 @is_resumption_exception@. The assertions from this trait are available to 267 the exception system while handling the exception. 244 268 245 269 At runtime, no copies are made. As the stack is not unwound the exception and 246 270 any values on the stack will remain in scope while the resumption is handled. 247 271 248 Then the exception system searches the stack starting from the resume and 249 proceeding to the base of the stack, from callee to caller. At each stack 250 frame, a check is made for resumption handlers defined by the @catchResume@ 251 clauses of a @try@ statement. 272 Then the exception system searches the stack using the provided exception. 273 It starts starts from the throw and proceeds to the base of the stack, 274 from callee to caller. 275 At each stack frame, a check is made for resumption handlers defined by the 276 @catchResume@ clauses of a @try@ statement. 252 277 \begin{cfa} 253 278 try { … … 259 284 } 260 285 \end{cfa} 261 The statements in the @GUARDED_BLOCK@ are executed. If those statements, or any 262 functions invoked from those statements, resumes an exception, and the 263 exception is not handled by a try statement further up the stack, the 264 resumption handlers are searched for a matching exception type from top to 265 bottom. (Note, termination and resumption handlers may be intermixed in a @try@ 266 statement but the kind of raise (throw/resume) only matches with the 267 corresponding kind of handler clause.) 268 269 The exception search and matching for resumption is the same as for 270 termination, including exception inheritance. The difference is when control 271 reaches the end of the handler: the resumption handler returns after the resume 272 rather than after the try statement. The resume point assumes the handler has273 corrected the problem so execution can safely continue.286 If the handlers are not involved in a search this will simply execute the 287 @GUARDED_BLOCK@ and then continue to the next statement. 288 Its purpose is to add handlers onto the stack. 289 (Note, termination and resumption handlers may be intermixed in a @try@ 290 statement but the kind of throw must be the same as the handler for it to be 291 considered as a possible match.) 292 293 If a search for a resumption handler reaches a try block it will check each 294 @catchResume@ clause, top-to-bottom. 295 At each handler if the thrown exception is or is a child type of 296 @EXCEPTION_TYPE@$_i$ then the a pointer to the exception is bound to 297 @NAME@$_i$ and then @HANDLER_BLOCK@$_i$ is executed. After the block is 298 finished control will return to the @throwResume@ statement. 274 299 275 300 Like termination, if no resumption handler is found, the default handler 276 visible at the resume statement is called, and the system default action is 277 executed. 278 279 For resumption, the exception system uses stack marking to partition the 280 resumption search. If another resumption exception is raised in a resumption 281 handler, the second exception search does not start at the point of the 282 original raise. (Remember the stack is not unwound and the current handler is 283 at the top of the stack.) The search for the second resumption starts at the 284 current point on the stack because new try statements may have been pushed by 285 the handler or functions called from the handler. If there is no match back to 286 the point of the current handler, the search skips\label{p:searchskip} the 287 stack frames already searched by the first resume and continues after 288 the try statement. The default handler always continues from default 289 handler associated with the point where the exception is created. 301 visible at the throw statement is called. It will use the best match at the 302 call sight according to \CFA's overloading rules. The default handler is 303 passed the exception given to the throw. When the default handler finishes 304 execution continues after the throw statement. 305 306 There is a global @defaultResumptionHandler@ is polymorphic over all 307 termination exceptions and preforms a termination throw on the exception. 308 The @defaultTerminationHandler@ for that throw is matched at the original 309 throw statement (the resumption @throwResume@) and it can be customized by 310 introducing a new or better match as well. 311 312 % \subsubsection? 313 314 A key difference between resumption and termination is that resumption does 315 not unwind the stack. A side effect that is that when a handler is matched 316 and run it's try block (the guarded statements) and every try statement 317 searched before it are still on the stack. This can lead to the recursive 318 resumption problem. 319 320 The recursive resumption problem is any situation where a resumption handler 321 ends up being called while it is running. 322 Consider a trivial case: 323 \begin{cfa} 324 try { 325 throwResume (E &){}; 326 } catchResume(E *) { 327 throwResume (E &){}; 328 } 329 \end{cfa} 330 When this code is executed the guarded @throwResume@ will throw, start a 331 search and match the handler in the @catchResume@ clause. This will be 332 call and placed on the stack on top of the try-block. The second throw then 333 throws and will seach the same try block and put call another instance of the 334 same handler leading to an infinite loop. 335 336 This situation is trivial and easy to avoid, but much more complex cycles 337 can form with multiple handlers and different exception types. 338 339 To prevent all of these cases we mask sections of the stack, or equvilantly 340 the try statements on the stack, so that the resumption seach skips over 341 them and continues with the next unmasked section of the stack. 342 343 A section of the stack is marked when it is searched to see if it contains 344 a handler for an exception and unmarked when that exception has been handled 345 or the search was completed without finding a handler. 290 346 291 347 % This might need a diagram. But it is an important part of the justification … … 306 362 \end{verbatim} 307 363 308 This resumption search pattern reflects the one for termination, and so 309 should come naturally to most programmers. 310 However, it avoids the \emph{recursive resumption} problem. 311 If parts of the stack are searched multiple times, loops 312 can easily form resulting in infinite recursion. 313 314 Consider the trivial case: 315 \begin{cfa} 316 try { 317 throwResume (E &){}; // first 318 } catchResume(E *) { 319 throwResume (E &){}; // second 320 } 321 \end{cfa} 322 If this handler is ever used it will be placed on top of the stack above the 323 try statement. If the stack was not masked than the @throwResume@ in the 324 handler would always be caught by the handler, leading to an infinite loop. 325 Masking avoids this problem and other more complex versions of it involving 326 multiple handlers and exception types. 327 328 Other masking stratagies could be used; such as masking the handlers that 329 have caught an exception. This one was choosen because it creates a symmetry 330 with termination (masked sections of the stack would be unwound with 331 termination) and having only one pattern to learn is easier. 364 The rules can be remembered as thinking about what would be searched in 365 termination. So when a throw happens in a handler; a termination handler 366 skips everything from the original throw to the original catch because that 367 part of the stack has been unwound, a resumption handler skips the same 368 section of stack because it has been masked. 369 A throw in a default handler will preform the same search as the original 370 throw because; for termination nothing has been unwound, for resumption 371 the mask will be the same. 372 373 The symmetry with termination is why this pattern was picked. Other patterns, 374 such as marking just the handlers that caught, also work but lack the 375 symmetry whih means there is more to remember. 332 376 333 377 \section{Conditional Catch} … … 335 379 condition to further control which exceptions they handle: 336 380 \begin{cfa} 337 catch (EXCEPTION_TYPE * NAME ; @CONDITION@)381 catch (EXCEPTION_TYPE * NAME ; CONDITION) 338 382 \end{cfa} 339 383 First, the same semantics is used to match the exception type. Second, if the … … 341 385 reference all names in scope at the beginning of the try block and @NAME@ 342 386 introduced in the handler clause. If the condition is true, then the handler 343 matches. Otherwise, the exception search continues a t the next appropriate kind344 of handler clause in the try block.387 matches. Otherwise, the exception search continues as if the exception type 388 did not match. 345 389 \begin{cfa} 346 390 try { … … 356 400 remaining handlers in the current try statement. 357 401 358 \section{Re raise}359 \colo r{red}{From Andrew: I recomend we talk about why the language doesn't402 \section{Rethrowing} 403 \colour{red}{From Andrew: I recomend we talk about why the language doesn't 360 404 have rethrows/reraises instead.} 361 405 362 \label{s:Re raise}406 \label{s:Rethrowing} 363 407 Within the handler block or functions called from the handler block, it is 364 408 possible to reraise the most recently caught exception with @throw@ or 365 @throwResume@, respective .409 @throwResume@, respectively. 366 410 \begin{cfa} 367 411 try { 368 412 ... 369 413 } catch( ... ) { 370 ... throw; // rethrow414 ... throw; 371 415 } catchResume( ... ) { 372 ... throwResume; // reresume416 ... throwResume; 373 417 } 374 418 \end{cfa} … … 381 425 382 426 \section{Finally Clauses} 383 A @finally@ clause may be placed at the end of a @try@ statement. 427 Finally clauses are used to preform unconditional clean-up when leaving a 428 scope. They are placed at the end of a try statement: 384 429 \begin{cfa} 385 430 try { … … 391 436 \end{cfa} 392 437 The @FINALLY_BLOCK@ is executed when the try statement is removed from the 393 stack, including when the @GUARDED_BLOCK@ or any handler clause finishes or394 during an unwind.438 stack, including when the @GUARDED_BLOCK@ finishes, any termination handler 439 finishes or during an unwind. 395 440 The only time the block is not executed is if the program is exited before 396 th at happens.441 the stack is unwound. 397 442 398 443 Execution of the finally block should always finish, meaning control runs off … … 403 448 @return@ that causes control to leave the finally block. Other ways to leave 404 449 the finally block, such as a long jump or termination are much harder to check, 405 and at best requiring additional run-time overhead, and so are discouraged. 450 and at best requiring additional run-time overhead, and so are mearly 451 discouraged. 452 453 Not all languages with exceptions have finally clauses. Notably \Cpp does 454 without it as descructors serve a similar role. Although destructors and 455 finally clauses can be used in many of the same areas they have their own 456 use cases like top-level functions and lambda functions with closures. 457 Destructors take a bit more work to set up but are much easier to reuse while 458 finally clauses are good for once offs and can include local information. 406 459 407 460 \section{Cancellation} … … 413 466 There is no special statement for starting a cancellation; instead the standard 414 467 library function @cancel_stack@ is called passing an exception. Unlike a 415 raise, this exception is not used in matching only to pass information about468 throw, this exception is not used in matching only to pass information about 416 469 the cause of the cancellation. 417 418 Handling of a cancellation depends on which stack is being cancelled. 470 (This also means matching cannot fail so there is no default handler either.) 471 472 After @cancel_stack@ is called the exception is copied into the exception 473 handling mechanism's memory. Then the entirety of the current stack is 474 unwound. After that it depends one which stack is being cancelled. 419 475 \begin{description} 420 476 \item[Main Stack:] … … 447 503 happen in an implicate join inside a destructor. So there is an error message 448 504 and an abort instead. 505 \todo{Perhaps have a more general disucssion of unwind collisions before 506 this point.} 449 507 450 508 The recommended way to avoid the abort is to handle the intial resumption … … 455 513 \item[Coroutine Stack:] A coroutine stack is created for a @coroutine@ object 456 514 or object that satisfies the @is_coroutine@ trait. A coroutine only knows of 457 two other coroutines, its starter and its last resumer. The last resumer has 458 the tightest coupling to the coroutine it activated. Hence, cancellation of 459 the active coroutine is forwarded to the last resumer after the stack is 460 unwound, as the last resumer has the most precise knowledge about the current 461 execution. When the resumer restarts, it resumes exception 515 two other coroutines, its starter and its last resumer. Of the two the last 516 resumer has the tightest coupling to the coroutine it activated and the most 517 up-to-date information. 518 519 Hence, cancellation of the active coroutine is forwarded to the last resumer 520 after the stack is unwound. When the resumer restarts, it resumes exception 462 521 @CoroutineCancelled@, which is polymorphic over the coroutine type and has a 463 522 pointer to the cancelled coroutine. -
doc/theses/andrew_beach_MMath/uw-ethesis.tex
rc6640a3 r1830a86 108 108 % Removes large sections of the document. 109 109 \usepackage{comment} 110 % Adds todos (Must be included after comment.) 111 \usepackage{todonotes} 112 110 113 111 114 % Hyperlinks make it very easy to navigate an electronic document. … … 213 216 % Optional arguments do not work with pdf string. (Some fix-up required.) 214 217 \pdfstringdefDisableCommands{\def\Cpp{C++}} 218 219 % Colour text, formatted in LaTeX style instead of TeX style. 220 \newcommand*\colour[2]{{\color{#1}#2}} 215 221 \makeatother 216 222
Note: See TracChangeset
for help on using the changeset viewer.