source: doc/working/exception/translate.c @ 2c37f34

ADTaaron-thesisarm-ehast-experimentalcleanup-dtorsdeferred_resndemanglerenumforall-pointer-decayjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerpthread-emulationqualifiedEnumresolv-newwith_gc
Last change on this file since 2c37f34 was c529a24, checked in by Andrew Beach <ajbeach@…>, 7 years ago

Updates to exception handling and translation.

  • Property mode set to 100644
File size: 5.6 KB
Line 
1/* Translation rules for exception handling code, from Cforall to C.
2 *
3 * Note that these are not final. Names, syntax and the exact translation
4 * will be updated. The first section is the shared definitions, not generated
5 * by the local translations but used by the translated code.
6 *
7 * Most of these exist only after translation (in C code). The first (the
8 * exception type) has to exist in Cforall code so that it can be used
9 * directly in Cforall. The two __throw_* functions might have wrappers in
10 * Cforall, but the underlying functions should probably be C. struct
11 * stack_exception_data has to exist inside of the coroutine data structures
12 * and so should be compiled as they are.
13 */
14
15// Currently it is a typedef for int, but later it will be a new type.
16typedef int exception;
17
18void __throw_terminate(exception except) __attribute__((noreturn));
19void __rethrow_terminate() __attribute__((noreturn));
20void __throw_resume(exception except);
21
22void __try_terminate(void (*try_block)(),
23        void (*catch_block)(int index, exception except),
24        int (*match_block)(exception except));
25
26struct __try_resume_node {
27        struct __try_resume_node * next;
28        bool (*try_to_handle)(exception except);
29};
30
31void __try_resume_cleanup(struct __try_resume_node * node);
32
33struct __cleanup_hook {};
34
35// An instance of the following must be paired with every stack.
36struct stack_exception_data {
37        __try_resume_node * top_resume_data;
38        // Other pointers may be required for re-resume.
39
40        exception current_exception;
41        int handler_index;
42};
43
44
45// Translations:
46
47// Throws:
48"Cforall"
49
50throw exception_instance;
51
52resume exception_instance;
53
54"C"
55
56__throw_terminate(exception_instance);
57
58__throw_resume(exception_instance);
59
60
61
62// Rethrows (inside matching handlers):
63"Cforall"
64
65throw;
66
67resume;
68
69"C"
70
71__rethrow_terminate();
72
73return false;
74
75
76// Termination Handlers:
77"Cforall"
78
79void try_terminate() {
80        try {
81                insideTry();
82        }
83        catch (SomeException) {
84                fiddleThing();
85        }
86        catch (OtherException err ; err.priority > 3) {
87                twiddleWidget();
88        }
89}
90
91"C"
92
93void try_terminate() {
94        {
95                void try1() {
96                        insideTry();
97                }
98                // index is not nessasary, but should be much faster than going over
99                // all the checks in if we can find a way to pass it in.
100                void catch1(exception except, int index) {
101                        switch (index) {
102                        case 1:
103                                // if it is referenced in the handler, cast except.
104                                {
105                                        fiddleThing();
106                                }
107                                return;
108                        case 2:
109                                {
110                                        twiddleWidget();
111                                }
112                                return;
113                        default:
114                                // Error, should never be reached.
115                        }
116                }
117                int match1(exception except) {
118                        OtherException inner_except;
119                        if (dynamic_cast__SomeException(except)) {
120                                return 1;
121                        }
122                        else if ( (inner_except = dynamic_cast__OtherException(except)) &&
123                                        inner_except.priority > 3) {
124                                return 2;
125                        }
126                        else return 0;
127                }
128                __try_terminate(try1, catch1, match1);
129        }
130}
131
132
133// Resumption Handlers:
134"Cforall"
135
136void try_resume() {
137        try {
138                insideTry();
139        }
140        catch resume (SomeException) {
141                fiddleThing();
142        }
143        catch resume (OtherException err ; err.priority > 3) {
144                twiddleWidget();
145        }
146}
147
148"C"
149
150void try_resume() {
151        {
152                bool handle1(exception except) {
153                        OtherException inner_except;
154                        if (dynamic_cast__SomeException(except)) {
155                                fiddleThing();
156                                return true;
157                        } else if (dynamic_cast__OtherException(except) &&
158                                        inner_except.priority > 3) {
159                                twiddleWidget();
160                                return true;
161                        } else {
162                                return false;
163                        }
164                }
165                struct __try_resume_node data =
166                        {.next = stack.except.top_resume, .try_to_handle = handle1};
167                stack.except.top_resume = &data;
168
169                struct __cleanup_hook generated_name
170                        __attribute__((cleanup(__try_resume_cleanup)));
171
172                {
173                        insideTry();
174                }
175        }
176}
177
178
179// Finally Clause:
180"Cforall"
181
182void try_finally() {
183        try {
184                insideTry();
185        }
186        finally {
187                twiddleWidget();
188        }
189}
190
191"C"
192
193void try_finally() {
194        {
195                void finally1() {
196                        twiddleWidget();
197                }
198
199                struct __cleanup_hook generated_name
200                        __attribute__((cleanup(finally1)));
201
202                {
203                        insideTry();
204                }
205        }
206}
207
208
209// Resume + Finally:
210"Cforall"
211
212void try_resume_finally() {
213        try {
214                insideTry();
215        }
216        catch resume (SomeException) {
217                fiddleThing();
218        }
219        finally {
220                twiddleWidget();
221        }
222}
223
224"C"
225
226void try_resume_finally() {
227        {
228                void finally1() {
229                        twiddleWidget();
230                }
231                bool handle1(exception except) {
232                        if (dynamic_cast__SomeException(except)) {
233                                fiddleThing();
234                                return true;
235                        } else {
236                                return false;
237                        }
238                }
239                struct __cleanup_hook generated_name
240                        __attribute__((cleanup(finally1)));
241
242                struct __try_resume_node data =
243                        {.next = stack.except.top_resume, .try_to_handle = handle1};
244                stack.except.top_resume = &data;
245
246                struct __cleanup_hook generated_name
247                        __attribute__((cleanup(__try_resume_cleanup)));
248        }
249}
250
251
252// Terminate + Resume + Finally:
253"Cforall"
254
255void try_all() {
256        try {
257                insideTry();
258        }
259        catch (SomeException) {
260                fiddleThing();
261        }
262        catch resume (OtherException) {
263                twiddleWidget();
264        }
265        finally {
266                twiddleWidget();
267        }
268}
269
270"C"
271
272void try_all() {
273        {
274                bool handle1() {
275                        if (dynamic_cast__OtherException(except)) {
276                                twiddleWidget();
277                                return true;
278                        }
279                        return false;
280                }
281                void try1 () {
282                        struct __try_resume_node generated_name =
283                                {.next = stack.except.top_resume, .try_to_handle = handle1}
284                                __attribute__((cleanup(__try_resume_cleanup)));
285                        stack.except.top_resume = &data;
286
287                        insideTry();
288                }
289                void catch1(exception except, int index) {
290                        switch (index) {
291                        case 1:
292                                fiddleThing();
293                                break;
294                        default:
295                                // Error if reached.
296                        }
297                }
298                int match1(exception except) {
299                        if (dynamic_cast__SomeException(except)) {
300                                return 1;
301                        }
302                        return 0;
303                }
304                void finally1() {
305
306                        twiddleWidget();
307                }
308                struct __cleanup_hook generated_name
309                        __attribute__((cleanup(finally1)));
310
311                __try_terminate(try1, catch1, match1);
312        }
313}
Note: See TracBrowser for help on using the repository browser.