upgrade to PSEH2 (note, the new macros are still named _SEH_*, not _SEH2_*!) Modified: trunk/reactos/include/ddk/exfuncs.h Modified: trunk/reactos/include/pseh/framebased/internal.h Modified: trunk/reactos/include/pseh/framebased.h Modified: trunk/reactos/include/pseh/native.h Modified: trunk/reactos/include/pseh/setjmp.h Modified: trunk/reactos/include/pseh.h Modified: trunk/reactos/lib/dbghelp/msc.c Modified: trunk/reactos/lib/kernel32/k32.h Modified: trunk/reactos/lib/pseh/framebased.c Modified: trunk/reactos/lib/pseh/i386/framebased.asm Modified: trunk/reactos/lib/pseh/i386/setjmp.asm Modified: trunk/reactos/ntoskrnl/ex/error.c Modified: trunk/reactos/ntoskrnl/ex/event.c Modified: trunk/reactos/ntoskrnl/ex/evtpair.c Modified: trunk/reactos/ntoskrnl/ex/mutant.c Modified: trunk/reactos/ntoskrnl/ex/profile.c Modified: trunk/reactos/ntoskrnl/ex/sem.c Modified: trunk/reactos/ntoskrnl/ex/sysinfo.c Modified: trunk/reactos/ntoskrnl/ex/time.c Modified: trunk/reactos/ntoskrnl/ex/timer.c Modified: trunk/reactos/ntoskrnl/include/internal/ex.h Modified: trunk/reactos/ntoskrnl/include/ntoskrnl.h Modified: trunk/reactos/ntoskrnl/ke/i386/trap.s Modified: trunk/reactos/ntoskrnl/mm/pool.c Modified: trunk/reactos/subsys/win32k/w32k.h _____
Modified: trunk/reactos/include/ddk/exfuncs.h --- trunk/reactos/include/ddk/exfuncs.h 2005-05-06 21:18:20 UTC (rev 15062) +++ trunk/reactos/include/ddk/exfuncs.h 2005-05-06 22:25:30 UTC (rev 15063) @@ -719,9 +719,9 @@
SUITE_TYPE SuiteType );
-BOOLEAN +LONG STDCALL -ExSystemExceptionFilter(); +ExSystemExceptionFilter(VOID);
VOID STDCALL _____
Modified: trunk/reactos/include/pseh/framebased/internal.h --- trunk/reactos/include/pseh/framebased/internal.h 2005-05-06 21:18:20 UTC (rev 15062) +++ trunk/reactos/include/pseh/framebased/internal.h 2005-05-06 22:25:30 UTC (rev 15063) @@ -43,6 +43,7 @@
_SEHRegistration_t;
struct __SEHPortableFrame; +struct __SEHPortableTryLevel;
typedef long (__stdcall * _SEHFilter_t) ( @@ -52,7 +53,7 @@
typedef __declspec(noreturn) void (__stdcall * _SEHHandler_t) ( - struct __SEHPortableFrame * + struct __SEHPortableTryLevel * );
typedef void (__stdcall * _SEHFinally_t) @@ -63,23 +64,69 @@ typedef struct __SEHHandlers { _SEHFilter_t SH_Filter; - _SEHHandler_t SH_Handler; _SEHFinally_t SH_Finally; } _SEHHandlers_t;
+typedef struct __SEHPortableTryLevel +{ + struct __SEHPortableTryLevel * SPT_Next; + const _SEHHandlers_t * SPT_Handlers; +} +_SEHPortableTryLevel_t; + typedef struct __SEHPortableFrame { _SEHRegistration_t SPF_Registration; unsigned long SPF_Code; - int SPF_Handling; - const _SEHHandlers_t * SPF_Handlers; + _SEHHandler_t SPF_Handler; + _SEHPortableTryLevel_t * SPF_TopTryLevel; } _SEHPortableFrame_t;
-extern void __stdcall _SEHEnter(_SEHPortableFrame_t *); -extern void __stdcall _SEHLeave(_SEHPortableFrame_t *); +#ifdef __cplusplus +extern "C" +{ +#endif
+extern void __stdcall _SEHEnterFrame_s +( + _SEHPortableFrame_t *, + _SEHPortableTryLevel_t * +); + +extern void __stdcall _SEHEnterTry_s(_SEHPortableTryLevel_t *); +extern void __stdcall _SEHLeave_s(void); + +#if !defined(_SEH_NO_FASTCALL) +# ifdef _M_IX86 +# define _SEH_FASTCALL __fastcall +# else +# define _SEH_FASTCALL __stdcall +# endif + +extern void _SEH_FASTCALL _SEHEnterFrame_f +( + _SEHPortableFrame_t *, + _SEHPortableTryLevel_t * +); + +extern void _SEH_FASTCALL _SEHEnterTry_f(_SEHPortableTryLevel_t *); +extern void _SEH_FASTCALL _SEHLeave_f(void); + +# define _SEHEnterFrame _SEHEnterFrame_f +# define _SEHEnterTry _SEHEnterTry_f +# define _SEHLeave _SEHLeave_f +#else +# define _SEHEnterFrame _SEHEnterFrame_s +# define _SEHEnterTry _SEHEnterTry_s +# define _SEHLeave _SEHLeave_s #endif
+#ifdef __cplusplus +} +#endif + +#endif + /* EOF */ _____
Modified: trunk/reactos/include/pseh/framebased.h --- trunk/reactos/include/pseh/framebased.h 2005-05-06 21:18:20 UTC (rev 15062) +++ trunk/reactos/include/pseh/framebased.h 2005-05-06 22:25:30 UTC (rev 15063) @@ -25,7 +25,6 @@
#include <pseh/framebased/internal.h> #include <pseh/excpt.h> -#include <malloc.h>
#ifndef offsetof # include <stddef.h> @@ -46,35 +45,34 @@ # define _SEHSetJmp setjmp # define _SEHJmpBuf_t jmp_buf #endif - +unsigned long DbgPrint(char * Format,...); typedef struct __SEHFrame { _SEHPortableFrame_t SEH_Header; - _SEHJmpBuf_t SEH_JmpBuf; void * SEH_Locals; } _SEHFrame_t;
-/* - Note: just define __inline to an empty symbol if your C compiler doesn't - support it -*/ -#ifdef __cplusplus -# ifndef __inline -# define __inline inline -# endif -#endif +typedef struct __SEHTryLevel +{ + _SEHPortableTryLevel_t ST_Header; + _SEHJmpBuf_t ST_JmpBuf; +} +_SEHTryLevel_t;
static __declspec(noreturn) __inline void __stdcall _SEHCompilerSpecificHandler ( - _SEHPortableFrame_t * frame + _SEHPortableTryLevel_t * trylevel ) { - _SEHFrame_t * myframe; - myframe = (_SEHFrame_t *)(((char *)frame) - offsetof(_SEHFrame_t, SEH_Header)); - _SEHLongJmp(myframe->SEH_JmpBuf, 1); + _SEHTryLevel_t * mytrylevel; + mytrylevel = _SEH_CONTAINING_RECORD(trylevel, _SEHTryLevel_t, ST_Header); + _SEHLongJmp(mytrylevel->ST_JmpBuf, 1); }
+static const int _SEHScopeKind = 1; +static _SEHPortableFrame_t * const _SEHPortableFrame = 0; + /* SHARED LOCALS */ /* Access the locals for the current frame */ #define _SEH_ACCESS_LOCALS(LOCALS_) \ @@ -111,7 +109,7 @@
/* FINALLY FUNCTIONS */ /* Declares a finally function's prototype */ -#define _SEH_FINALLY(NAME_) \ +#define _SEH_FINALLYFUNC(NAME_) \ void __stdcall NAME_ \ ( \ struct __SEHPortableFrame * _SEHPortableFrame \ @@ -122,200 +120,270 @@ _SEH_WRAP_FINALLY_ARGS(WRAPPER_, NAME_, ())
#define _SEH_WRAP_FINALLY_ARGS(WRAPPER_, NAME_, ARGS_) \ - static __inline _SEH_FINALLY(WRAPPER_) \ + static __inline _SEH_FINALLYFUNC(WRAPPER_) \ { \ NAME_ ARGS_; \ }
#define _SEH_WRAP_FINALLY_LOCALS_ARGS(WRAPPER_, LOCALS_, NAME_, ARGS_) \ - static __inline _SEH_FINALLY(WRAPPER_) \ + static __inline _SEH_FINALLYFUNC(WRAPPER_) \ { \ _SEH_ACCESS_LOCALS(LOCALS_); \ NAME_ ARGS_; \ }
/* SAFE BLOCKS */ -#define _SEH_TRY_FINALLY(FINALLY_) \ +#define _SEHX_TRY_FINALLY(FINALLY_) \ _SEH_TRY_FILTER_FINALLY \ ( \ _SEH_STATIC_FILTER(_SEH_CONTINUE_SEARCH), \ (FINALLY_) \ )
-#define _SEH_END_FINALLY _SEH_HANDLE _SEH_END +#define _SEHX_END_FINALLY _SEH_HANDLE _SEH_END
-#define _SEH_TRY_FILTER(FILTER_) \ - _SEH_TRY_FILTER_FINALLY((FILTER_), NULL) +#define _SEHX_TRY_FILTER(FILTER_) \ + _SEH_TRY_FILTER_FINALLY((FILTER_), 0)
-#define _SEH_TRY_HANDLE_FINALLY(FINALLY_) \ +#define _SEHX_TRY_HANDLE_FINALLY(FINALLY_) \ _SEH_TRY_FILTER_FINALLY \ ( \ _SEH_STATIC_FILTER(_SEH_EXECUTE_HANDLER), \ (FINALLY_) \ )
-#define _SEH_TRY \ - _SEH_TRY_HANDLE_FINALLY(NULL) +#define _SEHX_TRY \ + _SEH_TRY_HANDLE_FINALLY(0)
#ifdef __cplusplus # define _SEH_DECLARE_HANDLERS(FILTER_, FINALLY_) \ - const _SEHHandlers_t _SEHHandlers = \ - { \ - (FILTER_), \ - _SEHCompilerSpecificHandler, \ - (FINALLY_) \ - }; + static const _SEHHandlers_t _SEHHandlers = { (FILTER_), (FINALLY_) }; #else # define _SEH_DECLARE_HANDLERS(FILTER_, FINALLY_) \ - _SEHHandlers_t _SEHHandlers = \ - { \ - (0), \ - _SEHCompilerSpecificHandler, \ - (0) \ - }; \ + _SEHHandlers_t _SEHHandlers = { (0), (0) }; \ _SEHHandlers.SH_Filter = (FILTER_); \ _SEHHandlers.SH_Finally = (FINALLY_); #endif
-#define _SEH_TRY_FILTER_FINALLY(FILTER_, FINALLY_) \ +#define _SEHX_TRY_FILTER_FINALLY(FILTER_, FINALLY_) \ { \ - _SEHFrame_t * _SEHFrame; \ - volatile _SEHPortableFrame_t * _SEHPortableFrame; \ + _SEHPortableFrame_t * const _SEHCurPortableFrame = _SEHPortableFrame; \
\ - _SEH_DECLARE_HANDLERS(FILTER_, FINALLY_); \ + { \ + _SEHFrame_t _SEHFrame; \ + _SEHTryLevel_t _SEHTryLevel; \ + _SEHPortableFrame_t * const _SEHPortableFrame = \ + _SEHScopeKind ? &_SEHFrame.SEH_Header : _SEHCurPortableFrame; \
\ - _SEHFrame = _alloca(sizeof(_SEHFrame_t)); \ - _SEHFrame->SEH_Header.SPF_Handlers = &_SEHHandlers; \ - _SEHFrame->SEH_Locals = &_SEHLocals; \ + (void)_SEHPortableFrame; \
\ - _SEHPortableFrame = &_SEHFrame->SEH_Header; \ - (void)_SEHPortableFrame; \ + _SEH_DECLARE_HANDLERS((FILTER_), (FINALLY_)); \
\ - if(_SEHSetJmp(_SEHFrame->SEH_JmpBuf) == 0) \ - { \ - _SEHEnter(&_SEHFrame->SEH_Header); \ + _SEHTryLevel.ST_Header.SPT_Handlers = &_SEHHandlers; \
\ - do \ - { - -#define _SEH_HANDLE \ + if(_SEHScopeKind) \ + { \ + if(&_SEHLocals != _SEHDummyLocals) \ + _SEHFrame.SEH_Locals = &_SEHLocals; \
\ + _SEHFrame.SEH_Header.SPF_Handler = _SEHCompilerSpecificHandler; \ + _SEHEnterFrame(&_SEHFrame.SEH_Header, &_SEHTryLevel.ST_Header); \ } \ - while(0); \ + else \ + _SEHEnterTry(&_SEHTryLevel.ST_Header); \
\ - _SEHLeave(&_SEHFrame->SEH_Header); \ - } \ - else \ - { \ - _SEHLeave(&_SEHFrame->SEH_Header); \ + { \ + static const int _SEHScopeKind = 0; \ + (void)_SEHScopeKind; \ + \ + if(_SEHSetJmp(_SEHTryLevel.ST_JmpBuf) == 0) \ + { \ + for(;;) \ + {
-#define _SEH_END \ +#define _SEHX_HANDLE \ + \ + break; \ + } \ + \ + _SEHLeave(); \ + } \ + else \ + { \ + _SEHLeave(); + +#define _SEHX_END \ + } \ + \ + if(_SEHHandlers.SH_Finally) \ + _SEHHandlers.SH_Finally(_SEHPortableFrame); \ + } \ } \ - \ - if(_SEHHandlers.SH_Finally) \ - _SEHHandlers.SH_Finally(&_SEHFrame->SEH_Header); \ }
-#define _SEH_LEAVE break +#define _SEHX_LEAVE break
-#define _SEH_GetExceptionCode() (unsigned long)(_SEHPortableFrame->SPF_Code) +#define _SEHX_GetExceptionCode() (unsigned long)(_SEHPortableFrame->SPF_Code)
-#define _SEH_GetExceptionPointers() \ +#define _SEHX_GetExceptionPointers() \ ((struct _EXCEPTION_POINTERS *)_SEHExceptionPointers)
-#define _SEH_AbnormalTermination() (_SEHPortableFrame->SPF_Code != 0) +#define _SEHX_AbnormalTermination() (_SEHPortableFrame->SPF_Code != 0)
/* New syntax */ -#define _SEH2_STATE_INIT_EXCEPT (1) -#define _SEH2_STATE_INIT_FINALLY (_SEH2_STATE_INIT_EXCEPT + 1) -#define _SEH2_STATE_BODY (_SEH2_STATE_INIT_FINALLY + 1) -#define _SEH2_STATE_HANDLER (_SEH2_STATE_BODY + 1) -#define _SEH2_STATE_DONE (_SEH2_STATE_HANDLER + 1)
-#define _SEH2_LEAVE { _SEH2State = _SEH2_STATE_DONE; break; } +/* + NOTE: do not move, remove or modify any instance of _SEH2_ASSUME and + _SEH2_ASSUMING without doing extensive tests for correctness. Compilers can + generate the wrong code in presence of __assume in unpredictable ways. BE SURE + IT DOESN'T HAPPEN +*/ +#if defined(_MSC_VER) && (_MSC_VER > 1200) +# define _SEH2_ASSUME(X_) __assume(X_) +# if !defined(_SEH_NO_NATIVE_NLG) + /* + If we use the native setjmp, the compiler stops keeping track of variables, so + their actual values don't matter anymore. Optimize out some assignments + */ +# define _SEH2_ASSUMING(X_) +# else + /* No native setjmp, no magic, no assumptions. Actually set the values */ +# define _SEH2_ASSUMING(X_) X_ +# endif +#else +# define _SEH2_ASSUME(X_) +# define _SEH2_ASSUMING(X_) X_ +#endif
-#define _SEH2_TRY \ -{ \ - int _SEH2State; \ - _SEHFilter_t _SEH2Filter; \ - _SEHFinally_t _SEH2Finally; \ +#ifdef __cplusplus +# define _SEH2_INIT_CONST static const +#else +# define _SEH2_INIT_CONST register const +#endif + +#define _SEH_LEAVE break + +#define _SEH_TRY \ + { \ + _SEH2_INIT_CONST int _SEH2TopTryLevel = (_SEHScopeKind != 0); \ + _SEHPortableFrame_t * const _SEH2CurPortableFrame = _SEHPortableFrame; \
\ - _SEHFrame_t * _SEHFrame; \ - volatile _SEHPortableFrame_t * _SEHPortableFrame; \ + { \ + static const int _SEHScopeKind = 0; \ + register int _SEH2State = 0; \ + register int _SEH2Handle = 0; \ + _SEHFrame_t _SEH2Frame; \ + _SEHTryLevel_t _SEH2TryLevel; \ + _SEHPortableFrame_t * const _SEHPortableFrame = \ + _SEH2TopTryLevel ? &_SEH2Frame.SEH_Header : _SEH2CurPortableFrame; \
\ - for(_SEH2State = 0; _SEH2State < _SEH2_STATE_DONE; ++ _SEH2State) \ - { \ - switch(_SEH2State) \ - { \ - case _SEH2_STATE_BODY: \ + (void)_SEHScopeKind; \ + (void)_SEHPortableFrame; \ + (void)_SEH2Handle; \ + \ + for(;;) \ { \ - _SEH_DECLARE_HANDLERS(_SEH2Filter, _SEH2Finally); \ + if(_SEH2State) \ + { \ + for(;;) \ + { \ + { + +#define _SEH_EXCEPT(FILTER_) \ + } \
\ - _SEHFrame = _alloca(sizeof(_SEHFrame_t)); \ - _SEHFrame->SEH_Header.SPF_Handlers = &_SEHHandlers; \ - _SEHFrame->SEH_Locals = &_SEHLocals; \ + break; \ + } \
\ - _SEHPortableFrame = &_SEHFrame->SEH_Header; \ - (void)_SEHPortableFrame; \ - \ - if(_SEHSetJmp(_SEHFrame->SEH_JmpBuf)) \ + _SEH2_ASSUME(_SEH2Handle == 0); \ break; \ + } \ + else \ + { \ + _SEH_DECLARE_HANDLERS((FILTER_), 0); \
\ - _SEHEnter(&_SEHFrame->SEH_Header); - -#define _SEH2_EXCEPT(FILTER_) \ - _SEHLeave(&_SEHFrame->SEH_Header); \ - _SEH2State = _SEH2_STATE_DONE; \ + _SEH2TryLevel.ST_Header.SPT_Handlers = &_SEHHandlers; \
\ - break; \ - } \ + if(_SEH2TopTryLevel) \ + { \ + if(&_SEHLocals != _SEHDummyLocals) \ + _SEH2Frame.SEH_Locals = &_SEHLocals; \
\ - case _SEH2_STATE_INIT_EXCEPT: \ - { \ - _SEH2Filter = (FILTER_); \ - break; \ - } \ + _SEH2Frame.SEH_Header.SPF_Handler = _SEHCompilerSpecificHandler; \ + _SEHEnterFrame(&_SEH2Frame.SEH_Header, &_SEH2TryLevel.ST_Header); \ + } \ + else \ + _SEHEnterTry(&_SEH2TryLevel.ST_Header); \
\ - case _SEH2_STATE_HANDLER: \ - { \ - _SEHLeave(&_SEHFrame->SEH_Header); - -#define _SEH2_FINALLY(FINALLY_) \ + if((_SEH2Handle = _SEHSetJmp(_SEH2TryLevel.ST_JmpBuf)) == 0) \ + { \ + _SEH2_ASSUMING(++ _SEH2State); \ + _SEH2_ASSUME(_SEH2State != 0); \ + continue; \ + } \ + else \ + { \ + break; \ + } \ + } \ + \ break; \ } \
\ - case _SEH2_STATE_INIT_FINALLY: \ - { \ - _SEH2Finally = (FINALLY_); + _SEHLeave(); \ + \ + if(_SEH2Handle) \ + {
-#define _SEH2_END \ - break; \ - } \ +#define _SEH_FINALLY(FINALLY_) \ + } \
\ - default: \ - { \ - switch(_SEH2State) \ + break; \ + } \ + \ + _SEHLeave(); \ + break; \ + } \ + else \ { \ - case _SEH2_STATE_INIT_EXCEPT: _SEH2Filter = NULL; break; \ - case _SEH2_STATE_INIT_FINALLY: _SEH2Finally = NULL; break; \ - case _SEH2_STATE_HANDLER: _SEHLeave(&_SEHFrame->SEH_Header); break; \ + _SEH_DECLARE_HANDLERS(0, (FINALLY_)); \ + \ + _SEH2TryLevel.ST_Header.SPT_Handlers = &_SEHHandlers; \ + \ + if(_SEH2TopTryLevel) \ + { \ + if(&_SEHLocals != _SEHDummyLocals) \ + _SEH2Frame.SEH_Locals = &_SEHLocals; \ + \ + _SEH2Frame.SEH_Header.SPF_Handler = 0; \ + _SEHEnterFrame(&_SEH2Frame.SEH_Header, &_SEH2TryLevel.ST_Header); \ + } \ + else \ + _SEHEnterTry(&_SEH2TryLevel.ST_Header); \ + \ + ++ _SEH2State; \ + _SEH2_ASSUME(_SEH2State != 0); \ + continue; \ } \
\ break; \ } \ - } \ - } \
\ - if(_SEHHandlers.SH_Finally) \ - _SEHHandlers.SH_Finally(&_SEHFrame->SEH_Header); \ -} + (FINALLY_)(&_SEH2Frame.SEH_Header); \ + if(0) \ + {
-#define _SEH2_HANDLE _SEH2_EXCEPT(_SEH_STATIC_FILTER(_SEH_EXECUTE_HANDLER)) +#define _SEH_END \ + } \ + } \ + }
-#define _SEH2_GetExceptionCode _SEH_GetExceptionCode -#define _SEH2_GetExceptionPointers _SEH_GetExceptionPointers -#define _SEH2_AbnormalTermination _SEH_AbnormalTermination +#define _SEH_HANDLE _SEH_EXCEPT(_SEH_STATIC_FILTER(_SEH_EXECUTE_HANDLER))
+#define _SEH_GetExceptionCode _SEHX_GetExceptionCode +#define _SEH_GetExceptionPointers _SEHX_GetExceptionPointers +#define _SEH_AbnormalTermination _SEHX_AbnormalTermination + #endif
/* EOF */ _____
Modified: trunk/reactos/include/pseh/native.h --- trunk/reactos/include/pseh/native.h 2005-05-06 21:18:20 UTC (rev 15062) +++ trunk/reactos/include/pseh/native.h 2005-05-06 22:25:30 UTC (rev 15063) @@ -111,7 +111,7 @@
/* FINALLY FUNCTIONS */ /* Declares a finally function's prototype */ -#define _SEH_FINALLY(NAME_) \ +#define _SEH_FINALLYFUNC(NAME_) \ void __stdcall NAME_ \ ( \ int _SEHAbnormalTermination, \ @@ -123,13 +123,13 @@ _SEH_WRAP_FINALLY_ARGS(WRAPPER_, NAME_, ())
#define _SEH_WRAP_FINALLY_ARGS(WRAPPER_, NAME_, ARGS_) \ - static __inline _SEH_FINALLY(WRAPPER_) \ + static __inline _SEH_FINALLYFUNC(WRAPPER_) \ { \ NAME_ ARGS_; \ }
#define _SEH_WRAP_FINALLY_LOCALS_ARGS(WRAPPER_, LOCALS_, NAME_, ARGS_) \ - static __inline _SEH_FINALLY(WRAPPER_) \ + static __inline _SEH_FINALLYFUNC(WRAPPER_) \ { \ _SEH_ACCESS_LOCALS(LOCALS_); \ NAME_ ARGS_; \ _____
Modified: trunk/reactos/include/pseh/setjmp.h --- trunk/reactos/include/pseh/setjmp.h 2005-05-06 21:18:20 UTC (rev 15062) +++ trunk/reactos/include/pseh/setjmp.h 2005-05-06 22:25:30 UTC (rev 15063) @@ -36,10 +36,19 @@
_SEHJmpBuf_t[1]; #endif
+#ifdef __cplusplus +extern "C" +{ +#endif + extern __declspec(noreturn) void __stdcall _SEHLongJmp(_SEHJmpBuf_t, int); extern __declspec(noreturn) void __stdcall _SEHLongJmp_KeepEsp(_SEHJmpBuf_t, int); extern int __stdcall _SEHSetJmp(_SEHJmpBuf_t);
+#ifdef __cplusplus +} #endif
+#endif + /* EOF */ _____
Modified: trunk/reactos/include/pseh.h --- trunk/reactos/include/pseh.h 2005-05-06 21:18:20 UTC (rev 15062) +++ trunk/reactos/include/pseh.h 2005-05-06 22:25:30 UTC (rev 15063) @@ -51,6 +51,16 @@
# define _SEH_CONCAT(X_, Y_) _SEH_CONCAT1(X_, Y_) #endif
+/* + Note: just define __inline to an empty symbol if your C compiler doesn't + support it +*/ +#ifdef __cplusplus +# ifndef __inline +# define __inline inline +# endif +#endif + /* Locals sharing support */ #define _SEH_LOCALS_TYPENAME(BASENAME_) \ struct _SEH_CONCAT(_SEHLocalsTag, BASENAME_) @@ -64,8 +74,8 @@ _SEHPLocals = &_SEHLocals;
/* Dummy locals */ -static _SEH_LOCALS_TYPENAME(_SEHDummyLocals) { int Dummy_; } _SEHLocals; -static void __inline _SEHDummyLocalsUser(void) { (void)_SEHLocals; } +static int _SEHLocals; +static void * const _SEHDummyLocals = &_SEHLocals;
#include <pseh/framebased.h>
_____
Modified: trunk/reactos/lib/dbghelp/msc.c --- trunk/reactos/lib/dbghelp/msc.c 2005-05-06 21:18:20 UTC (rev 15062) +++ trunk/reactos/lib/dbghelp/msc.c 2005-05-06 22:25:30 UTC (rev 15063) @@ -2259,7 +2259,7 @@
msc_dbg.nomap = 0; msc_dbg.omapp = NULL;
- _SEH_TRY_FILTER(page_fault) + _SEH_TRY { ret = FALSE;
@@ -2324,7 +2324,7 @@ #endif
} - _SEH_HANDLE + _SEH_EXCEPT(page_fault) { ERR("Got a page fault while loading symbols\n"); ret = FALSE; _____
Modified: trunk/reactos/lib/kernel32/k32.h --- trunk/reactos/lib/kernel32/k32.h 2005-05-06 21:18:20 UTC (rev 15062) +++ trunk/reactos/lib/kernel32/k32.h 2005-05-06 22:25:30 UTC (rev 15063) @@ -6,6 +6,7 @@
#include <ctype.h> #include <stdarg.h> #include <stdio.h> +#include <malloc.h> #include <limits.h> #include <wchar.h> #include <string.h> _____
Modified: trunk/reactos/lib/pseh/framebased.c --- trunk/reactos/lib/pseh/framebased.c 2005-05-06 21:18:20 UTC (rev 15062) +++ trunk/reactos/lib/pseh/framebased.c 2005-05-06 22:25:30 UTC (rev 15063) @@ -24,28 +24,64 @@
#define WIN32_LEAN_AND_MEAN #include <windows.h>
+#include <pseh.h> #include <pseh/framebased/internal.h> #include <pseh/excpt.h> -#include <excpt.h> #include <pseh/framebased.h>
+#include <excpt.h> + /* Assembly helpers, see i386/framebased.asm */ extern void __cdecl _SEHCleanHandlerEnvironment(void); -extern void __cdecl _SEHRegisterFrame(_SEHRegistration_t *); -extern void __cdecl _SEHUnregisterFrame(const _SEHRegistration_t *); -extern void __cdecl _SEHUnwind(_SEHPortableFrame_t *); +extern struct __SEHRegistration * __cdecl _SEHRegisterFrame(_SEHRegistration_t *); +extern void __cdecl _SEHUnregisterFrame(void); +extern void __cdecl _SEHGlobalUnwind(_SEHPortableFrame_t *); +extern _SEHRegistration_t * __cdecl _SEHCurrentRegistration(void);
/* Borland C++ uses a different decoration (i.e. none) for stdcall functions */ extern void __stdcall RtlUnwind(void *, void *, void *, void *); void const * _SEHRtlUnwind = RtlUnwind;
-__declspec(noreturn) void __cdecl _SEHCallHandler(_SEHPortableFrame_t * frame) +void __stdcall _SEHLocalUnwind +( + _SEHPortableFrame_t * frame, + _SEHPortableTryLevel_t * dsttrylevel +) { - frame->SPF_Handling = 1; - _SEHUnwind(frame); - frame->SPF_Handlers->SH_Handler(frame); + _SEHPortableTryLevel_t * trylevel; + + for + ( + trylevel = frame->SPF_TopTryLevel; + trylevel != dsttrylevel; + trylevel = trylevel->SPT_Next + ) + { + _SEHFinally_t pfnFinally; + + /* ASSERT(trylevel); */ + + pfnFinally = trylevel->SPT_Handlers->SH_Finally; + + if(pfnFinally) + pfnFinally(frame); + } }
+__declspec(noreturn) void __cdecl _SEHCallHandler +( + _SEHPortableFrame_t * frame, + _SEHPortableTryLevel_t * trylevel +) +{ + DbgPrint("_SEHCallHandler: REG %p\n", _SEHCurrentRegistration()); + _SEHGlobalUnwind(frame); + DbgPrint("_SEHCallHandler: REG %p\n", _SEHCurrentRegistration()); + _SEHLocalUnwind(frame, trylevel); + DbgPrint("_SEHCallHandler: REG %p\n", _SEHCurrentRegistration()); + frame->SPF_Handler(trylevel); +} + int __cdecl _SEHFrameHandler ( struct _EXCEPTION_RECORD * ExceptionRecord, @@ -62,73 +98,143 @@
/* Unwinding */ if(ExceptionRecord->ExceptionFlags & (4 | 2)) - { - if(frame->SPF_Handlers->SH_Finally && !frame->SPF_Handling) - frame->SPF_Handlers->SH_Finally(frame); - } + _SEHLocalUnwind(frame, NULL); /* Handling */ else { int ret; + _SEHPortableTryLevel_t * trylevel;
if(ExceptionRecord->ExceptionCode) frame->SPF_Code = ExceptionRecord->ExceptionCode; else - frame->SPF_Code = 0xC0000001; + frame->SPF_Code = 0xC0000001;
- switch((UINT_PTR)frame->SPF_Handlers->SH_Filter) + for + ( + trylevel = frame->SPF_TopTryLevel; + trylevel != NULL; + trylevel = trylevel->SPT_Next + ) { - case (UINT_PTR)_SEH_STATIC_FILTER(_SEH_EXECUTE_HANDLER): - case (UINT_PTR)_SEH_STATIC_FILTER(_SEH_CONTINUE_SEARCH): - case (UINT_PTR)_SEH_STATIC_FILTER(_SEH_CONTINUE_EXECUTION): - { - ret = (int)((UINT_PTR)frame->SPF_Handlers->SH_Filter) - 2; - break; - } + _SEHFilter_t pfnFilter = trylevel->SPT_Handlers->SH_Filter;
- default: + switch((UINT_PTR)pfnFilter) { - if(frame->SPF_Handlers->SH_Filter) + case (UINT_PTR)_SEH_STATIC_FILTER(_SEH_EXECUTE_HANDLER): + case (UINT_PTR)_SEH_STATIC_FILTER(_SEH_CONTINUE_SEARCH): + case (UINT_PTR)_SEH_STATIC_FILTER(_SEH_CONTINUE_EXECUTION): { - EXCEPTION_POINTERS ep; - - ep.ExceptionRecord = ExceptionRecord; - ep.ContextRecord = ContextRecord; - - ret = frame->SPF_Handlers->SH_Filter(&ep, frame); + ret = (int)((UINT_PTR)pfnFilter) - 2; + break; } - else - ret = _SEH_CONTINUE_SEARCH;
- break; + default: + { + if(trylevel->SPT_Handlers->SH_Filter) + { + EXCEPTION_POINTERS ep; + + ep.ExceptionRecord = ExceptionRecord; + ep.ContextRecord = ContextRecord; + + ret = pfnFilter(&ep, frame); + } + else + ret = _SEH_CONTINUE_SEARCH; + + break; + } } + + /* _SEH_CONTINUE_EXECUTION */ + if(ret < 0) + return ExceptionContinueExecution; + /* _SEH_EXECUTE_HANDLER */ + else if(ret > 0) + _SEHCallHandler(frame, trylevel); + /* _SEH_CONTINUE_SEARCH */ + else + continue; }
- /* _SEH_CONTINUE_EXECUTION */ - if(ret < 0) - return ExceptionContinueExecution; - /* _SEH_EXECUTE_HANDLER */ - else if(ret > 0) - _SEHCallHandler(frame); - /* _SEH_CONTINUE_SEARCH */ - else - /* fall through */; + /* FALLTHROUGH */ }
return ExceptionContinueSearch; }
-void __stdcall _SEHEnter(_SEHPortableFrame_t * frame) +void __stdcall _SEHEnterFrame_s +( + _SEHPortableFrame_t * frame, + _SEHPortableTryLevel_t * trylevel +) { + _SEHEnterFrame_f(frame, trylevel); +} + +void __stdcall _SEHEnterTry_s(_SEHPortableTryLevel_t * trylevel) +{ + _SEHEnterTry_f(trylevel); +} + +void __stdcall _SEHLeave_s(void) +{ + _SEHLeave_f(); +} + +void _SEH_FASTCALL _SEHEnterFrame_f +( + _SEHPortableFrame_t * frame, + _SEHPortableTryLevel_t * trylevel +) +{ + /* ASSERT(frame); */ + /* ASSERT(trylevel); */ frame->SPF_Registration.SER_Handler = _SEHFrameHandler; frame->SPF_Code = 0; - frame->SPF_Handling = 0; + frame->SPF_TopTryLevel = trylevel; + trylevel->SPT_Next = NULL; _SEHRegisterFrame(&frame->SPF_Registration); }
-void __stdcall _SEHLeave(_SEHPortableFrame_t * frame) +void _SEH_FASTCALL _SEHEnterTry_f(_SEHPortableTryLevel_t * trylevel) { - _SEHUnregisterFrame(&frame->SPF_Registration); + _SEHPortableFrame_t * frame; + + frame = _SEH_CONTAINING_RECORD + ( + _SEHCurrentRegistration(), + _SEHPortableFrame_t, + SPF_Registration + ); + + trylevel->SPT_Next = frame->SPF_TopTryLevel; + frame->SPF_TopTryLevel = trylevel; }
+void _SEH_FASTCALL _SEHLeave_f(void) +{ + _SEHPortableFrame_t * frame; + _SEHPortableTryLevel_t * trylevel; + + frame = _SEH_CONTAINING_RECORD + ( + _SEHCurrentRegistration(), + _SEHPortableFrame_t, + SPF_Registration + ); + + /* ASSERT(frame); */ + + trylevel = frame->SPF_TopTryLevel; + + /* ASSERT(trylevel); */ + + if(trylevel->SPT_Next) + frame->SPF_TopTryLevel = trylevel->SPT_Next; + else + _SEHUnregisterFrame(); +} + /* EOF */ _____
Modified: trunk/reactos/lib/pseh/i386/framebased.asm --- trunk/reactos/lib/pseh/i386/framebased.asm 2005-05-06 21:18:20 UTC (rev 15062) +++ trunk/reactos/lib/pseh/i386/framebased.asm 2005-05-06 22:25:30 UTC (rev 15063) @@ -1,4 +1,4 @@
-; Copyright (c) 2004 KJK::Hyperion +; Copyright (c) 2004/2005 KJK::Hyperion
; Permission is hereby granted, free of charge, to any person obtaining a copy ; of this software and associated documentation files (the "Software"), to deal @@ -25,6 +25,11 @@ cld ret
+global __SEHCurrentRegistration +__SEHCurrentRegistration: + mov eax, [fs:0] + ret + global __SEHRegisterFrame __SEHRegisterFrame: mov ecx, [esp+4] @@ -35,33 +40,32 @@
global __SEHUnregisterFrame __SEHUnregisterFrame: - mov ecx, [esp+4] - mov ecx, [ecx] + mov ecx, [fs:0] + mov ecx, [ecx+0] mov [fs:0], ecx ret
-global __SEHUnwind -__SEHUnwind: +global __SEHGlobalUnwind +__SEHGlobalUnwind:
extern __SEHRtlUnwind
- mov ecx, [esp+4] - ; RtlUnwind clobbers all the "don't clobber" registers, so we save them + push ebx + mov ebx, [esp+8] push esi push edi - push ebx
- xor eax, eax - push eax ; ReturnValue - push eax ; ExceptionRecord - push eax ; TargetIp - push ecx ; TargetFrame [truncated at 1000 lines; 682 more skipped]