23#ifndef KJK_PSEH_FRAMEBASED_H_
24#define KJK_PSEH_FRAMEBASED_H_
26#if ((__GNUC__ > 4) && (__GNUC_MINOR__ > 1))
28# pragma GCC diagnostic ignored "-Wuninitialized"
38#if defined(_SEH_NO_NATIVE_NLG)
39# error PSEH setjmp/longjmp fallback is no longer supported
43# define _SEHLongJmp __builtin_longjmp
44# define _SEHSetJmp __builtin_setjmp
48# define _SEHLongJmp longjmp
49# define _SEHSetJmp setjmp
50# define _SEHJmpBuf_t jmp_buf
54# define _SEH_INIT_CONST static const
56# define _SEH_INIT_CONST register const
89#define _SEH_ACCESS_LOCALS(LOCALS_) \
90 _SEH_LOCALS_TYPENAME(LOCALS_) * _SEHPLocals; \
94 _SEH_LOCALS_TYPENAME(LOCALS_) *, \
95 _SEH_CONTAINING_RECORD(_SEHPortableFrame, _SEHFrame_t, SEH_Header) \
100#define _SEH_VAR(VAR_) _SEHPLocals->VAR_
104#define _SEH_FILTER(NAME_) \
105 long __stdcall NAME_ \
107 struct _EXCEPTION_POINTERS * _SEHExceptionPointers, \
108 struct __SEHPortableFrame * _SEHPortableFrame \
112#define _SEH_STATIC_FILTER(ACTION_) ((_SEHFilter_t)((ACTION_) + 2))
115#define _SEH_WRAP_FILTER(WRAPPER_, NAME_) \
116 static __inline _SEH_FILTER(WRAPPER_) \
118 return (NAME_)(_SEHExceptionPointers); \
123#define _SEH_FINALLYFUNC(NAME_) \
124 void __stdcall NAME_ \
126 struct __SEHPortableFrame * _SEHPortableFrame \
130#define _SEH_WRAP_FINALLY(WRAPPER_, NAME_) \
131 _SEH_WRAP_FINALLY_ARGS(WRAPPER_, NAME_, ())
133#define _SEH_WRAP_FINALLY_ARGS(WRAPPER_, NAME_, ARGS_) \
134 static __inline _SEH_FINALLYFUNC(WRAPPER_) \
139#define _SEH_WRAP_FINALLY_LOCALS_ARGS(WRAPPER_, LOCALS_, NAME_, ARGS_) \
140 static __inline _SEH_FINALLYFUNC(WRAPPER_) \
142 _SEH_ACCESS_LOCALS(LOCALS_); \
148# define _SEH_DECLARE_HANDLERS(FILTER_, FINALLY_) \
149 static const _SEHHandlers_t _SEHHandlers = { (FILTER_), (FINALLY_) };
151# define _SEH_DECLARE_HANDLERS(FILTER_, FINALLY_) \
152 _SEHHandlers_t _SEHHandlers = { (0), (0) }; \
153 _SEHHandlers.SH_Filter = (FILTER_); \
154 _SEHHandlers.SH_Finally = (FINALLY_);
157#define _SEH_SetExceptionCode(CODE_) (_SEHPortableFrame->SPF_Code = (CODE_))
158#define _SEH_GetExceptionCode() (unsigned long)(_SEHPortableFrame->SPF_Code)
160#define _SEH_GetExceptionPointers() \
161 ((struct _EXCEPTION_POINTERS *)_SEHExceptionPointers)
163#define _SEH_AbnormalTermination() (_SEHPortableFrame->SPF_Code != 0)
165#define _SEH_LEAVE break
167#define _SEH_YIELD(STMT_) \
192#define _SEH_EXCEPT(FILTER_) \
214#define _SEH_FINALLY(FINALLY_) \
229 (FINALLY_)(&_SEHFrame.SEH_Header); \
247 _SEH_INIT_CONST int _SEHTopTryLevel = (_SEHScopeKind != 0); \
248 _SEHPortableFrame_t * const _SEHCurPortableFrame = _SEHPortableFrame; \
249 _SEHPortableTryLevel_t * const _SEHPrevPortableTryLevel = _SEHPortableTryLevel; \
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; \
261 (void)_SEHScopeKind; \
262 (void)_SEHPortableFrame; \
263 (void)_SEHPortableTryLevel; \
274#define _SEH_EXCEPT(FILTER_) \
284 if((_SEHHandle = _SEHSetJmp(_SEHTryLevel.ST_JmpBuf)) == 0) \
286 _SEHTryLevel.ST_Header.SPT_Handlers.SH_Filter = (FILTER_); \
287 _SEHTryLevel.ST_Header.SPT_Handlers.SH_Finally = 0; \
289 _SEHTryLevel.ST_Header.SPT_Next = _SEHPrevPortableTryLevel; \
290 _SEHFrame.SEH_Header.SPF_TopTryLevel = &_SEHTryLevel.ST_Header; \
292 if(_SEHTopTryLevel) \
294 if(&_SEHLocals != _SEHDummyLocals) \
295 _SEHFrame.SEH_Locals = &_SEHLocals; \
297 _SEH_EnableTracing(_SEH_DO_DEFAULT_TRACING); \
298 _SEHFrame.SEH_Header.SPF_Handler = _SEHCompilerSpecificHandler; \
299 _SEHEnterFrame(&_SEHFrame.SEH_Header); \
314 _SEHPortableFrame->SPF_TopTryLevel = _SEHPrevPortableTryLevel; \
319#define _SEH_FINALLY(FINALLY_) \
325 _SEHPortableFrame->SPF_TopTryLevel = _SEHPrevPortableTryLevel; \
330 _SEHTryLevel.ST_Header.SPT_Handlers.SH_Filter = 0; \
331 _SEHTryLevel.ST_Header.SPT_Handlers.SH_Finally = (FINALLY_); \
333 _SEHTryLevel.ST_Header.SPT_Next = _SEHPrevPortableTryLevel; \
334 _SEHFrame.SEH_Header.SPF_TopTryLevel = &_SEHTryLevel.ST_Header; \
336 if(_SEHTopTryLevel) \
338 if(&_SEHLocals != _SEHDummyLocals) \
339 _SEHFrame.SEH_Locals = &_SEHLocals; \
341 _SEH_EnableTracing(_SEH_DO_DEFAULT_TRACING); \
342 _SEHFrame.SEH_Header.SPF_Handler = _SEHCompilerSpecificHandler; \
343 _SEHEnterFrame(&_SEHFrame.SEH_Header); \
353 (FINALLY_)(&_SEHFrame.SEH_Header); \
362 if(_SEHTopTryLevel) \
370#define _SEH_HANDLE _SEH_EXCEPT(_SEH_STATIC_FILTER(_SEH_EXECUTE_HANDLER))
372#define _SEH_EnableTracing(LEVEL_) ((void)(_SEHPortableFrame->SPF_Tracing = (LEVEL_)))
373#define _SEH_DisableTracing() ((void)(_SEHPortableFrame->SPF_Tracing = _SEH_DO_TRACE_NONE))
static const int _SEHScopeKind
static __declspec(noreturn) __inline void __stdcall _SEHCompilerSpecificHandler(_SEHPortableTryLevel_t *trylevel)
struct __SEHTryLevel _SEHTryLevel_t
static _SEHPortableFrame_t *const _SEHPortableFrame
static _SEHPortableTryLevel_t *const _SEHPortableTryLevel
struct __SEHFrame _SEHFrame_t
#define _SEH_CONTAINING_RECORD(ADDR_, TYPE_, FIELD_)
void *volatile SEH_Locals
_SEHPortableFrame_t SEH_Header
_SEHPortableTryLevel_t ST_Header