[ros-diffs] [gdalsnes] 12903: experimental/useless "pretty seh"

gdalsnes at svn.reactos.com gdalsnes at svn.reactos.com
Sun Jan 9 05:40:03 CET 2005


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 at 8
+SEHLongJmp_KeepEsp:
+__SEHLongJmp_KeepEsp at 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
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://www.reactos.org/pipermail/ros-diffs/attachments/20050109/0dc495e4/attachment.html


More information about the Ros-diffs mailing list