source: doc/working/exception/translate.c @ 465ed18

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 465ed18 was 465ed18, checked in by Andrew Beach <ajbeach@…>, 7 years ago

Update to the exception handling mechanism plan.

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