experimental/useless "pretty seh"
Added: trunk/reactos/include/pseh/prettybased.h
Modified: trunk/reactos/include/pseh/setjmp.h
Modified: trunk/reactos/lib/pseh/i386/setjmp.asm
_____
Added: trunk/reactos/include/pseh/prettybased.h
--- trunk/reactos/include/pseh/prettybased.h 2005-01-09 03:43:26 UTC
(rev 12902)
+++ trunk/reactos/include/pseh/prettybased.h 2005-01-09 04:40:01 UTC
(rev 12903)
@@ -0,0 +1,323 @@
+/*
+ Copyright (c) 2004 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 in
+ the Software without restriction, including without limitation the
rights to
+ use, copy, modify, merge, publish, distribute, sublicense, and/or sell
copies
+ of the Software, and to permit persons to whom the Software is
furnished to do
+ so, subject to the following conditions:
+
+ The above copyright notice and this permission notice shall be
included in all
+ copies or substantial portions of the Software.
+
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
EXPRESS OR
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
MERCHANTABILITY,
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT
SHALL THE
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE,
ARISING FROM,
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS
IN THE
+ SOFTWARE.
+*/
+/*
+Pretty PSEH
+
+Made to be macro compatible with ms seh syntax and to be pretty, having
the
+finally block inline etc. Being pretty is not cheap. PPSEH has more
+overhead than PSEH, thou mostly during exception/unwinding. Normal
execution
+only add the overhead of one setjmp, and only in the try/finally case.
+PPSEH is probably much less portable than PSEH also.....
+
+ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!ALERT!ALERT
!ALERT!
+-must always use non-native NLG cause a special version of longjmp
(which doesn't
+restore esp) is needed
+
+-compiler must use ebp as stack frame pointer, cause the finally block
rely
+on this to access external variables
+
+-all external variables that are used in the except/finally block MUST
be volatile
+to prevent variables from being optimized into registers.
+See:
http://alphalinux.org/archives/axp-list/1998/February1998/0330.html
+
+
+
+USAGE:
+
+__TRY{
+ __LEAVE;
+}
+__EXCEPT(_SEH_STATIC_FILTER(EXCEPTION_EXECUTE_HANDLER)){
+}
+__ENDTRY;
+
+
+__TRY{
+}
+__FINALLY{
+}
+__ENDTRY;
+
+
+_SEH_FILTER(filter){
+ return EXCEPTION_EXECUTE_HANDLER;
+}
+__TRY2{
+}
+__EXCEPT2(filter){
+}
+__FINALLY2{
+}
+__ENDTRY2;
+
+
+
+-Gunnar
+
+*/
+
+
+#ifndef KJK_PPSEH_FRAMEBASED_H_
+#define KJK_PPSEH_FRAMEBASED_H_
+
+#include <pseh/framebased/internal.h>
+#include <pseh/excpt.h>
+#include <malloc.h>
+
+#ifndef offsetof
+# include <stddef.h>
+#endif
+
+/*
+Must always use non-native NLG since we need a special version of
longjmp which does
+not restore esp
+*/
+#include <pseh/setjmp.h>
+
+
+typedef struct __SEHFrame
+{
+ _SEHPortableFrame_t SEH_Header;
+ _SEHJmpBuf_t SEH_JmpBuf;
+/* alternative: _SEHJmpBuf_t* SEH_JmpRetPtr; */
+}
+_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
+
+
+/* FILTER FUNCTIONS */
+/* Declares a filter function's prototype */
+#define _SEH_FILTER(NAME_) \
+ long __stdcall NAME_ \
+ ( \
+ struct _EXCEPTION_POINTERS * _SEHExceptionPointers, \
+ struct __SEHPortableFrame * _SEHPortableFrame \
+ )
+
+
+/* Declares a static filter */
+#define _SEH_STATIC_FILTER(ACTION_) ((_SEHFilter_t)((ACTION_) + 2))
+
+
+static __declspec(noreturn) __inline void __stdcall
_SEHCompilerSpecificHandler
+(
+ _SEHPortableFrame_t * frame
+)
+{
+ _SEHFrame_t * myframe;
+ myframe = (_SEHFrame_t *)(((char *)frame) - offsetof(_SEHFrame_t,
SEH_Header));
+ _SEHLongJmp(myframe->SEH_JmpBuf, 1);
+}
+
+
+
+void __stdcall _FinallyPretty
+(
+ struct __SEHPortableFrame * frame
+)
+{
+ _SEHFrame_t * myframe;
+ _SEHJmpBuf_t jmpRetBuf;
+
+ myframe = (_SEHFrame_t *)(((char *)frame) - offsetof(_SEHFrame_t,
SEH_Header));
+
+ if(_SEHSetJmp(jmpRetBuf) == 0)
+ {
+ _SEHLongJmp_KeepEsp(myframe->SEH_JmpBuf, (int)&jmpRetBuf);
+
+ /* alternative:
+ myframe->SEH_JmpRetPtr = &jmpRetBuf;
+ _SEHLongJmp_KeepEsp(myframe->SEH_JmpBuf, 2);
+ */
+ }
+}
+
+
+
+#define ___EXCEPT_DUAL(filter)
\
+ } while(0);
\
+
\
+ _SEHLeave(&_SEHFrame->SEH_Header);
\
+
\
+ if (!_SEHHandlers.SH_Finally) break;
\
+ _loop ++;
\
+ }
\
+ else
\
+ {
\
+ _SEHHandlers.SH_Filter = (filter);
\
+ _SEHHandlers.SH_Finally = _FinallyPretty;
\
+
\
+ if(_loop == 2 || (_ret = _SEHSetJmp(_SEHFrame->SEH_JmpBuf)))
\
+ {
\
+ if (_ret == 1)
\
+ {
\
+ _SEHLeave(&_SEHFrame->SEH_Header);
\
+ do
\
+ {
+
+
+
+#define ___FINALLY_DUAL
\
+ } while (0);
\
+ }
\
+
\
+ do
\
+ {
+
+
+
+#define ___END_DUAL
\
+
\
+ } while (0);
\
+
\
+ if (_ret > 1)
\
+ {
\
+ _SEHLongJmp(*((_SEHJmpBuf_t*)_ret), 1);
\
+ /* alternative: _SEHLongJmp(*_SEHFrame->SEH_JmpRetPtr,
1); */ \
+ }
\
+ break;
\
+ }
\
+ _loop ++;
\
+ }
\
+
\
+ } while (0);
+
+
+
+
+
+#define ___EXCEPT_SINGLE(filter)
\
+ } while(0);
\
+
\
+ _SEHLeave(&_SEHFrame->SEH_Header);
\
+ break;
\
+ }
\
+ else
\
+ {
\
+ _SEHHandlers.SH_Filter = (filter);
\
+ _SEHHandlers.SH_Finally = (NULL);
\
+
\
+ if(_SEHSetJmp(_SEHFrame->SEH_JmpBuf))
\
+ {
\
+ _SEHLeave(&_SEHFrame->SEH_Header);
\
+ do
\
+ {
+
+
+
+#define ___TRY
\
+ do
\
+ {
\
+ int _loop =0; int _ret = 0;
\
+ static _SEHHandlers_t _SEHHandlers =
\
+ {
\
+ (NULL),
\
+ _SEHCompilerSpecificHandler,
\
+ (NULL)
\
+ };
\
+
\
+ _SEHFrame_t * _SEHFrame;
\
+ volatile _SEHPortableFrame_t * _SEHPortableFrame;
\
+
\
+ _SEHFrame = _alloca(sizeof(_SEHFrame_t));
\
+ _SEHFrame->SEH_Header.SPF_Handlers = &_SEHHandlers;
\
+
\
+ _SEHPortableFrame = &_SEHFrame->SEH_Header;
\
+ (void)_SEHPortableFrame;
\
+
\
+ for(;;)
\
+ if (_loop == 1)
\
+ {
\
+ _SEHEnter(&_SEHFrame->SEH_Header);
\
+
\
+ do
\
+ {
+
+
+#define ___FINALLY_SINGLE
\
+ } while(0);
\
+
\
+ _SEHLeave(&_SEHFrame->SEH_Header);
\
+ _loop ++;
\
+ }
\
+ else
\
+ {
\
+ _SEHHandlers.SH_Filter =
_SEH_STATIC_FILTER(_SEH_CONTINUE_SEARCH); \
+ _SEHHandlers.SH_Finally = _FinallyPretty;
\
+
\
+ if(_loop == 2 || (_ret = _SEHSetJmp(_SEHFrame->SEH_JmpBuf)))
\
+ {
\
+ do
\
+ {
+
+
+
+#define ___END_SINGLE
\
+ } while (0);
\
+
\
+ if (_ret > 1)
\
+ {
\
+ _SEHLongJmp(*((_SEHJmpBuf_t*)_ret), 1);
\
+ /* alternative: _SEHLongJmp(*_SEHFrame->SEH_JmpRetPtr,
1); */ \
+ }
\
+ break;
\
+ }
\
+ _loop ++;
\
+ }
\
+ } while (0);
+
+
+
+#ifdef _MSC_VER
+ #define __TRY2 __try{__try
+ #define __EXCEPT2 __except
+ #define __FINALLY2 }__finally
+ #define __ENDTRY2
+ #define __TRY __try
+ #define __EXCEPT __except
+ #define __FINALLY __finally
+ #define __ENDTRY
+ #define _SEH_STATIC_FILTER(ACTION_) (ACTION_)
+ #define __LEAVE __leave
+#else
+ #define __TRY2 ___TRY
+ #define __EXCEPT2 ___EXCEPT_DUAL
+ #define __FINALLY2 ___FINALLY_DUAL
+ #define __ENDTRY2 ___END_DUAL
+ #define __TRY ___TRY
+ #define __EXCEPT ___EXCEPT_SINGLE
+ #define __FINALLY ___FINALLY_SINGLE
+ #define __ENDTRY ___END_SINGLE
+ #define __LEAVE break
+#endif
+
+
+#endif
_____
Modified: trunk/reactos/include/pseh/setjmp.h
--- trunk/reactos/include/pseh/setjmp.h 2005-01-09 03:43:26 UTC (rev
12902)
+++ trunk/reactos/include/pseh/setjmp.h 2005-01-09 04:40:01 UTC (rev
12903)
@@ -37,6 +37,7 @@
#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);
#endif
_____
Modified: trunk/reactos/lib/pseh/i386/setjmp.asm
--- trunk/reactos/lib/pseh/i386/setjmp.asm 2005-01-09 03:43:26 UTC
(rev 12902)
+++ trunk/reactos/lib/pseh/i386/setjmp.asm 2005-01-09 04:40:01 UTC
(rev 12903)
@@ -65,4 +65,25 @@
mov edi, [ecx+20]
jmp edx
+
+global SEHLongJmp_KeepEsp
+global __SEHLongJmp_KeepEsp@8
+SEHLongJmp_KeepEsp:
+__SEHLongJmp_KeepEsp@8:
+ ; return value
+ mov eax, [esp+8]
+
+ ; jump buffer
+ mov ecx, [esp+4]
+
+ ; restore the saved context
+ mov ebp, [ecx+0]
+; don't restore esp
+; mov esp, [ecx+4]
+ mov edx, [ecx+8]
+ mov ebx, [ecx+12]
+ mov esi, [ecx+16]
+ mov edi, [ecx+20]
+ jmp edx
+
; EOF