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

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

Added rethrow to translation.
Implemend and tested termination rethrowing.

  • Property mode set to 100644
File size: 4.8 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 __throw_resume(exception except);
20
21void __try_terminate(void (*try_block)(),
22 void (*catch_block)(int index, exception except),
23 int (*match_block)(exception except));
24
25struct __try_resume_node {
26 struct __try_resume_node * next;
27 bool (*try_to_handle)(exception except);
28};
29
30struct __cleanup_hook {};
31
32// An instance of the following must be paired with every stack.
33struct stack_exception_data {
34 __try_resume_node * top_resume_data;
35 // Other pointers may be required for re-resume.
36
37 exception current_exception;
38 int handler_index;
39};
40
41
42// Translations:
43
44// Throws:
45"Cforall"
46
47throw exception_instance;
48
49resume exception_instance;
50
51"C"
52
53__throw_terminate(exception_instance);
54
55__throw_resume(exception_instance);
56
57
58
59// Rethrows (inside matching handlers):
60"Cforall"
61
62throw;
63
64resume;
65
66"C"
67
68__rethrow_terminate();
69
70return false;
71
72
73// Termination Handlers:
74"Cforall"
75
76void try_terminate() {
77 try {
78 insideTry();
79 }
80 catch (SomeException) {
81 fiddleThing();
82 }
83 catch (OtherException err ; err.priority > 3) {
84 twiddleWidget();
85 }
86}
87
88"C"
89
90void try_terminate() {
91 {
92 void try1() {
93 insideTry();
94 }
95 // index is not nessasary, but should be much faster than going over
96 // all the checks in if we can find a way to pass it in.
97 void catch1(exception except, int index) {
98 switch (index) {
99 case 1:
100 // if it is referenced in the handler, cast except.
101 {
102 fiddleThing();
103 }
104 return;
105 case 2:
106 {
107 twiddleWidget();
108 }
109 return;
110 default:
111 // Error, should never be reached.
112 }
113 }
114 int match1(exception except) {
115 OtherException inner_except;
116 if (dynamic_cast__SomeException(except)) {
117 return 1;
118 }
119 else if ( (inner_except = dynamic_cast__OtherException(except)) &&
120 inner_except.priority > 3) {
121 return 2;
122 }
123 else return 0;
124 }
125 __try_terminate(try1, catch1, match1);
126 }
127}
128
129
130// Resumption Handlers:
131"Cforall"
132
133void try_resume() {
134 try {
135 insideTry();
136 }
137 catch resume (SomeException) {
138 fiddleThing();
139 }
140 catch resume (OtherException err ; err.priority > 3) {
141 twiddleWidget();
142 }
143}
144
145"C"
146
147void try_resume() {
148 {
149 bool catch1(exception except) {
150 OtherException inner_except;
151 if (dynamic_cast__SomeException(except)) {
152 fiddleThing();
153 return true;
154 } else if (dynamic_cast__OtherException(except) &&
155 inner_except.priority > 3) {
156 twiddleWidget();
157 return true;
158 } else {
159 return false;
160 }
161 }
162 struct __try_resume_node data =
163 {.next = stack.except.top_resume, .try_to_handle = catch1};
164 stack.except.top_resume = &data;
165
166 struct __cleanup_hook generated_name
167 __attribute__((cleanup(__try_resume_cleanup)));
168
169 {
170 insideTry();
171 }
172 }
173}
174
175
176// Finally Clause:
177"Cforall"
178
179void try_finally() {
180 try {
181 insideTry();
182 }
183 finally {
184 twiddleWidget();
185 }
186}
187
188"C"
189
190void try_finally() {
191 {
192 void finally1() {
193 twiddleWidget();
194 }
195
196 struct __cleanup_hook generated_name
197 __attribute__((cleanup(finally1)));
198
199 {
200 insideTry();
201 }
202 }
203}
204
205
206// Combining the Above:
207"Cforall"
208
209void try_all() {
210 try {
211 insideTry();
212 }
213 catch (SomeException) {
214 fiddleThing();
215 }
216 catch resume (OtherException) {
217 twiddleWidget();
218 }
219 finally {
220 twiddleWidget();
221 }
222}
223
224"C"
225
226void try_all() {
227 {
228 void try1 () {
229 insideTry();
230 }
231 void catch1(exception except, int index) {
232 switch (index) {
233 case 1:
234 fiddleThing();
235 break;
236 default:
237 // Error if reached.
238 }
239 }
240 int match1(exception except) {
241 if (dynamic_cast__SomeException(except)) {
242 return 1;
243 }
244 return 0;
245 }
246 bool catch2() {
247 if (dynamic_cast__OtherException(except)) {
248 twiddleWidget();
249 return true;
250 }
251 return false;
252 }
253 void finally1() {
254 // Finally, because of timing, also works for resume.
255 // However this might not actually be better in any way.
256 __try_resume_cleanup();
257
258 twiddleWidget();
259 }
260
261 struct __try_resume_node generated_name =
262 {.next = stack.except.top_resume, .try_to_handle = catch2};
263 stack.except.top_resume = &data;
264 struct __cleanup_hook generated_name
265 __attribute__((cleanup(finally1)));
266
267 __try_terminate(try1, catch1, match1);
268 }
269}
Note: See TracBrowser for help on using the repository browser.