source: doc/working/exception/translate.c@ 7b6ca2e

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

More tests for the exception library.

  • Property mode set to 100644
File size: 4.7 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// Termination Handlers:
59"Cforall"
60
61void try_terminate() {
62 try {
63 insideTry();
64 }
65 catch (SomeException) {
66 fiddleThing();
67 }
68 catch (OtherException err ; err.priority > 3) {
69 twiddleWidget();
70 }
71}
72
73"C"
74
75void try_terminate() {
76 {
77 void try1() {
78 insideTry();
79 }
80 // index is not nessasary, but should be much faster than going over
81 // all the checks in if we can find a way to pass it in.
82 void catch1(exception except, int index) {
83 switch (index) {
84 case 1:
85 // if it is referenced in the handler, cast except.
86 {
87 fiddleThing();
88 }
89 return;
90 case 2:
91 {
92 twiddleWidget();
93 }
94 return;
95 default:
96 // Error, should never be reached.
97 }
98 }
99 int match1(exception except) {
100 OtherException inner_except;
101 if (dynamic_cast__SomeException(except)) {
102 return 1;
103 }
104 else if ( (inner_except = dynamic_cast__OtherException(except)) &&
105 inner_except.priority > 3) {
106 return 2;
107 }
108 else return 0;
109 }
110 __try_terminate(try1, catch1, match1);
111 }
112}
113
114
115// Resumption Handlers:
116"Cforall"
117
118void try_resume() {
119 try {
120 insideTry();
121 }
122 catch resume (SomeException) {
123 fiddleThing();
124 }
125 catch resume (OtherException err ; err.priority > 3) {
126 twiddleWidget();
127 }
128}
129
130"C"
131
132void try_resume() {
133 {
134 bool catch1(exception except) {
135 OtherException inner_except;
136 if (dynamic_cast__SomeException(except)) {
137 fiddleThing();
138 return true;
139 } else if (dynamic_cast__OtherException(except) &&
140 inner_except.priority > 3) {
141 twiddleWidget();
142 return true;
143 } else {
144 return false;
145 }
146 }
147 struct __try_resume_node data =
148 {.next = stack.except.top_resume, .try_to_handle = catch1};
149 stack.except.top_resume = &data;
150
151 struct __cleanup_hook generated_name
152 __attribute__((cleanup(__try_resume_cleanup)));
153
154 {
155 insideTry();
156 }
157 }
158}
159
160
161// Finally Clause:
162"Cforall"
163
164void try_finally() {
165 try {
166 insideTry();
167 }
168 finally {
169 twiddleWidget();
170 }
171}
172
173"C"
174
175void try_finally() {
176 {
177 void finally1() {
178 twiddleWidget();
179 }
180
181 struct __cleanup_hook generated_name
182 __attribute__((cleanup(finally1)));
183
184 {
185 insideTry();
186 }
187 }
188}
189
190
191// Combining the Above:
192"Cforall"
193
194void try_all() {
195 try {
196 insideTry();
197 }
198 catch (SomeException) {
199 fiddleThing();
200 }
201 catch resume (OtherException) {
202 twiddleWidget();
203 }
204 finally {
205 twiddleWidget();
206 }
207}
208
209"C"
210
211void try_all() {
212 {
213 void try1 () {
214 insideTry();
215 }
216 void catch1(exception except, int index) {
217 switch (index) {
218 case 1:
219 fiddleThing();
220 break;
221 default:
222 // Error if reached.
223 }
224 }
225 int match1(exception except) {
226 if (dynamic_cast__SomeException(except)) {
227 return 1;
228 }
229 return 0;
230 }
231 bool catch2() {
232 if (dynamic_cast__OtherException(except)) {
233 twiddleWidget();
234 return true;
235 }
236 return false;
237 }
238 void finally1() {
239 // Finally, because of timing, also works for resume.
240 // However this might not actually be better in any way.
241 __try_resume_cleanup();
242
243 twiddleWidget();
244 }
245
246 struct __try_resume_node generated_name =
247 {.next = stack.except.top_resume, .try_to_handle = catch2};
248 stack.except.top_resume = &data;
249 struct __cleanup_hook generated_name
250 __attribute__((cleanup(finally1)));
251
252 __try_terminate(try1, catch1, match1);
253 }
254}
Note: See TracBrowser for help on using the repository browser.