source: doc/working/exception/impl/resume-main.c @ 4a58895

aaron-thesisarm-ehcleanup-dtorsdeferred_resndemanglerjacob/cs343-translationjenkins-sandboxnew-astnew-ast-unique-exprnew-envno_listpersistent-indexerresolv-newwith_gc
Last change on this file since 4a58895 was 4a58895, checked in by Andrew Beach <ajbeach@…>, 4 years ago

Added a proof of consept resumption exception handler. Has comparable speed to the existing termination handler under O2.

  • Property mode set to 100644
File size: 3.0 KB
Line 
1#include <stdio.h>
2#include <stdbool.h>
3
4// Proof of concept for resumption exception handling.
5// Names, checks promises and so on all would have to be improved.
6
7struct resume_group;
8
9// Stackwise information (global for single stack)
10struct code_stack_data {
11        struct resume_group * top_resume;
12        struct resume_group * current_resume;
13} stack = {NULL, NULL};
14
15// private exception header begin ============================================
16
17struct resume_group {
18        struct resume_group * next;
19        bool (*try_to_handle)(int);
20};
21
22void __resume_group_dtor(struct resume_group * this) {
23        stack.top_resume = this->next;
24}
25
26void __cfa_eh__throw_resume(int except) {
27        struct resume_group * original_head = stack.current_resume;
28        struct resume_group * current =
29                (original_head) ? original_head->next : stack.top_resume;
30
31        for ( ; current ; current = current->next) {
32                stack.current_resume = current;
33                if (current->try_to_handle(except)) {
34                        stack.current_resume = original_head;
35                        return;
36                }
37        }
38
39        printf("Unhandled exception %d\n", except);
40}
41
42// private exception header end ==============================================
43
44// Set up of unwind checker type.
45struct type_raii_t {
46        char * msg;
47};
48
49void dtor( struct type_raii_t * this ) {
50        printf("%s\n", this->msg);
51}
52
53#define raii_t __attribute__((cleanup(dtor))) struct type_raii_t
54
55void bar() {
56        raii_t a = { "Bar dtor" };
57
58        __cfa_eh__throw_resume( 3 );
59}
60
61void foo() {
62        raii_t a = { "Foo dtor" };
63
64        {
65                bool foo_catch_resume(int exception_id) {
66                        if (exception_id == 3) {
67                                printf("Exception caught\n");
68                                return true;
69                        }
70                        return false;
71                }
72                struct resume_group __attribute__((cleanup(__resume_group_dtor)))
73                        foo_try_resume = {stack.top_resume, foo_catch_resume};
74                stack.top_resume = &foo_try_resume;
75                {
76                        raii_t b = { "Foo try dtor" };
77
78                        bar();
79
80                        printf("Called bar successfully\n");
81                }
82        }
83        printf( "Foo exited normally\n" );
84}
85
86// Not in main.cfa
87void foe() {
88        raii_t a = { "Foe dtor" };
89
90        printf("Foe throws\n");
91        __cfa_eh__throw_resume( 4 );
92
93        printf("Foe exits normally\n");
94}
95
96void fy() {
97        raii_t a = { "Fy dtor" };
98
99        {
100                bool fy_catch_resume(int exception_id) {
101                        if (4 == exception_id) {
102                                printf("Rethrow in fy\n");
103                                __cfa_eh__throw_resume(exception_id);
104                                return true;
105                        }
106                        return false;
107                }
108                struct resume_group __attribute__((cleanup(__resume_group_dtor)))
109                        fy_try_resume = {stack.top_resume, fy_catch_resume};
110                stack.top_resume = &fy_try_resume;
111                {
112                        raii_t b = { "Fy try dtor" };
113                        foe();
114                }
115        }
116
117        printf("Fy exits normally\n");
118}
119
120void fee() {
121        raii_t a = { "Fee dtor" };
122
123        {
124                bool fee_catch_resume(int exception_id) {
125                        if (4 == exception_id) {
126                                printf("fee caught exception\n");
127                                return true;
128                        }
129                        return false;
130                }
131                struct resume_group __attribute__((cleanup(__resume_group_dtor)))
132                        fee_try_resume = {stack.top_resume, fee_catch_resume};
133                stack.top_resume = &fee_try_resume;
134                {
135                        raii_t b = { "Fee try dtor" };
136                        fy();
137                }
138        }
139
140        printf("Fee exits normally\n");
141}
142// End not in main.cfa
143
144int main() {
145        raii_t a = { "Main dtor" };
146
147        foo();
148
149        fee();
150
151        printf("End of program reached\n");
152}
Note: See TracBrowser for help on using the repository browser.