mirror of
https://github.com/reactos/reactos.git
synced 2025-08-03 22:56:00 +00:00
[PSEH3]
Implement __finally support for C++ svn path=/trunk/; revision=62626
This commit is contained in:
parent
9f2427ba20
commit
b938bfc001
2 changed files with 26 additions and 9 deletions
|
@ -10,7 +10,7 @@
|
||||||
#pragma once
|
#pragma once
|
||||||
#define _PSEH3_H_
|
#define _PSEH3_H_
|
||||||
|
|
||||||
#include "excpt.h"
|
#include <excpt.h>
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
extern "C" {
|
extern "C" {
|
||||||
|
@ -111,7 +111,7 @@ void * __cdecl __attribute__((error("Can only be used inside an exception filter
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
/* This attribute allows automatic cleanup of the registered frames */
|
/* 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! */
|
/* CLANG specific definitions! */
|
||||||
#ifdef __clang__
|
#ifdef __clang__
|
||||||
|
@ -217,7 +217,7 @@ _SEH3$_RegisterTryLevelWithNonVolatiles(
|
||||||
/* Use the global unregister function */
|
/* Use the global unregister function */
|
||||||
void
|
void
|
||||||
__attribute__((regparm(1)))
|
__attribute__((regparm(1)))
|
||||||
_SEH3$_Unregister(
|
_SEH3$_AutoCleanup(
|
||||||
volatile SEH3$_REGISTRATION_FRAME *Frame);
|
volatile SEH3$_REGISTRATION_FRAME *Frame);
|
||||||
|
|
||||||
/* These are only dummies here */
|
/* These are only dummies here */
|
||||||
|
@ -251,7 +251,7 @@ _SEH3$_Unregister(
|
||||||
#define _SEH3$_DECLARE_EXCEPT_INTRINSICS()
|
#define _SEH3$_DECLARE_EXCEPT_INTRINSICS()
|
||||||
|
|
||||||
/* Since we cannot use nested functions, we declare these globally as macros */
|
/* 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_code() (_SEH3$_TrylevelFrame.ExceptionPointers->ExceptionRecord->ExceptionCode)
|
||||||
#define _exception_info() (_SEH3$_TrylevelFrame.ExceptionPointers)
|
#define _exception_info() (_SEH3$_TrylevelFrame.ExceptionPointers)
|
||||||
|
|
||||||
|
@ -294,7 +294,7 @@ _SEH3$_Unregister(
|
||||||
_SEH3$_NESTED_FUNC_OPEN(_Name) \
|
_SEH3$_NESTED_FUNC_OPEN(_Name) \
|
||||||
/* Declare the intrinsics for the finally function */ \
|
/* Declare the intrinsics for the finally function */ \
|
||||||
inline __attribute__((always_inline, gnu_inline)) \
|
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 */ \
|
/* This construct makes sure that the finally function returns */ \
|
||||||
/* a proper value at the end */ \
|
/* a proper value at the end */ \
|
||||||
|
@ -351,7 +351,7 @@ _SEH3$_Unregister(
|
||||||
}; \
|
}; \
|
||||||
\
|
\
|
||||||
/* Forward declaration of the auto cleanup function */ \
|
/* Forward declaration of the auto cleanup function */ \
|
||||||
_SEH3$_DECLARE_CLEANUP_FUNC(_SEH3$_Unregister); \
|
_SEH3$_DECLARE_CLEANUP_FUNC(_SEH3$_AutoCleanup); \
|
||||||
\
|
\
|
||||||
/* Allocate a registration frame */ \
|
/* Allocate a registration frame */ \
|
||||||
volatile SEH3$_REGISTRATION_FRAME _SEH3$_AUTO_CLEANUP _SEH3$_TrylevelFrame; \
|
volatile SEH3$_REGISTRATION_FRAME _SEH3$_AUTO_CLEANUP _SEH3$_TrylevelFrame; \
|
||||||
|
@ -412,8 +412,8 @@ _SEH3$_Unregister(
|
||||||
/* End the try block */ \
|
/* End the try block */ \
|
||||||
while (0); \
|
while (0); \
|
||||||
_SEH3$_l_AfterTry: (void)0; \
|
_SEH3$_l_AfterTry: (void)0; \
|
||||||
/* Set ScopeTable to 0, this is used by _abnormal_termination() */ \
|
/* Set ExceptionPointers to 0, this is used by _abnormal_termination() */ \
|
||||||
_SEH3$_TrylevelFrame.ScopeTable = 0; \
|
_SEH3$_TrylevelFrame.ExceptionPointers = 0; \
|
||||||
\
|
\
|
||||||
goto _SEH3$_l_EndTry; \
|
goto _SEH3$_l_EndTry; \
|
||||||
\
|
\
|
||||||
|
@ -454,7 +454,7 @@ _SEH3$_Unregister(
|
||||||
_SEH3$_ASM_GOTO(_SEH3$_l_OnException); \
|
_SEH3$_ASM_GOTO(_SEH3$_l_OnException); \
|
||||||
\
|
\
|
||||||
/* Implementation of the auto cleanup function */ \
|
/* Implementation of the auto cleanup function */ \
|
||||||
_SEH3$_DEFINE_CLEANUP_FUNC(_SEH3$_Unregister); \
|
_SEH3$_DEFINE_CLEANUP_FUNC(_SEH3$_AutoCleanup); \
|
||||||
\
|
\
|
||||||
/* Close the outer scope */ \
|
/* Close the outer scope */ \
|
||||||
} while (0);
|
} while (0);
|
||||||
|
|
|
@ -130,6 +130,23 @@ _SEH3$_InvokeFilter(
|
||||||
return FilterResult;
|
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
|
static inline
|
||||||
LONG
|
LONG
|
||||||
_SEH3$_GetFilterResult(
|
_SEH3$_GetFilterResult(
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue