source: doc/working/exception/impl/test-main.c@ c529a24

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

Updates to exception handling and translation.

  • Property mode set to 100644
File size: 9.2 KB
Line 
1#include "exception.h"
2
3// Use: gcc -fexceptions -Wall -Werror -g exception.c test-main.c
4
5#include <stdio.h>
6#include <stdbool.h>
7
8// Helps with manual translation. It may or may not get folded into the
9// header, that depends on how it interacts with concurancy.
10void __try_resume_node_new(struct __try_resume_node * node,
11 _Bool (*handler)(exception except)) {
12 node->next = shared_stack.top_resume;
13 shared_stack.top_resume = node;
14 node->try_to_handle = handler;
15}
16
17// Local Print On Exit:
18struct raii_base_type {
19 const char * area;
20};
21
22void raii_dtor(struct raii_base_type * this) {
23 printf("Exiting: %s\n", this->area);
24}
25
26#define raii_t __attribute__((cleanup(raii_dtor))) struct raii_base_type
27
28// ===========================================================================
29// Runtime code (post-translation).
30void terminate(int except_value) {
31 raii_t a = {"terminate function"};
32 __throw_terminate(except_value);
33 printf("terminate returned\n");
34}
35
36void resume(int except_value) {
37 raii_t a = {"resume function"};
38 __throw_resume(except_value);
39 printf("resume returned\n");
40}
41
42// Termination Test: Two handlers: no catch, catch
43void bar() {
44 raii_t a = {"bar function"};
45 {
46 void bar_try1() {
47 terminate(4);
48 }
49 void bar_catch1(int index, exception except) {
50 switch(except) {
51 case 1:
52 printf("bar caught exception 3.\n");
53 break;
54 default:
55 printf("INVALID INDEX in bar: %d (%d)\n", index, except);
56 }
57 }
58 int bar_match1(exception except) {
59 if (3 == except) {
60 return 1;
61 } else {
62 return 0;
63 }
64 }
65 __try_terminate(bar_try1, bar_catch1, bar_match1);
66 }
67}
68
69void foo() {
70 raii_t a = {"foo function"};
71 {
72 void foo_try1() {
73 bar();
74 }
75 void foo_catch1(int index, exception except) {
76 switch(index) {
77 case 1:
78 printf("foo caught exception 4.\n");
79 break;
80 case 2:
81 printf("foo caught exception 2.\n");
82 break;
83 default:
84 printf("INVALID INDEX in foo: %d (%d)\n", index, except);
85 }
86 }
87 int foo_match1(exception except) {
88 if (4 == except) {
89 return 1;
90 } else if (2 == except) {
91 return 2;
92 } else {
93 return 0;
94 }
95 }
96 __try_terminate(foo_try1, foo_catch1, foo_match1);
97 }
98}
99
100// Resumption Two Handler Test: no catch, catch.
101void beta() {
102 raii_t a = {"beta function"};
103 {
104 bool beta_handle1(exception except) {
105 if (3 == except) {
106 printf("beta caught exception 3\n");
107 return true;
108 } else {
109 return false;
110 }
111 }
112 struct __try_resume_node node
113 __attribute__((cleanup(__try_resume_cleanup)));
114 __try_resume_node_new(&node, beta_handle1);
115 {
116 resume(4);
117 }
118 }
119}
120void alpha() {
121 raii_t a = {"alpha function"};
122 {
123 bool alpha_handle1(exception except) {
124 if (2 == except) {
125 printf("alpha caught exception 2\n");
126 return true;
127 } else if (4 == except) {
128 printf("alpha caught exception 4\n");
129 return true;
130 } else {
131 return false;
132 }
133 }
134 struct __try_resume_node node
135 __attribute__((cleanup(__try_resume_cleanup)));
136 __try_resume_node_new(&node, alpha_handle1);
137 {
138 beta();
139 }
140 }
141}
142
143// Finally Test:
144void farewell() {
145 {
146 void farewell_finally1() {
147 printf("See you next time\n");
148 }
149 struct __cleanup_hook __hidden_hook
150 __attribute__((cleanup(farewell_finally1)));
151 {
152 printf("walk out of farewell\n");
153 }
154 }
155}
156
157// Resume-to-Terminate Test:
158void fallback() {
159 {
160 void fallback_try1() {
161 resume(1);
162 }
163 void fallback_catch1(int index, exception except) {
164 switch (index) {
165 case 1:
166 printf("fallback caught termination 1\n");
167 break;
168 default:
169 printf("INVALID INDEX in fallback: %d (%d)\n", index, except);
170 }
171 }
172 int fallback_match1(exception except) {
173 if (1 == except) {
174 return 1;
175 } else {
176 return 0;
177 }
178 }
179 __try_terminate(fallback_try1, fallback_catch1, fallback_match1);
180 }
181}
182
183// Terminate Throw New Exception:
184void terminate_swap() {
185 raii_t a = {"terminate_swap"};
186 {
187 void fn_try1() {
188 terminate(2);
189 }
190 void fn_catch1(int index, exception except) {
191 switch (index) {
192 case 1:
193 terminate(1);
194 break;
195 default:
196 printf("INVALID INDEX in terminate_swap: %d (%d)\n",
197 index, except);
198 }
199 }
200 int fn_match1(exception except) {
201 if (2 == except) {
202 return 1;
203 } else {
204 return 0;
205 }
206 }
207 __try_terminate(fn_try1, fn_catch1, fn_match1);
208 }
209}
210
211void terminate_swapped() {
212 raii_t a = {"terminate_swapped"};
213 {
214 void fn_try1() {
215 terminate_swap();
216 }
217 void fn_catch1(int index, exception except) {
218 switch (index) {
219 case 1:
220 printf("terminate_swapped caught exception 1\n");
221 break;
222 default:
223 printf("INVALID INDEX in terminate_swapped: %d (%d)\n",
224 index, except);
225 }
226 }
227 int fn_match1(exception except) {
228 if (1 == except) {
229 return 1;
230 } else {
231 return 0;
232 }
233 }
234 __try_terminate(fn_try1, fn_catch1, fn_match1);
235 }
236}
237
238// Resume Throw New Exception:
239void resume_swap() {
240 raii_t a = {"terminate_swap"};
241 {
242 bool fn_handle1(exception except) {
243 if (2 == except) {
244 resume(1);
245 return true;
246 } else {
247 return false;
248 }
249 }
250 struct __try_resume_node node
251 __attribute__((cleanup(__try_resume_cleanup)));
252 __try_resume_node_new(&node, fn_handle1);
253 {
254 resume(2);
255 }
256 }
257}
258
259void resume_swapped() {
260 {
261 bool fn_handle1(exception except) {
262 if (1 == except) {
263 printf("resume_swapped caught exception 1\n");
264 return true;
265 } else {
266 return false;
267 }
268 }
269 struct __try_resume_node node
270 __attribute__((cleanup(__try_resume_cleanup)));
271 __try_resume_node_new(&node, fn_handle1);
272 {
273 resume_swap();
274 }
275 }
276}
277
278// Terminate Rethrow:
279// I don't have an implementation for this.
280void reterminate() {
281 {
282 void fn_try1() {
283 void fn_try2() {
284 terminate(1);
285 }
286 void fn_catch2(int index, exception except) {
287 switch (index) {
288 case 1:
289 printf("reterminate 2 caught and "
290 "will rethrow exception 1\n");
291 __rethrow_terminate();
292 break;
293 default:
294 printf("INVALID INDEX in reterminate 2: %d (%d)\n",
295 index, except);
296 }
297 }
298 int fn_match2(exception except) {
299 if (1 == except) {
300 return 1;
301 } else {
302 return 0;
303 }
304 }
305 __try_terminate(fn_try2, fn_catch2, fn_match2);
306 }
307 void fn_catch1(int index, exception except) {
308 switch (index) {
309 case 1:
310 printf("reterminate 1 caught exception 1\n");
311 break;
312 default:
313 printf("INVALID INDEX in reterminate 1: %d (%d)\n",
314 index, except);
315 }
316 }
317 int fn_match1(exception except) {
318 if (1 == except) {
319 return 1;
320 } else {
321 return 0;
322 }
323 }
324 __try_terminate(fn_try1, fn_catch1, fn_match1);
325 }
326}
327
328// Resume Rethrow:
329void reresume() {
330 {
331 bool reresume_handle1(exception except) {
332 if (1 == except) {
333 printf("reresume 1 caught exception 1\n");
334 return true;
335 } else {
336 return false;
337 }
338 }
339 struct __try_resume_node node
340 __attribute__((cleanup(__try_resume_cleanup)));
341 __try_resume_node_new(&node, reresume_handle1);
342 {
343 bool reresume_handle2(exception except) {
344 if (1 == except) {
345 printf("reresume 2 caught and rethrows exception 1\n");
346 return false;
347 } else {
348 return false;
349 }
350 }
351 struct __try_resume_node node
352 __attribute__((cleanup(__try_resume_cleanup)));
353 __try_resume_node_new(&node, reresume_handle2);
354 {
355 resume(1);
356 }
357 }
358 }
359}
360
361// Terminate-Resume interaction:
362void fum() {
363 // terminate block, call resume
364 {
365 void fum_try1() {
366 resume(3);
367 }
368 void fum_catch1(int index, exception except) {
369 switch (index) {
370 case 1:
371 printf("fum caught exception 3\n");
372 break;
373 default:
374 printf("INVALID INDEX in fum: %d (%d)\n", index, except);
375 }
376 }
377 int fum_match1(exception except) {
378 if (3 == except) {
379 return 1;
380 } else {
381 return 0;
382 }
383 }
384 __try_terminate(fum_try1, fum_catch1, fum_match1);
385 }
386}
387
388void foe() {
389 // resume block, call terminate
390 {
391 bool foe_handle1(exception except) {
392 if (3 == except) {
393 printf("foe caught exception 3\n");
394 return true;
395 } else {
396 return false;
397 }
398 }
399 struct __try_resume_node node
400 __attribute__((cleanup(__try_resume_cleanup)));
401 __try_resume_node_new(&node, foe_handle1);
402 {
403 terminate(3);
404 }
405 }
406}
407
408void fy() {
409 // terminate block calls fum, call foe
410 {
411 void fy_try1() {
412 foe();
413 }
414 void fy_catch1(int index, exception except) {
415 switch (index) {
416 case 1:
417 printf("fy caught exception 3\n");
418 fum();
419 break;
420 default:
421 printf("INVALID INDEX in fy: %d (%d)\n", index, except);
422 }
423 }
424 int fy_match1(exception except) {
425 if (3 == except) {
426 return 1;
427 } else {
428 return 0;
429 }
430 }
431 __try_terminate(fy_try1, fy_catch1, fy_match1);
432 }
433}
434
435void fee() {
436 // resume block, call fy
437 {
438 bool fee_handle1(exception except) {
439 if (3 == except) {
440 printf("fee caught exception 3\n");
441 return true;
442 } else {
443 return false;
444 }
445 }
446 struct __try_resume_node node
447 __attribute__((cleanup(__try_resume_cleanup)));
448 __try_resume_node_new(&node, fee_handle1);
449 {
450 fy();
451 }
452 }
453}
454
455
456// main: choose which tests to run
457int main(int argc, char * argv[]) {
458 raii_t a = {"main function"};
459
460 foo(); printf("\n");
461 alpha(); printf("\n");
462 farewell(); printf("\n");
463 fallback(); printf("\n");
464 terminate_swapped(); printf("\n");
465 resume_swapped(); printf("\n");
466 reterminate(); printf("\n");
467 reresume(); printf("\n");
468 fee(); printf("\n");
469 // Uncaught termination test.
470 terminate(7);
471}
Note: See TracBrowser for help on using the repository browser.