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

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 a4683611 was 4a58895, checked in by Andrew Beach <ajbeach@…>, 8 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.