source: doc/working/exception/translate.c@ ec35498

ADT aaron-thesis arm-eh ast-experimental cleanup-dtors deferred_resn demangler enum forall-pointer-decay jacob/cs343-translation jenkins-sandbox new-ast new-ast-unique-expr new-env no_list persistent-indexer pthread-emulation qualifiedEnum resolv-new with_gc
Last change on this file since ec35498 was c529a24, checked in by Andrew Beach <ajbeach@…>, 8 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.