source: doc/working/exception/translate.c @ 78372fd

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 78372fd was 6a48cc9, checked in by Andrew Beach <ajbeach@…>, 7 years ago

More tests for the exception library.

  • Property mode set to 100644
File size: 4.7 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 __throw_resume(exception except);
20
21void __try_terminate(void (*try_block)(),
22        void (*catch_block)(int index, exception except),
23        int (*match_block)(exception except));
24
25struct __try_resume_node {
26        struct __try_resume_node * next;
27        bool (*try_to_handle)(exception except);
28};
29
30struct __cleanup_hook {};
31
32// An instance of the following must be paired with every stack.
33struct stack_exception_data {
34        __try_resume_node * top_resume_data;
35        // Other pointers may be required for re-resume.
36
37        exception current_exception;
38        int handler_index;
39};
40
41
42// Translations:
43
44// Throws:
45"Cforall"
46
47throw exception_instance;
48
49resume exception_instance;
50
51"C"
52
53__throw_terminate(exception_instance);
54
55__throw_resume(exception_instance);
56
57
58// Termination Handlers:
59"Cforall"
60
61void try_terminate() {
62        try {
63                insideTry();
64        }
65        catch (SomeException) {
66                fiddleThing();
67        }
68        catch (OtherException err ; err.priority > 3) {
69                twiddleWidget();
70        }
71}
72
73"C"
74
75void try_terminate() {
76        {
77                void try1() {
78                        insideTry();
79                }
80                // index is not nessasary, but should be much faster than going over
81                // all the checks in if we can find a way to pass it in.
82                void catch1(exception except, int index) {
83                        switch (index) {
84                        case 1:
85                                // if it is referenced in the handler, cast except.
86                                {
87                                        fiddleThing();
88                                }
89                                return;
90                        case 2:
91                                {
92                                        twiddleWidget();
93                                }
94                                return;
95                        default:
96                                // Error, should never be reached.
97                        }
98                }
99                int match1(exception except) {
100                        OtherException inner_except;
101                        if (dynamic_cast__SomeException(except)) {
102                                return 1;
103                        }
104                        else if ( (inner_except = dynamic_cast__OtherException(except)) &&
105                                        inner_except.priority > 3) {
106                                return 2;
107                        }
108                        else return 0;
109                }
110                __try_terminate(try1, catch1, match1);
111        }
112}
113
114
115// Resumption Handlers:
116"Cforall"
117
118void try_resume() {
119        try {
120                insideTry();
121        }
122        catch resume (SomeException) {
123                fiddleThing();
124        }
125        catch resume (OtherException err ; err.priority > 3) {
126                twiddleWidget();
127        }
128}
129
130"C"
131
132void try_resume() {
133        {
134                bool catch1(exception except) {
135                        OtherException inner_except;
136                        if (dynamic_cast__SomeException(except)) {
137                                fiddleThing();
138                                return true;
139                        } else if (dynamic_cast__OtherException(except) &&
140                                        inner_except.priority > 3) {
141                                twiddleWidget();
142                                return true;
143                        } else {
144                                return false;
145                        }
146                }
147                struct __try_resume_node data =
148                        {.next = stack.except.top_resume, .try_to_handle = catch1};
149                stack.except.top_resume = &data;
150
151                struct __cleanup_hook generated_name
152                        __attribute__((cleanup(__try_resume_cleanup)));
153
154                {
155                        insideTry();
156                }
157        }
158}
159
160
161// Finally Clause:
162"Cforall"
163
164void try_finally() {
165        try {
166                insideTry();
167        }
168        finally {
169                twiddleWidget();
170        }
171}
172
173"C"
174
175void try_finally() {
176        {
177                void finally1() {
178                        twiddleWidget();
179                }
180
181                struct __cleanup_hook generated_name
182                        __attribute__((cleanup(finally1)));
183
184                {
185                        insideTry();
186                }
187        }
188}
189
190
191// Combining the Above:
192"Cforall"
193
194void try_all() {
195        try {
196                insideTry();
197        }
198        catch (SomeException) {
199                fiddleThing();
200        }
201        catch resume (OtherException) {
202                twiddleWidget();
203        }
204        finally {
205                twiddleWidget();
206        }
207}
208
209"C"
210
211void try_all() {
212        {
213                void try1 () {
214                        insideTry();
215                }
216                void catch1(exception except, int index) {
217                        switch (index) {
218                        case 1:
219                                fiddleThing();
220                                break;
221                        default:
222                                // Error if reached.
223                        }
224                }
225                int match1(exception except) {
226                        if (dynamic_cast__SomeException(except)) {
227                                return 1;
228                        }
229                        return 0;
230                }
231                bool catch2() {
232                        if (dynamic_cast__OtherException(except)) {
233                                twiddleWidget();
234                                return true;
235                        }
236                        return false;
237                }
238                void finally1() {
239                        // Finally, because of timing, also works for resume.
240                        // However this might not actually be better in any way.
241                        __try_resume_cleanup();
242
243                        twiddleWidget();
244                }
245
246                struct __try_resume_node generated_name =
247                        {.next = stack.except.top_resume, .try_to_handle = catch2};
248                stack.except.top_resume = &data;
249                struct __cleanup_hook generated_name
250                        __attribute__((cleanup(finally1)));
251
252                __try_terminate(try1, catch1, match1);
253        }
254}
Note: See TracBrowser for help on using the repository browser.