[PSEH3]
[reactos.git] / reactos / include / reactos / libs / pseh / pseh2.h
index 6c473a4..f74805d 100644 (file)
        FROM, OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER
        DEALINGS IN THE SOFTWARE.
 */
-#ifdef _M_AMD64
-#include "pseh2_64.h"
-#else
 
 #ifndef KJK_PSEH2_H_
 #define KJK_PSEH2_H_
 
-#if !defined (__arm__) && !defined(__clang__)
+#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_EXCEPT(...) } if (0) {
+#define _SEH2_END }
+#define _SEH2_GetExceptionInformation()
+#define _SEH2_GetExceptionCode() 0
+#define _SEH2_AbnormalTermination()
+#define _SEH2_YIELD(STMT_) STMT_
+#define _SEH2_LEAVE
+
+#elif defined(_USE_PSEH3)
+
+#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__)
 
-#if defined(__GNUC__)
 struct _EXCEPTION_RECORD;
 struct _EXCEPTION_POINTERS;
 struct _CONTEXT;
@@ -76,8 +112,7 @@ typedef struct __SEH2HandleTryLevel
 _SEH2HandleTryLevel_t;
 
 #ifdef __cplusplus
-extern "C"
-{
+extern "C" {
 #endif
 
 extern int __cdecl _SEH2EnterFrameAndTrylevel(_SEH2Frame_t *, volatile _SEH2TryLevel_t *);
@@ -90,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__("#")
 
@@ -172,7 +215,6 @@ extern void __cdecl _SEH2Return(void);
        if(_SEHTopTryLevel) \
        { \
                _SEH2LeaveFrame(); \
-               __asm__ __volatile__("mov %0, %%esp" : : "g" (_SEHStackPointer)); \
        }
 
 #define __SEH_END_SCOPE_CHAIN \
@@ -199,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; \
  \
@@ -229,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; \
@@ -369,41 +410,11 @@ extern void __cdecl _SEH2Return(void);
 
 __SEH_END_SCOPE_CHAIN;
 
-#else
-
-#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
-
-#endif
 
 #else
-
-#define _SEH2_TRY  {
-#define _SEH2_FINALLY }  {
-#define _SEH2_EXCEPT(...) } if (0) {
-#define _SEH2_END }
-
-#define _SEH2_GetExceptionInformation() 
-#define _SEH2_GetExceptionCode() 0
-#define _SEH2_AbnormalTermination() 
-
-#define _SEH2_YIELD(STMT_) STMT_
-#define _SEH2_LEAVE
-
+#error no PSEH support
 #endif
 
-#endif
-#endif
+#endif /* !KJK_PSEH2_H_ */
 
 /* EOF */