Module: wine Branch: master Commit: 0ee44f5e203fb627392ac2ad03cf822d66da2037 URL: http://source.winehq.org/git/wine.git/?a=commit;h=0ee44f5e203fb627392ac2ad03...
Author: Alexandre Julliard julliard@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 */