3 static Token longjmp_stack_t
, unwind_t
, longjmp_base
;
4 static Token longjmp_ctx_top
;
5 static Token longjmp_ctx
;
9 longjmp_stack_t
= new_symbol ("longjmp_StaCk");
10 unwind_t
= new_symbol ("AuToDt_t");
11 longjmp_ctx_top
= new_symbol ("longjmp_StaCkTop");
12 longjmp_ctx
= new_symbol ("longjmp_CoNtExT");
13 longjmp_base
= new_symbol ("longjmp_iNiTObjFaKe");
16 static char _lwcbuiltin_estack
[] =
17 "static inline void *__lwcbuiltin_get_estack ()\n"
19 " return longjmp_StaCkTop;\n"
21 "static inline void __lwcbuiltin_set_estack (void *v)\n"
23 " longjmp_StaCkTop = v;\n"
26 static char _Unwind_gcc
[] =
27 " /*"COLS
"*** gcc unwind internals ***"COLE
"*/\n"
28 " static _Unwind_Reason_Code"
31 " return _URC_NO_REASON ;"
34 " void __lwc_unwind (void*) __attribute__ ((noreturn, noinline));"
35 " void __lwc_unwind ( void *i )"
37 " struct _Unwind_Exception * exc = malloc ( sizeof * exc ) ;"
38 " exc -> exception_class = 0 ;"
39 " exc -> exception_cleanup = 0 ;"
40 " longjmp_StaCkTop -> X = i ;"
41 " longjmp_StaCkTop -> i = exc ;"
42 #ifndef __USING_SJLJ_EXCEPTIONS__
43 " _Unwind_ForcedUnwind ( exc , ThRoW_sToP, 0 ) ;"
45 " _Unwind_SjLj_ForcedUnwind ( exc , ThRoW_sToP , 0 ) ;"
47 " \n/* did you forget -fexceptions ? */ * ( int * ) 0 = 0 ;"
50 " void __lwc_landingpad ( int * i ) "
53 " longjmp ( * longjmp_StaCkTop -> x , 1 ) ;"
56 #define IFEH if (EHUnwind) {
57 #define IFNEH if (!EHUnwind) {
61 void decl_except_data ()
63 outprintf (INCLUDE
, include_sys_header_s ("setjmp.h"), -1);
64 IFEH
// include <unwind.h>
65 outprintf (INCLUDE
, include_sys_header_s ("unwind.h"), -1);
68 IFNEH
// declare manual unwind accounting
70 RESERVED_struct
, unwind_t
, '{',
71 RESERVED_const
, RESERVED_struct
, unwind_t
, '*', RESERVED_X
, ';',
72 RESERVED_void
, '*', RESERVED_x
, ';',
73 RESERVED_void
, '*', '(', '*' , RESERVED_y
, ')', '(', RESERVED_void
, '*', ')', ';',
78 RESERVED_struct
, longjmp_stack_t
, '{',
79 RESERVED_jmp_buf
, '*', RESERVED_x
, ';',
80 RESERVED_struct
, longjmp_stack_t
, '*', RESERVED_y
, ';',
81 RESERVED_void
, '*', RESERVED_X
, ';', -1);
82 IFEH
// cleanup eh mess
83 outprintf (STRUCTS
, RESERVED_void
, '*', RESERVED_i
, ';', -1);
84 ELSE
// accounting member
85 outprintf (STRUCTS
, RESERVED_const
, RESERVED_struct
, unwind_t
, '*', RESERVED_i
, ';', -1);
87 outprintf (STRUCTS
, '}', ';', -1);
90 outprintf (GVARS
, Reentrant
? RESERVED___thread
: BLANKT
,
91 RESERVED_struct
, longjmp_stack_t
, longjmp_base
, ',', '*',
92 RESERVED___restrict
, longjmp_ctx_top
, '=', '&', longjmp_base
, ';', -1);
94 outprintf (GVARS
, RESERVED_extern
,
95 Reentrant
? RESERVED___thread
: BLANKT
,
96 RESERVED_struct
, longjmp_stack_t
, '*', longjmp_ctx_top
, ';', -1);
98 #define EHTOP longjmp_ctx_top, POINTSAT
99 #define ADTOP EHTOP, RESERVED_i
101 outprintf (GVARS
, RESERVED_extern
, RESERVED_void
, RESERVED___lwc_unwind
,
102 '(', RESERVED_void
, '*', ')', -1);
103 #ifdef HAVE_GNUC_ATTR_NORETURN
104 outprintf (GVARS
, RESERVED___attribute__
, '(', '(',RESERVED_noreturn
,')', ')', -1);
106 output_itoken (GVARS
, ';');
107 IFEH
// landing pad prototype
108 outprintf (GVARS
, RESERVED_extern
, RESERVED_void
, RESERVED___lwc_landingpad
,
109 '(', RESERVED_int
, '*', ')', ';', -1);
113 outprintf (GVARS
, RESERVED_void
, RESERVED___lwc_unwind
, '(', RESERVED_void
, '*',')',
114 RESERVED___attribute__
, '(', '(', RESERVED_noreturn
, ')', ')', ';',
115 RESERVED_void
, RESERVED___lwc_unwind
, '(', RESERVED_void
, '*',
116 RESERVED_X
, ')', '{',
117 EHTOP
, RESERVED_X
, '=', RESERVED_X
, ';',
118 RESERVED_while
, '(', ADTOP
, ')', '{',
119 ADTOP
, POINTSAT
, RESERVED_y
, '(', ADTOP
, POINTSAT
, RESERVED_x
, ')', ';',
120 ADTOP
, '=', ADTOP
, POINTSAT
, RESERVED_X
, ';', '}',
121 RESERVED_longjmp
, '(', '*',
122 EHTOP
, RESERVED_x
, ',', RESERVED_1
, ')', ';', '}', -1);
123 else output_itoken (GVARS
, new_symbol (_Unwind_gcc
));
125 outprintf (GVARS
, new_symbol (_lwcbuiltin_estack
), -1);
129 /* member 'r' is normally a recID, but if a symbol, it's
130 the name of the custom dtor function. Useful for arrdtor */
131 #define DTOR_OF(x) ISSYMBOL(x) ? x : dtor_name (x)
135 void push_unwind (OUTSTREAM o
, recID r
, Token arg
)
137 if (EHUnwind
) return;
139 #define NOWARNONTYPE '(', RESERVED___typeof__, '(', u, '.', RESERVED_y, ')', ')'
140 Token u
= name_unwind_var (arg
);
141 outprintf (o
, UWMARK
, RESERVED_const
, RESERVED_struct
, unwind_t
, u
, '=', '{',
142 '.', RESERVED_X
, '=', ADTOP
, ',',
143 '.', RESERVED_x
, '=', '&', arg
, ',',
144 '.', RESERVED_y
, '=', NOWARNONTYPE
, DTOR_OF (r
), ',',
145 '}', ';', ADTOP
, '=', '&', u
, ';', UWMARK
, -1);
148 void pop_unwind (OUTSTREAM o
)
150 if (EHUnwind
) return;
151 outprintf (o
, UWMARK
, ADTOP
, '=', ADTOP
, POINTSAT
, RESERVED_X
, ';', UWMARK
, -1);
154 void remove_unwind_stuff (Token
*str
)
157 for (i
= 0; str
[i
] != -1;)
158 if (str
[i
] == UWMARK
) {
159 for (j
= i
+ 1; str
[j
] != UWMARK
; j
++);
160 for (k
= i
, j
+= 1;;)
161 if ((str
[k
++] = str
[j
++]) == -1)
166 void leave_escope (OUTSTREAM o
)
169 outprintf (o
, internal_identifier3 (), '=', RESERVED_1
, ';', -1);
171 outprintf (o
, longjmp_ctx_top
, '=', longjmp_ctx_top
, POINTSAT
, RESERVED_y
, ';', -1);
174 NormPtr
throw_statement (OUTSTREAM o
, NormPtr p
)
178 outprintf (o
, RESERVED___lwc_unwind
, '(', -1);
181 output_itoken (o
, RESERVED_0
);
184 p
= parse_expression_retconv (p
, &E
, typeID_voidP
, NORMAL_EXPR
);
185 if (!E
.ok
) return p
+ 1;
186 outprintf (o
, ISTR (E
.newExpr
), -1);
190 parse_error (p
, "excepted ';' after throw expression");
193 outprintf (o
, ')', ';', -1);
198 NormPtr
try_statement (OUTSTREAM o
, NormPtr p
)
200 Token x
= RESERVED_x
;
201 Token y
= RESERVED_y
;
202 Token X
= RESERVED_X
;
203 Token i
= RESERVED_i
;
204 Token ii
= internal_identifier2 ();
205 Token i3
= internal_identifier3 ();
209 outprintf (o
, '{', RESERVED_struct
, longjmp_stack_t
, longjmp_ctx
, ';', -1);
211 if (have_retcode
= CODE
[p
] == '(') {
213 p
= skip_parenthesis (p2
= p
+ 1) - 1;
216 local_declaration (o
, p2
);
218 retcode
= recent_obj ();
221 outprintf (o
, RESERVED_jmp_buf
, ii
, ';', longjmp_ctx
, '.', x
, '=', '&', ii
, ';',
222 longjmp_ctx
, '.', y
, '=', longjmp_ctx_top
, ';', longjmp_ctx_top
,
223 '=', '&', longjmp_ctx
, ';', longjmp_ctx
, '.', X
, '=', RESERVED_0
, ';', -1);
225 IFNEH
// init manual accounting
226 outprintf (o
, longjmp_ctx
, '.', RESERVED_i
, '=', RESERVED_0
, ';', -1);
229 RESERVED_if
, '(', '!', '(', RESERVED_setjmp
, '(', ii
, ')', ')',
232 IFEH
// cleanup with landing pad
233 outprintf (o
, RESERVED_int
, i3
, cleanup_func (RESERVED___lwc_landingpad
),
234 '=', RESERVED_0
, ';', -1);
237 SAVE_VAR (may_throw
, may_throw
);
238 int pos
= get_stream_pos (o
);
239 p
= statement (o
, p
);
240 nowipeout_unwind (o
, pos
);
241 RESTOR_VAR (may_throw
);
243 IFEH
// mark landing pad normal termination
244 outprintf (o
, i3
, '=', RESERVED_1
, ';', -1);
246 outprintf (o
, longjmp_ctx_top
, '=', longjmp_ctx
, '.', y
, ';', '}', -1);
248 outprintf (o
, RESERVED_else
, '{', -1);
250 outprintf (o
, retcode
, '=', longjmp_ctx
, '.', RESERVED_X
, ';', -1);
251 IFEH
// cleanup eh mess
252 outprintf (o
, RESERVED_free
, '(', longjmp_ctx
, '.', i
, ')', ';', -1);
254 outprintf (o
, longjmp_ctx_top
, '=', longjmp_ctx
, '.', y
, ';', -1);
255 if (CODE
[p
] == RESERVED_else
)
256 p
= statement (o
, p
+ 1);
257 output_itoken (o
, '}');
259 output_itoken (o
, '}');
261 if (have_retcode
) close_local_scope ();
266 NormPtr
on_throw_statement (OUTSTREAM o
, NormPtr p
)
268 Token x
= RESERVED_x
;
269 Token y
= RESERVED_y
;
270 Token X
= RESERVED_X
;
271 Token ii
= internal_identifier2 ();
272 Token i3
= internal_identifier3 ();
276 // the exception handler is removed when the scope closes
277 add_auto_destruction (LEAVE_ESCOPE
, -1, 0);
279 outprintf (o
, RESERVED_struct
, longjmp_stack_t
, longjmp_ctx
, ';', -1);
281 if (have_retcode
= CODE
[p
] == '(') {
283 p
= skip_parenthesis (p2
= p
+ 1) - 1;
286 local_declaration (o
, p2
);
288 retcode
= recent_obj ();
291 outprintf (o
, RESERVED_jmp_buf
, ii
, ';', longjmp_ctx
, '.', x
, '=', '&', ii
, ';',
292 longjmp_ctx
, '.', y
, '=', longjmp_ctx_top
, ';', longjmp_ctx_top
,
293 '=', '&', longjmp_ctx
, ';', longjmp_ctx
, '.', X
, '=', RESERVED_0
, ';', -1);
295 IFNEH
// init manual accounting
296 outprintf (o
, longjmp_ctx
, '.', RESERVED_i
, '=', RESERVED_0
, ';', -1);
297 ELSE
// install landing pad
298 outprintf (o
, RESERVED_int
, i3
, cleanup_func (RESERVED___lwc_landingpad
),
299 '=', RESERVED_0
, ';', -1);
303 RESERVED_if
, '(', '(', RESERVED_setjmp
, '(', ii
, ')', ')', ')', '{', -1);
304 IFNEH
// init manual accounting
305 outprintf (o
, longjmp_ctx
, '.', RESERVED_i
, '=', RESERVED_0
, ';', -1);
308 outprintf (o
, retcode
, '=', longjmp_ctx
, '.', RESERVED_X
, ';', -1);
310 p
= statement (o
, p
);
311 output_itoken (o
, '}');
312 if (have_retcode
) close_local_scope ();