Home | Info | Community | Development | myReactOS | Contact Us
ReactOS Development > Doxygenpseh2.h
Go to the documentation of this file.
00001 /* 00002 Copyright (c) 2008 KJK::Hyperion 00003 00004 Permission is hereby granted, free of charge, to any person obtaining a 00005 copy of this software and associated documentation files (the "Software"), 00006 to deal in the Software without restriction, including without limitation 00007 the rights to use, copy, modify, merge, publish, distribute, sublicense, 00008 and/or sell copies of the Software, and to permit persons to whom the 00009 Software is furnished to do so, subject to the following conditions: 00010 00011 The above copyright notice and this permission notice shall be included in 00012 all copies or substantial portions of the Software. 00013 00014 THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR 00015 IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, 00016 FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE 00017 AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER 00018 LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING 00019 FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER 00020 DEALINGS IN THE SOFTWARE. 00021 */ 00022 00023 #ifndef KJK_PSEH2_H_ 00024 #define KJK_PSEH2_H_ 00025 00026 #if defined(USE_NATIVE_SEH) || defined(_MSC_VER) 00027 00028 #include <excpt.h> 00029 #define _SEH2_TRY __try 00030 #define _SEH2_FINALLY __finally 00031 #define _SEH2_EXCEPT(...) __except(__VA_ARGS__) 00032 #define _SEH2_END 00033 #define _SEH2_GetExceptionInformation() (GetExceptionInformation()) 00034 #define _SEH2_GetExceptionCode() (GetExceptionCode()) 00035 #define _SEH2_AbnormalTermination() (AbnormalTermination()) 00036 #define _SEH2_YIELD(STMT_) STMT_ 00037 #define _SEH2_LEAVE __leave 00038 00039 #elif defined(USE_DUMMY_PSEH) || defined (__arm__) || defined(__clang__) || defined(_M_AMD64) 00040 00041 #define _SEH2_TRY { 00042 #define _SEH2_FINALLY } { 00043 #define _SEH2_EXCEPT(...) } if (0) { 00044 #define _SEH2_END } 00045 #define _SEH2_GetExceptionInformation() 00046 #define _SEH2_GetExceptionCode() 0 00047 #define _SEH2_AbnormalTermination() 00048 #define _SEH2_YIELD(STMT_) STMT_ 00049 #define _SEH2_LEAVE 00050 00051 #elif defined(__GNUC__) 00052 00053 struct _EXCEPTION_RECORD; 00054 struct _EXCEPTION_POINTERS; 00055 struct _CONTEXT; 00056 00057 typedef int (__cdecl * _SEH2FrameHandler_t) 00058 ( 00059 struct _EXCEPTION_RECORD *, 00060 void *, 00061 struct _CONTEXT *, 00062 void * 00063 ); 00064 00065 typedef struct __SEH2Registration 00066 { 00067 struct __SEH2Registration * SER_Prev; 00068 _SEH2FrameHandler_t SER_Handler; 00069 } 00070 _SEH2Registration_t; 00071 00072 typedef struct __SEH2Frame 00073 { 00074 _SEH2Registration_t SF_Registration; 00075 volatile struct __SEH2TryLevel * volatile SF_TopTryLevel; 00076 volatile unsigned long SF_Code; 00077 } 00078 _SEH2Frame_t; 00079 00080 typedef struct __SEH2TryLevel 00081 { 00082 volatile struct __SEH2TryLevel * ST_Next; 00083 void * ST_Filter; 00084 void * ST_Body; 00085 } 00086 _SEH2TryLevel_t; 00087 00088 typedef struct __SEH2HandleTryLevel 00089 { 00090 _SEH2TryLevel_t SHT_Common; 00091 void * volatile SHT_Esp; 00092 void * volatile SHT_Ebp; 00093 void * volatile SHT_Ebx; 00094 void * volatile SHT_Esi; 00095 void * volatile SHT_Edi; 00096 } 00097 _SEH2HandleTryLevel_t; 00098 00099 #ifdef __cplusplus 00100 extern "C" { 00101 #endif 00102 00103 extern int __cdecl _SEH2EnterFrameAndTrylevel(_SEH2Frame_t *, volatile _SEH2TryLevel_t *); 00104 extern __attribute__((returns_twice)) int __cdecl _SEH2EnterFrameAndHandleTrylevel(_SEH2Frame_t *, volatile _SEH2HandleTryLevel_t *, void *); 00105 extern __attribute__((returns_twice)) int __cdecl _SEH2EnterHandleTrylevel(_SEH2Frame_t *, volatile _SEH2HandleTryLevel_t *, void *); 00106 extern void __cdecl _SEH2LeaveFrame(void); 00107 extern void __cdecl _SEH2Return(void); 00108 00109 #ifdef __cplusplus 00110 } 00111 #endif 00112 00113 /* A no-op side effect that scares GCC */ 00114 #define __SEH_SIDE_EFFECT __asm__ __volatile__("#") 00115 00116 /* A no-op without any real side effects, but silences warnings */ 00117 #define __SEH_PRETEND_SIDE_EFFECT (void)0 00118 00119 /* Forces GCC to consider the specified label reachable */ 00120 #define __SEH_USE_LABEL(L_) if(__SEH_VOLATILE_FALSE) goto L_; 00121 00122 /* Makes GCC pretend the specified label is reachable, to silence warnings */ 00123 #define __SEH_PRETEND_USE_LABEL(L_) (void)(&&L_) 00124 00125 /* Soft memory barrier */ 00126 #define __SEH_BARRIER __asm__ __volatile__("#":::"memory") 00127 00128 /* GCC doesn't know that this equals zero */ 00129 #define __SEH_VOLATILE_ZERO ({ int zero = 0; __asm__ __volatile__("#" : "+g" (zero)); zero; }) 00130 00131 #define __SEH_VOLATILE_FALSE __builtin_expect(__SEH_VOLATILE_ZERO, 0) 00132 #define __SEH_VOLATILE_TRUE __builtin_expect(!__SEH_VOLATILE_ZERO, 1) 00133 00134 #define ___SEH_STRINGIFY(X_) # X_ 00135 #define __SEH_STRINGIFY(X_) ___SEH_STRINGIFY(X_) 00136 00137 #define __SEH_EXCEPT_RET long 00138 #define __SEH_EXCEPT_ARGS __attribute__((unused)) _SEH2Frame_t * _SEH2FrameP, __attribute__((unused)) struct _EXCEPTION_POINTERS * _SEHExceptionInformation 00139 #define __SEH_EXCEPT_ARGS_ , __SEH_EXCEPT_ARGS 00140 #define __SEH_EXCEPT_PFN __SEH_DECLARE_EXCEPT_PFN 00141 #define __SEH_DECLARE_EXCEPT_PFN(NAME_) __SEH_EXCEPT_RET (__cdecl * NAME_)(__SEH_EXCEPT_ARGS) 00142 #define __SEH_DECLARE_EXCEPT(NAME_) __SEH_EXCEPT_RET __cdecl NAME_(__SEH_EXCEPT_ARGS) 00143 #define __SEH_DEFINE_EXCEPT(NAME_) __SEH_EXCEPT_RET __cdecl NAME_(__SEH_EXCEPT_ARGS) 00144 00145 #define __SEH_FINALLY_RET void 00146 #define __SEH_FINALLY_ARGS void 00147 #define __SEH_FINALLY_ARGS_ 00148 #define __SEH_FINALLY_PFN __SEH_DECLARE_FINALLY_PFN 00149 #define __SEH_DECLARE_FINALLY_PFN(NAME_) __SEH_FINALLY_RET (__cdecl * NAME_)(__SEH_FINALLY_ARGS) 00150 #define __SEH_DECLARE_FINALLY(NAME_) __SEH_FINALLY_RET __cdecl NAME_(__SEH_FINALLY_ARGS) 00151 #define __SEH_DEFINE_FINALLY(NAME_) __SEH_FINALLY_RET __cdecl NAME_(__SEH_FINALLY_ARGS) 00152 00153 #define __SEH_RETURN_EXCEPT(R_) return (long)(R_) 00154 #define __SEH_RETURN_FINALLY() return 00155 00156 #define __SEH_BEGIN_TRY \ 00157 { \ 00158 __label__ _SEHEndTry; \ 00159 \ 00160 __SEH_PRETEND_USE_LABEL(_SEHEndTry); \ 00161 \ 00162 { \ 00163 __SEH_BARRIER; 00164 00165 #define __SEH_END_TRY \ 00166 __SEH_BARRIER; \ 00167 } \ 00168 _SEHEndTry:; \ 00169 } 00170 00171 #define __SEH_SET_TRYLEVEL(TRYLEVEL_) \ 00172 { \ 00173 __SEH_BARRIER; _SEH2FrameP->SF_TopTryLevel = (TRYLEVEL_); __SEH_BARRIER; \ 00174 } 00175 00176 #define __SEH_ENTER_FRAME_AND_TRYLEVEL(TRYLEVEL_) (_SEH2EnterFrameAndTrylevel(_SEH2FrameP, (TRYLEVEL_))) 00177 #define __SEH_ENTER_TRYLEVEL(TRYLEVEL_) ((__SEH_SET_TRYLEVEL((TRYLEVEL_))), 0) 00178 00179 #define __SEH_ENTER_FRAME_AND_HANDLE_TRYLEVEL(TRYLEVEL_, HANDLE_) _SEH2EnterFrameAndHandleTrylevel(_SEH2FrameP, (TRYLEVEL_), (HANDLE_)) 00180 #define __SEH_ENTER_HANDLE_TRYLEVEL(TRYLEVEL_, HANDLE_) _SEH2EnterHandleTrylevel(_SEH2FrameP, (TRYLEVEL_), (HANDLE_)) 00181 00182 #define __SEH_ENTER_SCOPE(TRYLEVEL_) (_SEHTopTryLevel ? __SEH_ENTER_FRAME_AND_TRYLEVEL(TRYLEVEL_) : __SEH_ENTER_TRYLEVEL(TRYLEVEL_)) 00183 #define __SEH_ENTER_HANDLE_SCOPE(TRYLEVEL_, HANDLE_) (({ __SEH_BARRIER; __asm__ __volatile__("mov %%esp, %0" : "=m" ((TRYLEVEL_)->SHT_Esp)); __SEH_BARRIER; }), (_SEHTopTryLevel ? __SEH_ENTER_FRAME_AND_HANDLE_TRYLEVEL((TRYLEVEL_), (HANDLE_)) : __SEH_ENTER_HANDLE_TRYLEVEL((TRYLEVEL_), (HANDLE_)))) 00184 00185 #define __SEH_LEAVE_TRYLEVEL() \ 00186 if(!_SEHTopTryLevel) \ 00187 { \ 00188 __SEH_SET_TRYLEVEL(_SEHPrevTryLevelP); \ 00189 } \ 00190 00191 #define __SEH_LEAVE_FRAME() \ 00192 if(_SEHTopTryLevel) \ 00193 { \ 00194 _SEH2LeaveFrame(); \ 00195 } 00196 00197 #define __SEH_END_SCOPE_CHAIN \ 00198 static __attribute__((unused)) const int _SEH2ScopeKind = 1; \ 00199 static __attribute__((unused)) _SEH2Frame_t * const _SEH2FrameP = 0; \ 00200 static __attribute__((unused)) _SEH2TryLevel_t * const _SEH2TryLevelP = 0; 00201 00202 #define __SEH_BEGIN_SCOPE \ 00203 for(;;) \ 00204 { \ 00205 const int _SEHTopTryLevel = (_SEH2ScopeKind != 0); \ 00206 _SEH2Frame_t * const _SEHCurFrameP = _SEH2FrameP; \ 00207 volatile _SEH2TryLevel_t * const _SEHPrevTryLevelP = _SEH2TryLevelP; \ 00208 __attribute__((unused)) int _SEHAbnormalTermination; \ 00209 \ 00210 (void)_SEHTopTryLevel; \ 00211 (void)_SEHCurFrameP; \ 00212 (void)_SEHPrevTryLevelP; \ 00213 \ 00214 { \ 00215 __label__ _SEHBeforeTry; \ 00216 __label__ _SEHDoTry; \ 00217 __label__ _SEHAfterTry; \ 00218 static const int _SEH2ScopeKind = 0; \ 00219 volatile _SEH2TryLevel_t _SEHTryLevel; \ 00220 volatile _SEH2HandleTryLevel_t _SEHHandleTryLevel; \ 00221 _SEH2Frame_t _SEH2Frame[_SEHTopTryLevel ? 1 : 0]; \ 00222 volatile _SEH2TryLevel_t * _SEH2TryLevelP; \ 00223 _SEH2Frame_t * const _SEH2FrameP = _SEHTopTryLevel ? \ 00224 _SEH2Frame : _SEHCurFrameP; \ 00225 \ 00226 (void)_SEH2ScopeKind; \ 00227 (void)_SEHTryLevel; \ 00228 (void)_SEHHandleTryLevel; \ 00229 (void)_SEH2FrameP; \ 00230 (void)_SEH2TryLevelP; \ 00231 \ 00232 goto _SEHBeforeTry; \ 00233 \ 00234 _SEHDoTry:; 00235 00236 #define __SEH_END_SCOPE \ 00237 } \ 00238 \ 00239 break; \ 00240 } 00241 00242 #define __SEH_SCOPE_LOCALS \ 00243 __label__ _SEHBeginExcept; \ 00244 __label__ _SEHEndExcept; \ 00245 \ 00246 auto __SEH_DECLARE_FINALLY(_SEHFinally); 00247 00248 #define _SEH2_TRY \ 00249 __SEH_BEGIN_SCOPE \ 00250 { \ 00251 __SEH_SCOPE_LOCALS; \ 00252 \ 00253 __SEH_BEGIN_TRY \ 00254 { 00255 00256 #define _SEH2_FINALLY \ 00257 } \ 00258 __SEH_END_TRY; \ 00259 \ 00260 goto _SEHAfterTry; \ 00261 _SEHBeforeTry:; \ 00262 \ 00263 __SEH_PRETEND_USE_LABEL(_SEHBeginExcept); \ 00264 __SEH_PRETEND_USE_LABEL(_SEHEndExcept); \ 00265 \ 00266 _SEHTryLevel.ST_Filter = 0; \ 00267 _SEHTryLevel.ST_Body = &_SEHFinally; \ 00268 _SEHTryLevel.ST_Next = _SEHPrevTryLevelP; \ 00269 __SEH_ENTER_SCOPE(&_SEHTryLevel); \ 00270 _SEH2TryLevelP = &_SEHTryLevel; \ 00271 \ 00272 _SEHAbnormalTermination = 1; \ 00273 \ 00274 goto _SEHDoTry; \ 00275 _SEHAfterTry:; \ 00276 \ 00277 _SEHAbnormalTermination = 0; \ 00278 \ 00279 __SEH_LEAVE_TRYLEVEL(); \ 00280 \ 00281 _SEHFinally(); \ 00282 goto _SEHEndExcept; \ 00283 \ 00284 _SEHBeginExcept:; \ 00285 \ 00286 __attribute__((noinline)) __SEH_DEFINE_FINALLY(_SEHFinally) \ 00287 { \ 00288 __SEH_END_SCOPE_CHAIN; \ 00289 \ 00290 (void)_SEH2ScopeKind; \ 00291 (void)_SEH2FrameP; \ 00292 (void)_SEH2TryLevelP; \ 00293 \ 00294 for(;; ({ __SEH_RETURN_FINALLY(); })) \ 00295 { 00296 00297 #define _SEH2_EXCEPT(...) \ 00298 } \ 00299 __SEH_END_TRY; \ 00300 \ 00301 goto _SEHAfterTry; \ 00302 \ 00303 _SEHBeforeTry:; \ 00304 \ 00305 { \ 00306 __attribute__((unused)) struct _EXCEPTION_POINTERS * volatile _SEHExceptionInformation; \ 00307 \ 00308 if(__builtin_constant_p((__VA_ARGS__)) && (__VA_ARGS__) <= 0) \ 00309 { \ 00310 if((__VA_ARGS__) < 0) \ 00311 { \ 00312 _SEHTryLevel.ST_Filter = (void *)-1; \ 00313 _SEHTryLevel.ST_Body = 0; \ 00314 } \ 00315 else \ 00316 { \ 00317 _SEHTryLevel.ST_Filter = (void *)0; \ 00318 _SEHTryLevel.ST_Body = 0; \ 00319 } \ 00320 \ 00321 _SEHTryLevel.ST_Next = _SEHPrevTryLevelP; \ 00322 __SEH_ENTER_SCOPE(&_SEHTryLevel); \ 00323 _SEH2TryLevelP = &_SEHTryLevel; \ 00324 } \ 00325 else \ 00326 { \ 00327 if(__builtin_constant_p((__VA_ARGS__)) && (__VA_ARGS__) > 0) \ 00328 _SEHHandleTryLevel.SHT_Common.ST_Filter = (void *)1; \ 00329 else \ 00330 { \ 00331 __SEH_DEFINE_EXCEPT(_SEHExcept) \ 00332 { \ 00333 __SEH_RETURN_EXCEPT((__VA_ARGS__)); \ 00334 } \ 00335 \ 00336 _SEHHandleTryLevel.SHT_Common.ST_Filter = &_SEHExcept; \ 00337 } \ 00338 \ 00339 _SEHHandleTryLevel.SHT_Common.ST_Next = _SEHPrevTryLevelP; \ 00340 _SEH2TryLevelP = &_SEHHandleTryLevel.SHT_Common; \ 00341 \ 00342 if(__builtin_expect(__SEH_ENTER_HANDLE_SCOPE(&_SEHHandleTryLevel, &&_SEHBeginExcept), 0)) \ 00343 goto _SEHBeginExcept; \ 00344 } \ 00345 } \ 00346 \ 00347 goto _SEHDoTry; \ 00348 \ 00349 __attribute__((unused)) __SEH_DEFINE_FINALLY(_SEHFinally) { __SEH_RETURN_FINALLY(); } \ 00350 \ 00351 _SEHAfterTry:; \ 00352 __SEH_LEAVE_TRYLEVEL(); \ 00353 \ 00354 goto _SEHEndExcept; \ 00355 \ 00356 _SEHBeginExcept:; \ 00357 { \ 00358 { \ 00359 __SEH_BARRIER; 00360 00361 #define _SEH2_END \ 00362 __SEH_BARRIER; \ 00363 } \ 00364 } \ 00365 \ 00366 _SEHEndExcept:; \ 00367 \ 00368 __SEH_LEAVE_FRAME(); \ 00369 } \ 00370 __SEH_END_SCOPE; 00371 00372 #define _SEH2_GetExceptionInformation() (_SEHExceptionInformation) 00373 #define _SEH2_GetExceptionCode() ((_SEH2FrameP)->SF_Code) 00374 #define _SEH2_AbnormalTermination() (_SEHAbnormalTermination) 00375 00376 #define _SEH2_YIELD(STMT_) \ 00377 for(;;) \ 00378 { \ 00379 if(!_SEH2ScopeKind) \ 00380 _SEH2Return(); \ 00381 \ 00382 STMT_; \ 00383 } 00384 00385 #define _SEH2_LEAVE goto _SEHEndTry 00386 00387 __SEH_END_SCOPE_CHAIN; 00388 00389 00390 #else 00391 #error no PSEH support 00392 #endif 00393 00394 #endif /* !KJK_PSEH2_H_ */ 00395 00396 /* EOF */ Generated on Fri May 25 2012 04:31:45 for ReactOS by
1.7.6.1
|