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;
_SEH2HandleTryLevel_t;
#ifdef __cplusplus
-extern "C"
-{
+extern "C" {
#endif
extern int __cdecl _SEH2EnterFrameAndTrylevel(_SEH2Frame_t *, volatile _SEH2TryLevel_t *);
}
#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__("#")
if(_SEHTopTryLevel) \
{ \
_SEH2LeaveFrame(); \
- __asm__ __volatile__("mov %0, %%esp" : : "g" (_SEHStackPointer)); \
}
#define __SEH_END_SCOPE_CHAIN \
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; \
\
auto __SEH_DECLARE_FINALLY(_SEHFinally);
#define _SEH2_TRY \
+ __PREVENT_GCC_FROM_INLINING_SEH_FUNCTIONS() \
__SEH_BEGIN_SCOPE \
{ \
__SEH_SCOPE_LOCALS; \
__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 */