From b938bfc00145ba6dd39b913d74bfa746358e1baa Mon Sep 17 00:00:00 2001 From: Timo Kreuzer Date: Sat, 5 Apr 2014 15:41:03 +0000 Subject: [PATCH] [PSEH3] Implement __finally support for C++ svn path=/trunk/; revision=62626 --- reactos/include/reactos/libs/pseh/pseh3.h | 18 +++++++++--------- reactos/lib/pseh/i386/pseh3.c | 17 +++++++++++++++++ 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/reactos/include/reactos/libs/pseh/pseh3.h b/reactos/include/reactos/libs/pseh/pseh3.h index c1ab215e4e2..8b7ca201242 100644 --- a/reactos/include/reactos/libs/pseh/pseh3.h +++ b/reactos/include/reactos/libs/pseh/pseh3.h @@ -10,7 +10,7 @@ #pragma once #define _PSEH3_H_ -#include "excpt.h" +#include #ifdef __cplusplus extern "C" { @@ -111,7 +111,7 @@ void * __cdecl __attribute__((error("Can only be used inside an exception filter #endif /* This attribute allows automatic cleanup of the registered frames */ -#define _SEH3$_AUTO_CLEANUP __attribute__((cleanup(_SEH3$_Unregister))) +#define _SEH3$_AUTO_CLEANUP __attribute__((cleanup(_SEH3$_AutoCleanup))) /* CLANG specific definitions! */ #ifdef __clang__ @@ -217,7 +217,7 @@ _SEH3$_RegisterTryLevelWithNonVolatiles( /* Use the global unregister function */ void __attribute__((regparm(1))) -_SEH3$_Unregister( +_SEH3$_AutoCleanup( volatile SEH3$_REGISTRATION_FRAME *Frame); /* These are only dummies here */ @@ -251,7 +251,7 @@ _SEH3$_Unregister( #define _SEH3$_DECLARE_EXCEPT_INTRINSICS() /* Since we cannot use nested functions, we declare these globally as macros */ -#define _abnormal_termination() (_SEH3$_TrylevelFrame.ScopeTable != 0) +#define _abnormal_termination() (_SEH3$_TrylevelFrame.ExceptionPointers != 0) #define _exception_code() (_SEH3$_TrylevelFrame.ExceptionPointers->ExceptionRecord->ExceptionCode) #define _exception_info() (_SEH3$_TrylevelFrame.ExceptionPointers) @@ -294,7 +294,7 @@ _SEH3$_Unregister( _SEH3$_NESTED_FUNC_OPEN(_Name) \ /* Declare the intrinsics for the finally function */ \ inline __attribute__((always_inline, gnu_inline)) \ - int _abnormal_termination() { return (_SEH3$_TrylevelFrame.ScopeTable != 0); } \ + int _abnormal_termination() { return (_SEH3$_TrylevelFrame.ExceptionPointers != 0); } \ \ /* This construct makes sure that the finally function returns */ \ /* a proper value at the end */ \ @@ -351,7 +351,7 @@ _SEH3$_Unregister( }; \ \ /* Forward declaration of the auto cleanup function */ \ - _SEH3$_DECLARE_CLEANUP_FUNC(_SEH3$_Unregister); \ + _SEH3$_DECLARE_CLEANUP_FUNC(_SEH3$_AutoCleanup); \ \ /* Allocate a registration frame */ \ volatile SEH3$_REGISTRATION_FRAME _SEH3$_AUTO_CLEANUP _SEH3$_TrylevelFrame; \ @@ -412,8 +412,8 @@ _SEH3$_Unregister( /* End the try block */ \ while (0); \ _SEH3$_l_AfterTry: (void)0; \ - /* Set ScopeTable to 0, this is used by _abnormal_termination() */ \ - _SEH3$_TrylevelFrame.ScopeTable = 0; \ + /* Set ExceptionPointers to 0, this is used by _abnormal_termination() */ \ + _SEH3$_TrylevelFrame.ExceptionPointers = 0; \ \ goto _SEH3$_l_EndTry; \ \ @@ -454,7 +454,7 @@ _SEH3$_Unregister( _SEH3$_ASM_GOTO(_SEH3$_l_OnException); \ \ /* Implementation of the auto cleanup function */ \ - _SEH3$_DEFINE_CLEANUP_FUNC(_SEH3$_Unregister); \ + _SEH3$_DEFINE_CLEANUP_FUNC(_SEH3$_AutoCleanup); \ \ /* Close the outer scope */ \ } while (0); diff --git a/reactos/lib/pseh/i386/pseh3.c b/reactos/lib/pseh/i386/pseh3.c index 7e7d438ea1f..b4856174135 100644 --- a/reactos/lib/pseh/i386/pseh3.c +++ b/reactos/lib/pseh/i386/pseh3.c @@ -130,6 +130,23 @@ _SEH3$_InvokeFilter( return FilterResult; } +void +__attribute__((regparm(1))) +_SEH3$_AutoCleanup( + SEH3$_REGISTRATION_FRAME *Frame) +{ + /* Check for __finally frames */ + if (Frame->ScopeTable->Target == NULL) + { + _SEH3$_InvokeFilter(Frame, Frame->ScopeTable->Filter); + } + + if (Frame->Handler) + _SEH3$_UnregisterFrame(Frame); + else + _SEH3$_UnregisterTryLevel(Frame); +} + static inline LONG _SEH3$_GetFilterResult(