ReactOS 0.4.15-dev-7924-g5949c20
framebased.h
Go to the documentation of this file.
1/*
2 Copyright (c) 2004/2005 KJK::Hyperion
3
4 Permission is hereby granted, free of charge, to any person obtaining a
5 copy of this software and associated documentation files (the "Software"),
6 to deal in the Software without restriction, including without limitation
7 the rights to use, copy, modify, merge, publish, distribute, sublicense,
8 and/or sell copies of the Software, and to permit persons to whom the
9 Software is furnished to do so, subject to the following conditions:
10
11 The above copyright notice and this permission notice shall be included in
12 all copies or substantial portions of the Software.
13
14 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
15 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
16 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
17 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
18 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING
19 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
20 DEALINGS IN THE SOFTWARE.
21*/
22
23#ifndef KJK_PSEH_FRAMEBASED_H_
24#define KJK_PSEH_FRAMEBASED_H_
25
26#if ((__GNUC__ > 4) && (__GNUC_MINOR__ > 1))
27/* warning: this will hide uninitialized variable warnings in the following code */
28# pragma GCC diagnostic ignored "-Wuninitialized"
29#endif
30
32#include <pseh/excpt.h>
33
34#ifndef offsetof
35# include <stddef.h>
36#endif
37
38#if defined(_SEH_NO_NATIVE_NLG)
39# error PSEH setjmp/longjmp fallback is no longer supported
40#endif
41
42#if defined(__GNUC__)
43# define _SEHLongJmp __builtin_longjmp
44# define _SEHSetJmp __builtin_setjmp
45 typedef void * _SEHJmpBuf_t[5];
46#else
47# include <setjmp.h>
48# define _SEHLongJmp longjmp
49# define _SEHSetJmp setjmp
50# define _SEHJmpBuf_t jmp_buf
51#endif
52
53#ifdef __cplusplus
54# define _SEH_INIT_CONST static const
55#else
56# define _SEH_INIT_CONST register const
57#endif
58
59typedef struct __SEHFrame
60{
62 void * volatile SEH_Locals;
63}
65
66typedef struct __SEHTryLevel
67{
70}
72
73static __declspec(noreturn) __inline void __stdcall _SEHCompilerSpecificHandler
74(
75 _SEHPortableTryLevel_t * trylevel
76)
77{
78 _SEHTryLevel_t * mytrylevel;
79 mytrylevel = _SEH_CONTAINING_RECORD(trylevel, _SEHTryLevel_t, ST_Header);
80 _SEHLongJmp(mytrylevel->ST_JmpBuf, 1);
81}
82
83static const int _SEHScopeKind = 1;
86
87/* SHARED LOCALS */
88/* Access the locals for the current frame */
89#define _SEH_ACCESS_LOCALS(LOCALS_) \
90 _SEH_LOCALS_TYPENAME(LOCALS_) * _SEHPLocals; \
91 _SEHPLocals = \
92 _SEH_PVOID_CAST \
93 ( \
94 _SEH_LOCALS_TYPENAME(LOCALS_) *, \
95 _SEH_CONTAINING_RECORD(_SEHPortableFrame, _SEHFrame_t, SEH_Header) \
96 ->SEH_Locals \
97 );
98
99/* Access local variable VAR_ */
100#define _SEH_VAR(VAR_) _SEHPLocals->VAR_
101
102/* FILTER FUNCTIONS */
103/* Declares a filter function's prototype */
104#define _SEH_FILTER(NAME_) \
105 long __stdcall NAME_ \
106 ( \
107 struct _EXCEPTION_POINTERS * _SEHExceptionPointers, \
108 struct __SEHPortableFrame * _SEHPortableFrame \
109 )
110
111/* Declares a static filter */
112#define _SEH_STATIC_FILTER(ACTION_) ((_SEHFilter_t)((ACTION_) + 2))
113
114/* Declares a PSEH filter wrapping a regular filter function */
115#define _SEH_WRAP_FILTER(WRAPPER_, NAME_) \
116 static __inline _SEH_FILTER(WRAPPER_) \
117 { \
118 return (NAME_)(_SEHExceptionPointers); \
119 }
120
121/* FINALLY FUNCTIONS */
122/* Declares a finally function's prototype */
123#define _SEH_FINALLYFUNC(NAME_) \
124 void __stdcall NAME_ \
125 ( \
126 struct __SEHPortableFrame * _SEHPortableFrame \
127 )
128
129/* Declares a PSEH finally function wrapping a regular function */
130#define _SEH_WRAP_FINALLY(WRAPPER_, NAME_) \
131 _SEH_WRAP_FINALLY_ARGS(WRAPPER_, NAME_, ())
132
133#define _SEH_WRAP_FINALLY_ARGS(WRAPPER_, NAME_, ARGS_) \
134 static __inline _SEH_FINALLYFUNC(WRAPPER_) \
135 { \
136 NAME_ ARGS_; \
137 }
138
139#define _SEH_WRAP_FINALLY_LOCALS_ARGS(WRAPPER_, LOCALS_, NAME_, ARGS_) \
140 static __inline _SEH_FINALLYFUNC(WRAPPER_) \
141 { \
142 _SEH_ACCESS_LOCALS(LOCALS_); \
143 NAME_ ARGS_; \
144 }
145
146/* SAFE BLOCKS */
147#ifdef __cplusplus
148# define _SEH_DECLARE_HANDLERS(FILTER_, FINALLY_) \
149 static const _SEHHandlers_t _SEHHandlers = { (FILTER_), (FINALLY_) };
150#else
151# define _SEH_DECLARE_HANDLERS(FILTER_, FINALLY_) \
152 _SEHHandlers_t _SEHHandlers = { (0), (0) }; \
153 _SEHHandlers.SH_Filter = (FILTER_); \
154 _SEHHandlers.SH_Finally = (FINALLY_);
155#endif
156
157#define _SEH_SetExceptionCode(CODE_) (_SEHPortableFrame->SPF_Code = (CODE_))
158#define _SEH_GetExceptionCode() (unsigned long)(_SEHPortableFrame->SPF_Code)
159
160#define _SEH_GetExceptionPointers() \
161 ((struct _EXCEPTION_POINTERS *)_SEHExceptionPointers)
162
163#define _SEH_AbnormalTermination() (_SEHPortableFrame->SPF_Code != 0)
164
165#define _SEH_LEAVE break
166
167#define _SEH_YIELD(STMT_) \
168 for(;;) \
169 { \
170 if(!_SEHScopeKind) \
171 _SEHReturn(); \
172 \
173 STMT_; \
174 }
175
176#ifdef _ARM_
177
178#define _SEH_TRY \
179 for(;;) \
180 { \
181 \
182 { \
183 \
184 for(;;) \
185 { \
186 if(1) \
187 { \
188 for(;;) \
189 { \
190 {
191
192#define _SEH_EXCEPT(FILTER_) \
193 } \
194 \
195 break; \
196 } \
197 \
198 break; \
199 } \
200 else \
201 { \
202 { \
203 break; \
204 } \
205 } \
206 \
207 break; \
208 } \
209 \
210 \
211 if(0) \
212 {
213
214#define _SEH_FINALLY(FINALLY_) \
215 } \
216 \
217 break; \
218 } \
219 \
220 break; \
221 } \
222 else \
223 { \
224 } \
225 \
226 break; \
227 } \
228 \
229 (FINALLY_)(&_SEHFrame.SEH_Header); \
230 \
231 if(0) \
232 {
233
234#define _SEH_END \
235 } \
236 } \
237 \
238 \
239 break; \
240 }
241
242#else
243
244#define _SEH_TRY \
245 for(;;) \
246 { \
247 _SEH_INIT_CONST int _SEHTopTryLevel = (_SEHScopeKind != 0); \
248 _SEHPortableFrame_t * const _SEHCurPortableFrame = _SEHPortableFrame; \
249 _SEHPortableTryLevel_t * const _SEHPrevPortableTryLevel = _SEHPortableTryLevel; \
250 \
251 { \
252 _SEH_INIT_CONST int _SEHScopeKind = 0; \
253 register int _SEHState = 0; \
254 register int _SEHHandle = 0; \
255 _SEHFrame_t _SEHFrame; \
256 _SEHTryLevel_t _SEHTryLevel; \
257 _SEHPortableFrame_t * const _SEHPortableFrame = \
258 _SEHTopTryLevel ? &_SEHFrame.SEH_Header : _SEHCurPortableFrame; \
259 _SEHPortableTryLevel_t * const _SEHPortableTryLevel = &_SEHTryLevel.ST_Header; \
260 \
261 (void)_SEHScopeKind; \
262 (void)_SEHPortableFrame; \
263 (void)_SEHPortableTryLevel; \
264 (void)_SEHHandle; \
265 \
266 for(;;) \
267 { \
268 if(_SEHState) \
269 { \
270 for(;;) \
271 { \
272 {
273
274#define _SEH_EXCEPT(FILTER_) \
275 } \
276 \
277 break; \
278 } \
279 \
280 break; \
281 } \
282 else \
283 { \
284 if((_SEHHandle = _SEHSetJmp(_SEHTryLevel.ST_JmpBuf)) == 0) \
285 { \
286 _SEHTryLevel.ST_Header.SPT_Handlers.SH_Filter = (FILTER_); \
287 _SEHTryLevel.ST_Header.SPT_Handlers.SH_Finally = 0; \
288 \
289 _SEHTryLevel.ST_Header.SPT_Next = _SEHPrevPortableTryLevel; \
290 _SEHFrame.SEH_Header.SPF_TopTryLevel = &_SEHTryLevel.ST_Header; \
291 \
292 if(_SEHTopTryLevel) \
293 { \
294 if(&_SEHLocals != _SEHDummyLocals) \
295 _SEHFrame.SEH_Locals = &_SEHLocals; \
296 \
297 _SEH_EnableTracing(_SEH_DO_DEFAULT_TRACING); \
298 _SEHFrame.SEH_Header.SPF_Handler = _SEHCompilerSpecificHandler; \
299 _SEHEnterFrame(&_SEHFrame.SEH_Header); \
300 } \
301 \
302 ++ _SEHState; \
303 continue; \
304 } \
305 else \
306 { \
307 break; \
308 } \
309 } \
310 \
311 break; \
312 } \
313 \
314 _SEHPortableFrame->SPF_TopTryLevel = _SEHPrevPortableTryLevel; \
315 \
316 if(_SEHHandle) \
317 {
318
319#define _SEH_FINALLY(FINALLY_) \
320 } \
321 \
322 break; \
323 } \
324 \
325 _SEHPortableFrame->SPF_TopTryLevel = _SEHPrevPortableTryLevel; \
326 break; \
327 } \
328 else \
329 { \
330 _SEHTryLevel.ST_Header.SPT_Handlers.SH_Filter = 0; \
331 _SEHTryLevel.ST_Header.SPT_Handlers.SH_Finally = (FINALLY_); \
332 \
333 _SEHTryLevel.ST_Header.SPT_Next = _SEHPrevPortableTryLevel; \
334 _SEHFrame.SEH_Header.SPF_TopTryLevel = &_SEHTryLevel.ST_Header; \
335 \
336 if(_SEHTopTryLevel) \
337 { \
338 if(&_SEHLocals != _SEHDummyLocals) \
339 _SEHFrame.SEH_Locals = &_SEHLocals; \
340 \
341 _SEH_EnableTracing(_SEH_DO_DEFAULT_TRACING); \
342 _SEHFrame.SEH_Header.SPF_Handler = _SEHCompilerSpecificHandler; \
343 _SEHEnterFrame(&_SEHFrame.SEH_Header); \
344 } \
345 \
346 ++ _SEHState; \
347 continue; \
348 } \
349 \
350 break; \
351 } \
352 \
353 (FINALLY_)(&_SEHFrame.SEH_Header); \
354 \
355 if(0) \
356 {
357
358#define _SEH_END \
359 } \
360 } \
361 \
362 if(_SEHTopTryLevel) \
363 _SEHLeaveFrame(); \
364 \
365 break; \
366 }
367
368#endif
369
370#define _SEH_HANDLE _SEH_EXCEPT(_SEH_STATIC_FILTER(_SEH_EXECUTE_HANDLER))
371
372#define _SEH_EnableTracing(LEVEL_) ((void)(_SEHPortableFrame->SPF_Tracing = (LEVEL_)))
373#define _SEH_DisableTracing() ((void)(_SEHPortableFrame->SPF_Tracing = _SEH_DO_TRACE_NONE))
374
375#endif
376
377/* EOF */
#define _SEHJmpBuf_t
Definition: framebased.h:50
static const int _SEHScopeKind
Definition: framebased.h:83
static __declspec(noreturn) __inline void __stdcall _SEHCompilerSpecificHandler(_SEHPortableTryLevel_t *trylevel)
Definition: framebased.h:73
struct __SEHTryLevel _SEHTryLevel_t
static _SEHPortableFrame_t *const _SEHPortableFrame
Definition: framebased.h:84
#define _SEHLongJmp
Definition: framebased.h:48
static _SEHPortableTryLevel_t *const _SEHPortableTryLevel
Definition: framebased.h:85
struct __SEHFrame _SEHFrame_t
#define _SEH_CONTAINING_RECORD(ADDR_, TYPE_, FIELD_)
Definition: pseh.h:43
void *volatile SEH_Locals
Definition: framebased.h:62
_SEHPortableFrame_t SEH_Header
Definition: framebased.h:61
_SEHJmpBuf_t ST_JmpBuf
Definition: framebased.h:69
_SEHPortableTryLevel_t ST_Header
Definition: framebased.h:68
#define __stdcall
Definition: typedefs.h:25