[PSEH3]
[reactos.git] / reactos / include / reactos / libs / pseh / pseh2.h
index 776864a..f74805d 100644 (file)
 #ifndef KJK_PSEH2_H_
 #define KJK_PSEH2_H_
 
-#if defined(USE_DUMMY_PSEH) || defined (__arm__) || defined(__clang__) || defined(_M_AMD64)
+#if defined(_USE_NATIVE_SEH) || defined(_MSC_VER)
+
+#include <excpt.h>
+#define _SEH2_TRY __try
+#define _SEH2_FINALLY __finally
+#define _SEH2_EXCEPT(...) __except(__VA_ARGS__)
+#define _SEH2_END
+#define _SEH2_GetExceptionInformation() (GetExceptionInformation())
+#define _SEH2_GetExceptionCode() (GetExceptionCode())
+#define _SEH2_AbnormalTermination() (AbnormalTermination())
+#define _SEH2_YIELD(STMT_) STMT_
+#define _SEH2_LEAVE __leave
+
+#elif defined(_USE_DUMMY_PSEH) || defined (__arm__) || defined(__clang__) || defined(_M_AMD64)
 
 #define _SEH2_TRY  {
 #define _SEH2_FINALLY }  {
 #define _SEH2_YIELD(STMT_) STMT_
 #define _SEH2_LEAVE
 
-#elif defined(USE_NATIVE_SEH) || defined(_MSC_VER)
+#elif defined(_USE_PSEH3)
 
-#include <excpt.h>
-#define _SEH2_TRY __try
-#define _SEH2_FINALLY __finally
-#define _SEH2_EXCEPT(...) __except(__VA_ARGS__)
-#define _SEH2_END
-#define _SEH2_GetExceptionInformation() (GetExceptionInformation())
-#define _SEH2_GetExceptionCode() (GetExceptionCode())
-#define _SEH2_AbnormalTermination() (AbnormalTermination())
-#define _SEH2_YIELD(STMT_) STMT_
-#define _SEH2_LEAVE __leave
+#include "pseh3.h"
+
+/* Compatibility macros */
+#define _SEH2_TRY _SEH3_TRY
+#define _SEH2_EXCEPT _SEH3_EXCEPT
+#define _SEH2_FINALLY _SEH3_FINALLY
+#define _SEH2_END _SEH3_END
+#define _SEH2_GetExceptionInformation() ((struct _EXCEPTION_POINTERS*)_exception_info())
+#define _SEH2_GetExceptionCode _exception_code
+#define _SEH2_AbnormalTermination _abnormal_termination
+#define _SEH2_LEAVE _SEH3_LEAVE
+#define _SEH2_YIELD(x) x
 
 #elif defined(__GNUC__)
 
@@ -110,6 +125,14 @@ extern void __cdecl _SEH2Return(void);
 }
 #endif
 
+/* Prevent gcc from inlining functions that use SEH. */
+#if ((__GNUC__ >= 4) && (__GNUC_MINOR__ >= 7))
+static inline __attribute__((always_inline)) __attribute__((returns_twice)) void _SEH_DontInline() {}
+#define __PREVENT_GCC_FROM_INLINING_SEH_FUNCTIONS() _SEH_DontInline();
+#else
+#define __PREVENT_GCC_FROM_INLINING_SEH_FUNCTIONS()
+#endif
+
 /* A no-op side effect that scares GCC */
 #define __SEH_SIDE_EFFECT __asm__ __volatile__("#")
 
@@ -192,7 +215,6 @@ extern void __cdecl _SEH2Return(void);
        if(_SEHTopTryLevel) \
        { \
                _SEH2LeaveFrame(); \
-               __asm__ __volatile__("mov %0, %%esp" : : "g" (_SEHStackPointer)); \
        }
 
 #define __SEH_END_SCOPE_CHAIN \
@@ -219,16 +241,14 @@ extern void __cdecl _SEH2Return(void);
                        static const int _SEH2ScopeKind = 0; \
                        volatile _SEH2TryLevel_t _SEHTryLevel; \
                        volatile _SEH2HandleTryLevel_t _SEHHandleTryLevel; \
-                       void * _SEHStackPointer; \
+                       _SEH2Frame_t _SEH2Frame[_SEHTopTryLevel ? 1 : 0]; \
                        volatile _SEH2TryLevel_t * _SEH2TryLevelP; \
                        _SEH2Frame_t * const _SEH2FrameP = _SEHTopTryLevel ? \
-                               ({ __asm__ __volatile__("mov %%esp, %0" : "=g" (_SEHStackPointer)); __builtin_alloca(sizeof(_SEH2Frame_t)); }) : \
-                               _SEHCurFrameP; \
+                               _SEH2Frame : _SEHCurFrameP; \
  \
                        (void)_SEH2ScopeKind; \
                        (void)_SEHTryLevel; \
                        (void)_SEHHandleTryLevel; \
-                       (void)_SEHStackPointer; \
                        (void)_SEH2FrameP; \
                        (void)_SEH2TryLevelP; \
  \
@@ -249,6 +269,7 @@ extern void __cdecl _SEH2Return(void);
        auto __SEH_DECLARE_FINALLY(_SEHFinally);
 
 #define _SEH2_TRY \
+       __PREVENT_GCC_FROM_INLINING_SEH_FUNCTIONS() \
        __SEH_BEGIN_SCOPE \
        { \
                __SEH_SCOPE_LOCALS; \