Alexandre Julliard : ntdll: Make the exception handling functions inline.

Alexandre Julliard julliard at winehq.org
Thu May 1 06:38:45 CDT 2008


Module: wine
Branch: master
Commit: 0ee44f5e203fb627392ac2ad03cf822d66da2037
URL:    http://source.winehq.org/git/wine.git/?a=commit;h=0ee44f5e203fb627392ac2ad03cf822d66da2037

Author: Alexandre Julliard <julliard at winehq.org>
Date:   Thu May  1 10:57:54 2008 +0200

ntdll: Make the exception handling functions inline.

---

 dlls/ntdll/exception.c   |   63 -------------------------
 dlls/ntdll/ntdll.spec    |    4 --
 include/wine/exception.h |  113 +++++++++++++++++++++++++++++++++++++++++----
 3 files changed, 103 insertions(+), 77 deletions(-)

diff --git a/dlls/ntdll/exception.c b/dlls/ntdll/exception.c
index c039dd4..8aa906e 100644
--- a/dlls/ntdll/exception.c
+++ b/dlls/ntdll/exception.c
@@ -565,69 +565,6 @@ ULONG WINAPI RtlRemoveVectoredExceptionHandler( PVOID handler )
 
 
 /*************************************************************
- *            __wine_exception_handler (NTDLL.@)
- *
- * Exception handler for exception blocks declared in Wine code.
- */
-DWORD __wine_exception_handler( EXCEPTION_RECORD *record, EXCEPTION_REGISTRATION_RECORD *frame,
-                                CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **pdispatcher )
-{
-    __WINE_FRAME *wine_frame = (__WINE_FRAME *)frame;
-
-    if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND | EH_NESTED_CALL))
-        return ExceptionContinueSearch;
-
-    if (wine_frame->u.filter == (void *)1)  /* special hack for page faults */
-    {
-        if (record->ExceptionCode != STATUS_ACCESS_VIOLATION)
-            return ExceptionContinueSearch;
-    }
-    else if (wine_frame->u.filter)
-    {
-        EXCEPTION_POINTERS ptrs;
-        ptrs.ExceptionRecord = record;
-        ptrs.ContextRecord = context;
-        switch(wine_frame->u.filter( &ptrs ))
-        {
-        case EXCEPTION_CONTINUE_SEARCH:
-            return ExceptionContinueSearch;
-        case EXCEPTION_CONTINUE_EXECUTION:
-            return ExceptionContinueExecution;
-        case EXCEPTION_EXECUTE_HANDLER:
-            break;
-        default:
-            MESSAGE( "Invalid return value from exception filter\n" );
-            assert( FALSE );
-        }
-    }
-    /* hack to make GetExceptionCode() work in handler */
-    wine_frame->ExceptionCode   = record->ExceptionCode;
-    wine_frame->ExceptionRecord = wine_frame;
-
-    RtlUnwind( frame, 0, record, 0 );
-    __wine_pop_frame( frame );
-    siglongjmp( wine_frame->jmp, 1 );
-}
-
-
-/*************************************************************
- *            __wine_finally_handler (NTDLL.@)
- *
- * Exception handler for try/finally blocks declared in Wine code.
- */
-DWORD __wine_finally_handler( EXCEPTION_RECORD *record, EXCEPTION_REGISTRATION_RECORD *frame,
-                              CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **pdispatcher )
-{
-    if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
-    {
-        __WINE_FRAME *wine_frame = (__WINE_FRAME *)frame;
-        wine_frame->u.finally_func( FALSE );
-    }
-    return ExceptionContinueSearch;
-}
-
-
-/*************************************************************
  *            __wine_spec_unimplemented_stub
  *
  * ntdll-specific implementation to avoid depending on kernel functions.
diff --git a/dlls/ntdll/ntdll.spec b/dlls/ntdll/ntdll.spec
index 23ee968..ed89cbd 100644
--- a/dlls/ntdll/ntdll.spec
+++ b/dlls/ntdll/ntdll.spec
@@ -1366,10 +1366,6 @@
 # All functions must be prefixed with '__wine_' (for internal functions)
 # or 'wine_' (for user-visible functions) to avoid namespace conflicts.
 
-# Exception handling
-@ cdecl -norelay __wine_exception_handler(ptr ptr ptr ptr)
-@ cdecl -norelay __wine_finally_handler(ptr ptr ptr ptr)
-
 # Relays
 @ cdecl -norelay -i386 __wine_call_from_32_regs()
 @ cdecl -i386 __wine_enter_vm86(ptr)
diff --git a/include/wine/exception.h b/include/wine/exception.h
index fc90364..1dce217 100644
--- a/include/wine/exception.h
+++ b/include/wine/exception.h
@@ -23,6 +23,7 @@
 
 #include <setjmp.h>
 #include <windef.h>
+#include <winternl.h>
 #include <excpt.h>
 
 /* The following definitions allow using exceptions in Wine and Winelib code
@@ -100,6 +101,30 @@
                  const __WINE_FRAME * const __eptr __attribute__((unused)) = &__f; \
                  do {
 
+/* convenience handler for page fault exceptions */
+#define __EXCEPT_PAGE_FAULT \
+             } while(0); \
+             __wine_pop_frame( &__f.frame ); \
+             break; \
+         } else { \
+             __f.frame.Handler = __wine_exception_handler_page_fault; \
+             __wine_push_frame( &__f.frame ); \
+             if (sigsetjmp( __f.jmp, 0 )) { \
+                 const __WINE_FRAME * const __eptr __attribute__((unused)) = &__f; \
+                 do {
+
+/* convenience handler for all exception */
+#define __EXCEPT_ALL \
+             } while(0); \
+             __wine_pop_frame( &__f.frame ); \
+             break; \
+         } else { \
+             __f.frame.Handler = __wine_exception_handler_all; \
+             __wine_push_frame( &__f.frame ); \
+             if (sigsetjmp( __f.jmp, 0 )) { \
+                 const __WINE_FRAME * const __eptr __attribute__((unused)) = &__f; \
+                 do {
+
 #define __ENDTRY \
                  } while (0); \
                  break; \
@@ -125,11 +150,6 @@
 typedef LONG (CALLBACK *__WINE_FILTER)(PEXCEPTION_POINTERS);
 typedef void (CALLBACK *__WINE_FINALLY)(BOOL);
 
-/* convenience handler for page fault exceptions */
-#define __EXCEPT_PAGE_FAULT __EXCEPT( (__WINE_FILTER)1 )
-/* convenience handler for all exception */
-#define __EXCEPT_ALL __EXCEPT( NULL )
-
 #define GetExceptionInformation() (__eptr)
 #define GetExceptionCode()        (__eptr->ExceptionRecord->ExceptionCode)
 #define AbnormalTermination()     (!__normal)
@@ -150,11 +170,6 @@ typedef struct __tagWINE_FRAME
     const struct __tagWINE_FRAME *ExceptionRecord;
 } __WINE_FRAME;
 
-extern DWORD __wine_exception_handler( PEXCEPTION_RECORD record, EXCEPTION_REGISTRATION_RECORD *frame,
-                                       CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **pdispatcher );
-extern DWORD __wine_finally_handler( PEXCEPTION_RECORD record, EXCEPTION_REGISTRATION_RECORD *frame,
-                                     CONTEXT *context, EXCEPTION_REGISTRATION_RECORD **pdispatcher );
-
 #endif /* USE_COMPILER_EXCEPTIONS */
 
 static inline EXCEPTION_REGISTRATION_RECORD *__wine_push_frame( EXCEPTION_REGISTRATION_RECORD *frame )
@@ -209,4 +224,82 @@ static inline EXCEPTION_REGISTRATION_RECORD *__wine_pop_frame( EXCEPTION_REGISTR
 
 extern void __wine_enter_vm86( CONTEXT *context );
 
+#ifndef USE_COMPILER_EXCEPTIONS
+
+static inline void DECLSPEC_NORETURN __wine_unwind_frame( EXCEPTION_RECORD *record,
+                                                          EXCEPTION_REGISTRATION_RECORD *frame )
+{
+    __WINE_FRAME *wine_frame = (__WINE_FRAME *)frame;
+
+    /* hack to make GetExceptionCode() work in handler */
+    wine_frame->ExceptionCode   = record->ExceptionCode;
+    wine_frame->ExceptionRecord = wine_frame;
+
+    RtlUnwind( frame, 0, record, 0 );
+    __wine_pop_frame( frame );
+    siglongjmp( wine_frame->jmp, 1 );
+}
+
+static inline DWORD __wine_exception_handler( EXCEPTION_RECORD *record,
+                                              EXCEPTION_REGISTRATION_RECORD *frame,
+                                              CONTEXT *context,
+                                              EXCEPTION_REGISTRATION_RECORD **pdispatcher )
+{
+    __WINE_FRAME *wine_frame = (__WINE_FRAME *)frame;
+    EXCEPTION_POINTERS ptrs;
+
+    if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND | EH_NESTED_CALL))
+        return ExceptionContinueSearch;
+
+    ptrs.ExceptionRecord = record;
+    ptrs.ContextRecord = context;
+    switch(wine_frame->u.filter( &ptrs ))
+    {
+    case EXCEPTION_CONTINUE_SEARCH:
+        return ExceptionContinueSearch;
+    case EXCEPTION_CONTINUE_EXECUTION:
+        return ExceptionContinueExecution;
+    case EXCEPTION_EXECUTE_HANDLER:
+        break;
+    }
+    __wine_unwind_frame( record, frame );
+}
+
+static inline DWORD __wine_exception_handler_page_fault( EXCEPTION_RECORD *record,
+                                                         EXCEPTION_REGISTRATION_RECORD *frame,
+                                                         CONTEXT *context,
+                                                         EXCEPTION_REGISTRATION_RECORD **pdispatcher )
+{
+    if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND | EH_NESTED_CALL))
+        return ExceptionContinueSearch;
+    if (record->ExceptionCode != STATUS_ACCESS_VIOLATION)
+        return ExceptionContinueSearch;
+    __wine_unwind_frame( record, frame );
+}
+
+static inline DWORD __wine_exception_handler_all( EXCEPTION_RECORD *record,
+                                                  EXCEPTION_REGISTRATION_RECORD *frame,
+                                                  CONTEXT *context,
+                                                  EXCEPTION_REGISTRATION_RECORD **pdispatcher )
+{
+    if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND | EH_NESTED_CALL))
+        return ExceptionContinueSearch;
+    __wine_unwind_frame( record, frame );
+}
+
+static inline DWORD __wine_finally_handler( EXCEPTION_RECORD *record,
+                                            EXCEPTION_REGISTRATION_RECORD *frame,
+                                            CONTEXT *context,
+                                            EXCEPTION_REGISTRATION_RECORD **pdispatcher )
+{
+    if (record->ExceptionFlags & (EH_UNWINDING | EH_EXIT_UNWIND))
+    {
+        __WINE_FRAME *wine_frame = (__WINE_FRAME *)frame;
+        wine_frame->u.finally_func( FALSE );
+    }
+    return ExceptionContinueSearch;
+}
+
+#endif /* USE_COMPILER_EXCEPTIONS */
+
 #endif  /* __WINE_WINE_EXCEPTION_H */




More information about the wine-cvs mailing list