ReactOS  0.4.15-dev-1018-g0695ecb
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 
59 typedef struct __SEHFrame
60 {
62  void * volatile SEH_Locals;
63 }
65 
66 typedef struct __SEHTryLevel
67 {
70 }
72 
73 static __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 
83 static 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 */
struct __SEHFrame _SEHFrame_t
static const int _SEHScopeKind
Definition: framebased.h:83
struct __SEHTryLevel _SEHTryLevel_t
_SEHPortableFrame_t SEH_Header
Definition: framebased.h:61
_SEHJmpBuf_t ST_JmpBuf
Definition: framebased.h:69
#define _SEHJmpBuf_t
Definition: framebased.h:50
void *volatile SEH_Locals
Definition: framebased.h:62
#define __stdcall
Definition: typedefs.h:25
#define _SEHLongJmp
Definition: framebased.h:48
static _SEHPortableTryLevel_t *const _SEHPortableTryLevel
Definition: framebased.h:85
_SEHPortableTryLevel_t ST_Header
Definition: framebased.h:68
#define _SEH_CONTAINING_RECORD(ADDR_, TYPE_, FIELD_)
Definition: pseh.h:43
static __declspec(noreturn) __inline void __stdcall _SEHCompilerSpecificHandler(_SEHPortableTryLevel_t *trylevel)
Definition: framebased.h:73
static _SEHPortableFrame_t *const _SEHPortableFrame
Definition: framebased.h:84