1 | \chapter{Future Work} |
---|
2 | \label{c:future} |
---|
3 | |
---|
4 | \section{Language Improvements} |
---|
5 | \CFA is a developing programming language. As such, there are partially or |
---|
6 | unimplemented features of the language (including several broken components) |
---|
7 | that I had to workaround while building an exception handling system largely in |
---|
8 | the \CFA language (some C components). The following are a few of these |
---|
9 | issues, and once implemented/fixed, how they would affect the exception system. |
---|
10 | \begin{itemize} |
---|
11 | \item |
---|
12 | The implementation of termination is not portable because it includes |
---|
13 | hand-crafted assembly statements. These sections must be ported by hand to |
---|
14 | support more hardware architectures, such as the ARM processor. |
---|
15 | \PAB{I think this is a straw-man problem because the hand-coded assembler code |
---|
16 | has to be generated somewhere, and that somewhere is hand-coded.} |
---|
17 | \item |
---|
18 | Due to a type-system problem, the catch clause cannot bind the exception to a |
---|
19 | reference instead of a pointer. Since \CFA has a very general reference |
---|
20 | capability, programmers will want to use it. Once fixed, this capability should |
---|
21 | result in little or no change in the exception system but simplify usage. |
---|
22 | \item |
---|
23 | Termination handlers cannot use local control-flow transfers, \eg by @break@, |
---|
24 | @return@, \etc. The reason is that current code generation hoists a handler |
---|
25 | into a nested function for convenience (versus assemble-code generation at the |
---|
26 | @try@ statement). Hence, when the handler runs, its code is not in the lexical |
---|
27 | scope of the @try@ statement, where the local control-flow transfers are |
---|
28 | meaningful. |
---|
29 | \item |
---|
30 | There is no detection of colliding unwinds. It is possible for clean-up code |
---|
31 | run during an unwind to trigger another unwind that escapes the clean-up code |
---|
32 | itself, \eg, a termination exception caught further down the stack or a |
---|
33 | cancellation. There do exist ways to handle this issue, but currently they are not |
---|
34 | even detected and the first unwind is simply dropped, often leaving |
---|
35 | it in a bad state. \Cpp terminates the program in this case, and Java picks the ... |
---|
36 | \item |
---|
37 | Also the exception system did not have a lot of time to be tried and tested. |
---|
38 | So just letting people use the exception system more will reveal new |
---|
39 | quality of life upgrades that can be made with time. |
---|
40 | \end{itemize} |
---|
41 | |
---|
42 | \section{Complete Virtual System} |
---|
43 | The virtual system should be completed. It was not supposed to be part of this |
---|
44 | project, but was thrust upon it to do exception inheritance; hence, only |
---|
45 | minimal work is done. A draft for a complete virtual system is available but |
---|
46 | it is not finalized. A future \CFA project is to complete that work and then |
---|
47 | update the exception system that uses the current version. |
---|
48 | |
---|
49 | There are several improvements to the virtual system that would improve the |
---|
50 | exception traits. The most important one is an assertion to check one virtual |
---|
51 | type is a child of another. This check precisely captures many of the |
---|
52 | correctness requirements. |
---|
53 | |
---|
54 | The full virtual system might also include other improvement like associated |
---|
55 | types to allow traits to refer to types not listed in their header. This |
---|
56 | feature allows exception traits to not refer to the virtual-table type |
---|
57 | explicitly, removing the need for the current interface macros. |
---|
58 | |
---|
59 | \section{Additional Raises} |
---|
60 | Several other kinds of exception raises were considered beyond termination |
---|
61 | (@throw@), resumption (@throwResume@), and reraise. |
---|
62 | |
---|
63 | The first is a non-local/concurrent raise providing asynchronous exceptions, |
---|
64 | \ie raising an exception on another stack. This semantics acts like signals |
---|
65 | allowing for out-of-band communication among coroutines and threads. This kind |
---|
66 | of raise is often restricted to resumption to allow the target stack to |
---|
67 | continue execution normally after the exception has been handled. That is, |
---|
68 | allowing one coroutine/thread to unwind the stack of another via termination is |
---|
69 | bad software engineering. |
---|
70 | |
---|
71 | Non-local/concurrent raise requires more coordination between the concurrency system |
---|
72 | and the exception system. Many of the interesting design decisions centre |
---|
73 | around masking, \ie controlling which exceptions may be thrown at a stack. It |
---|
74 | would likely require more of the virtual system and would also effect how |
---|
75 | default handlers are set. |
---|
76 | |
---|
77 | Other raises were considered to mimic bidirectional algebraic effects. |
---|
78 | Algebraic effects are used in some functional languages allowing one function |
---|
79 | to have another function on the stack resolve an effect (which is defined with |
---|
80 | a functional-like interface). This semantics can be mimicked with resumptions |
---|
81 | and new raises were discussed to mimic bidirectional algebraic-effects, where |
---|
82 | control can go back and forth between the function-effect caller and handler |
---|
83 | while the effect is underway. |
---|
84 | % resume-top & resume-reply |
---|
85 | These raises would be like the resumption raise except using different search |
---|
86 | patterns to find the handler. |
---|
87 | |
---|
88 | \section{Checked Exceptions} |
---|
89 | Checked exceptions make exceptions part of a function's type by adding an |
---|
90 | exception signature. An exception signature must declare all checked |
---|
91 | exceptions that could propagate from the function (either because they were |
---|
92 | raised inside the function or came from a sub-function). This improves safety |
---|
93 | by making sure every checked exception is either handled or consciously |
---|
94 | passed on. |
---|
95 | |
---|
96 | However checked exceptions were never seriously considered for this project because |
---|
97 | they have significant usability and reuse trade-offs in |
---|
98 | exchange for the increased safety. |
---|
99 | These trade-offs are most problematic when trying to pass exceptions through |
---|
100 | higher-order functions from the functions the user passed into the |
---|
101 | higher-order function. There are no well known solutions to this problem |
---|
102 | that were satisfactory for \CFA (which carries some of C's flexibility |
---|
103 | over safety design) so additional research is needed. |
---|
104 | |
---|
105 | Follow-up work might find a compromise design for checked exceptions in \CFA, possibly using |
---|
106 | polymorphic exception signatures, a form of tunneling\cite{Zhang19}, or |
---|
107 | checked and unchecked raises. |
---|
108 | |
---|
109 | \section{Zero-Cost Try} |
---|
110 | \CFA does not have zero-cost try-statements because the compiler generates C |
---|
111 | code rather than assembler code (see \vpageref{p:zero-cost}). When the compiler |
---|
112 | does create its own assembly (or LLVM byte-code), then zero-cost try-statements |
---|
113 | are possible. The downside of zero-cost try-statements is the LSDA complexity, |
---|
114 | its size (program bloat), and the high cost of raising an exception. |
---|
115 | |
---|
116 | Alternatively, some research could be done into the simpler alternative method |
---|
117 | with a non-zero-cost try-statement but much lower cost exception raise. For |
---|
118 | example, programs are starting to use exception in the normal control path, so |
---|
119 | more exceptions are thrown. In these cases, the cost balance switches towards |
---|
120 | low-cost raise. Unfortunately, while exceptions remain exceptional, the |
---|
121 | libunwind model will probably remain the most effective option. |
---|
122 | |
---|
123 | Zero-cost resumptions is still an open problem. First, because libunwind does |
---|
124 | not support a successful-exiting stack-search without doing an unwind. |
---|
125 | Workarounds are possible but awkward. Ideally an extension to libunwind could |
---|
126 | be made, but that would either require separate maintenance or gain enough |
---|
127 | support to have it folded into the standard. |
---|
128 | |
---|
129 | Also new techniques to skip previously searched parts of the stack need to be |
---|
130 | developed to handle the recursive resume problem and support advanced algebraic |
---|
131 | effects. |
---|
132 | |
---|
133 | \section{Signal Exceptions} |
---|
134 | Goodenough~\cite{Goodenough75} suggests three types of exceptions: escape, |
---|
135 | notify and signal. Escape are termination exceptions, notify are resumption |
---|
136 | exceptions, leaving signal unimplemented. |
---|
137 | |
---|
138 | A signal exception allows either behaviour, \ie after an exception is handled, |
---|
139 | the handler has the option of returning to the raise or after the @try@ |
---|
140 | statement. Currently, \CFA fixes the semantics of the handler return |
---|
141 | syntactically by the @catch@ or @catchResume@ clause. |
---|
142 | |
---|
143 | Signal exception should be reexamined and possibly be supported in \CFA. A very |
---|
144 | direct translation is to have a new raise and catch pair, and a new statement |
---|
145 | (or statements) would indicate if the handler returns to the raise or continues |
---|
146 | where it is; but there may be other options. |
---|
147 | |
---|
148 | For instance, resumption could be extended to cover this use by allowing local |
---|
149 | control flow out of it. This approach would require an unwind as part of the |
---|
150 | transition as there are stack frames that have to be removed back to the resumption handler. This approach |
---|
151 | means no special statement is required in the handler to continue after it. |
---|
152 | Currently, \CFA allows a termination exception to be thrown from within any resumption handler so |
---|
153 | there is already a way to partially mimic signal exceptions. |
---|
154 | |
---|
155 | % Maybe talk about the escape; and escape CONTROL_STMT; statements or how |
---|
156 | % if we could choose if _Unwind_Resume proceeded to the clean-up stage this |
---|
157 | % would be much easier to implement. |
---|