# Changes in /[716b62c:056cbdb]

Ignore:
Files:
7 edited

Unmodified
Removed
• ## doc/theses/andrew_beach_MMath/features.tex

 r716b62c \paragraph{Hierarchy} A common way to organize exceptions is in a hierarchical structure. This pattern comes from object-orientated languages where the This pattern comes from object-oriented languages where the exception hierarchy is a natural extension of the object hierarchy. A common feature in many programming languages is a tool to pair code (behaviour) with data. In \CFA this is done with the virtual system, In \CFA, this is done with the virtual system, which allow type information to be abstracted away, recovered and allow operations to be performed on the abstract objects. For example, consider an error reading a configuration file. This is most likely a problem with the configuration file @config_error@, but the function could have been passed the wrong file name @arg_error@. This is most likely a problem with the configuration file (@config_error@), but the function could have been passed the wrong file name (@arg_error@). In this case the function could raise one exception and then, if it is unhandled, raise the other. For instance, a resumption used to send messages to the logger may not need to be handled at all. Putting the following default handler at the global scope can make handling the exception optional by default. at the global scope can make handling that exception optional by default. \begin{cfa} void defaultResumptionHandler(log_message &) { After a coroutine stack is unwound, control returns to the @resume@ function that most recently resumed it. @resume@ reports a @CoroutineCancelled@ exception, which contains a references to the cancelled @CoroutineCancelled@ exception, which contains a reference to the cancelled coroutine and the exception used to cancel it. The @resume@ function also takes the \defaultResumptionHandler{} from the
• ## doc/theses/andrew_beach_MMath/implement.tex

 r716b62c of a function's state with @setjmp@ and restoring that snapshot with @longjmp@. This approach bypasses the need to know stack details by simply reseting to a snapshot of an arbitrary but existing function frame on the resetting to a snapshot of an arbitrary but existing function frame on the stack. It is up to the programmer to ensure the snapshot is valid when it is reset and that all required cleanup from the unwound stacks is performed. This approach is fragile and requires extra work in the surrounding code. Because it does not automate or check any of this cleanup, it can be easy to make mistakes and always must be handled manually. With respect to the extra work in the surrounding code, library that provides tools for stack walking, handler execution, and unwinding. What follows is an overview of all the relevant features of libunwind needed for this work, and how \CFA uses them to implement exception handling. libunwind needed for this work. Following that is the description of the \CFA code that uses libunwind to implement termination. \subsection{libunwind Usage}
• ## doc/theses/andrew_beach_MMath/intro.tex

 r716b62c it returns control to that function. \begin{center} \input{termination} \medskip %\input{termination} % %\medskip \input{termhandle.pstex_t} % I hate these diagrams, but I can't access xfig to fix them and they are % better than the alternative. \end{center} \todo*{Can I make the new diagrams fit the old style?} Resumption exception handling searches the stack for a handler and then calls that preformed the raise, usually starting after the raise. \begin{center} \input{resumption} \medskip %\input{resumption} % %\medskip \input{resumhandle.pstex_t} % The other one. \end{center} message as a payload\cite{Ada12}. The modern flag-ship for termination exceptions is \Cpp, The modern flagship for termination exceptions -- if one exists -- is \Cpp, which added them in its first major wave of non-object-orientated features in 1990.\cite{CppHistory} included in the \Cpp standard. % https://en.wikipedia.org/wiki/Exception_handling Since then, resumptions have been ignored in main-stream programming languages. Since then, resumptions have been ignored in mainstream programming languages. However, resumption is being revisited in the context of decades of other developments in programming languages. %\subsection More recently exceptions, seem to be vanishing from newer programming More recently, exceptions seem to be vanishing from newer programming languages, replaced by panic". In Rust, a panic is just a program level abort that may be implemented by unwinding the stack like in termination exception handling.\cite{RustPanicMacro}\cite{RustPanicModule} Go's panic through is very similar to a termination, except it only supports Go's panic though is very similar to a termination, except it only supports a catch-all by calling \code{Go}{recover()}, simplifying the interface at the cost of flexibility.\cite{Go:2021} through multiple functions before it is addressed. Here is an example of the pattern in Bash, where commands can only  return" numbers and most output is done through streams of text. \begin{lstlisting}[language=bash,escapechar={}] # Immediately after running a command: case \$? in 0) # Success ;; 1) # Error Code 1 ;; 2|3) # Error Code 2 or Error Code 3 ;; # Add more cases as needed. asac \end{lstlisting} \item\emph{Special Return with Global Store}: Similar to the error codes pattern but the function itself only returns This approach avoids the multiple results issue encountered with straight error codes but otherwise has the same disadvantages and more. error codes as only a single error value has to be returned, but otherwise has the same disadvantages and more. Every function that reads or writes to the global store must agree on all possible errors and managing it becomes more complex with concurrency. This example shows some of what has to be done to robustly handle a C standard library function that reports errors this way. \begin{lstlisting}[language=C] // Now a library function can set the error. int handle = open(path_name, flags); if (-1 == handle) { switch (errno) { case ENAMETOOLONG: // path_name is a bad argument. break; case ENFILE: // A system resource has been exausted. break; // And many more... } } \end{lstlisting} % cite open man page? \item\emph{Return Union}: This pattern is very popular in any functional or semi-functional language with primitive support for tagged unions (or algebraic data types). % We need listing Rust/rust to format code snippets from it. % Rust's \code{rust}{Result} Return unions can also be expressed as monads (evaluation in a context) and often are in languages with special syntax for monadic evaluation, such as Haskell's \code{haskell}{do} blocks. The main advantage is that an arbitrary object can be used to represent an error, so it can include a lot more information than a simple error code. execution, and if there aren't primitive tagged unions proper, usage can be hard to enforce. % We need listing Rust/rust to format code snippets from it. % Rust's \code{rust}{Result} This is a simple example of examining the result of a failing function in Haskell, using its \code{haskell}{Either} type. Examining \code{haskell}{error} further would likely involve more matching, but the type of \code{haskell}{error} is user defined so there are no general cases. \begin{lstlisting}[language=haskell] case failingFunction argA argB of Right value -> -- Use the successful computed value. Left error -> -- Handle the produced error. \end{lstlisting} Return unions as monads will result in the same code, but can hide most of the work to propagate errors in simple cases. The code to actually handle the errors, or to interact with other monads (a common case in these languages) still has to be written by hand. If \code{haskell}{failingFunction} is implemented with two helpers that use the same error type, then it can be implemented with a \code{haskell}{do} block. \begin{lstlisting}[language=haskell,literate={}] failingFunction x y = do z <- helperOne x helperTwo y z \end{lstlisting} \item\emph{Handler Functions}: function calls, but cheaper (constant time) to call, they are more suited to more frequent (less exceptional) situations. Although, in \Cpp and other languages that do not have checked exceptions, they can actually be enforced by the type system be more reliable. This is a more local example in \Cpp, using a function to provide a default value for a mapping. \begin{lstlisting}[language=C++] ValueT Map::key_or_default(KeyT key, ValueT(*make_default)(KeyT)) { ValueT * value = find_value(key); if (nullptr != value) { return *value; } else { return make_default(key); } } \end{lstlisting} \end{itemize} Because of their cost, exceptions are rarely used for hot paths of execution. Hence, there is an element of self-fulfilling prophecy as implementation techniques have been focused on making them cheap to set-up, techniques have been focused on making them cheap to set up, happily making them expensive to use in exchange. This difference is less important in higher-level scripting languages,
• ## doc/theses/andrew_beach_MMath/performance.tex

 r716b62c resumption exceptions. Even the older programming languages with resumption seem to be notable only for having resumption. On the other hand, the functional equivalents to resumption are too new. There does not seem to be any standard implementations in well-known languages; so far, they seem confined to extensions and research languages. % There was some maybe interesting comparison to an OCaml extension % but I'm not sure how to get that working if it is interesting. Instead, resumption is compared to its simulation in other programming languages: fixup functions that are explicitly passed into a function. \CFA, \Cpp and Java. % To be exact, the Match All and Match None cases. The most likely explination is that, The most likely explanation is that the generally faster languages have made common cases fast" at the expense of the rarer cases. Since exceptions are considered rare, they are made expensive to help speed up common actions, such as entering and leaving try statements. Python on the other hand, while generally slower than the other languages, uses exceptions more and has not scarified their performance. Python, on the other hand, while generally slower than the other languages, uses exceptions more and has not sacrificed their performance. In addition, languages with high-level representations have a much easier time scanning the stack as there is less to decode.
• ## doc/theses/andrew_beach_MMath/uw-ethesis-frontpgs.tex

 r716b62c \begin{center}\textbf{Acknowledgements}\end{center} I would like to thank all the people who made this thesis possible. (I'm waiting until who is involved is finalized.) As is tradition and his due, I would like to begin by thanking my supervisor Peter Buhr. From accepting me in a first place, to helping me run performance tests, I would not be here without him. Also if there was an artist" field here he would be listed there as well, he helped me a lot with the diagrams. I would like to thank the readers Gregor Richards and Yizhou Zhang for their feedback and approval. The presentation of the thesis has definitely been improved with their feedback. I also thank the entire Cforall Team who built the rest of the \CFA compiler. From the existing features I used in my work, to the internal tooling that makes further development easier and the optimizations that make running tests pass by quickly. This includes: Aaron Moss, Rob Schluntz, Thierry Delisle, Michael Brooks, Mubeen Zulfieqar \& Fangren Yu. And thank-you Henry Xue, the co-op student who converted my macro implementation of exception declarations into the compiler features presented in this thesis. Finally I thank my family, who are still relieved I learned how to read. \cleardoublepage
• ## doc/theses/andrew_beach_MMath/uw-ethesis.bib

 r716b62c author={The Rust Team}, key={Rust Panic Macro}, howpublished={\href{https://doc.rust-lang.org/std/panic/index.html}{https://\-doc.rust-lang.org/\-std/\-panic/\-index.html}}, howpublished={\href{https://doc.rust-lang.org/std/macro.panic.html}{https://\-doc.rust-lang.org/\-std/\-macro.panic.html}}, addendum={Accessed 2021-08-31}, }
• ## libcfa/src/fstream.hfa

 r716b62c void release( ofstream & ); void lock( ofstream & ); void unlock( ofstream & ); struct osacquire { ofstream & os;
Note: See TracChangeset for help on using the changeset viewer.