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

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 a724ac1 was 465ed18, checked in by Andrew Beach <ajbeach@…>, 9 years ago

Update to the exception handling mechanism plan.

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