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

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