source: doc/working/exception/translate.c@ 81da70a5

ADT arm-eh ast-experimental enum forall-pointer-decay jacob/cs343-translation new-ast new-ast-unique-expr pthread-emulation qualifiedEnum
Last change on this file since 81da70a5 was f1a10a7, checked in by Andrew Beach <ajbeach@…>, 8 years ago

Updated translate.c, new translation reduces the chance of name mixup.

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