Author: tkreuzer Date: Sat Mar 8 18:57:45 2014 New Revision: 62462
URL: http://svn.reactos.org/svn/reactos?rev=62462&view=rev Log: [PSEH3] Add a bit more code to support Clang and C++.
Modified: trunk/reactos/include/reactos/libs/pseh/pseh3.h
Modified: trunk/reactos/include/reactos/libs/pseh/pseh3.h URL: http://svn.reactos.org/svn/reactos/trunk/reactos/include/reactos/libs/pseh/p... ============================================================================== --- trunk/reactos/include/reactos/libs/pseh/pseh3.h [iso-8859-1] (original) +++ trunk/reactos/include/reactos/libs/pseh/pseh3.h [iso-8859-1] Sat Mar 8 18:57:45 2014 @@ -11,6 +11,10 @@ #define _PSEH3_H_
#include "excpt.h" + +#ifdef __cplusplus +extern "C" { +#endif
/* CLANG must safe non-volatiles, because it uses a return-twice algorithm */ #if defined(__clang__) && !defined(_SEH3$_FRAME_ALL_NONVOLATILES) @@ -207,6 +211,46 @@ #define _SEH3$_DECLARE_FILTER_FUNC(_Name) #define _SEH3$_DEFINE_DUMMY_FINALLY(_Name)
+/* The "nested" functions are a piece of code with a ret instruction at the end */ +#define _SEH3$_NESTED_FUNC_OPEN() \ + { \ + int SavedEsp, result = 0; \ +\ + /* Save esp */ \ + asm volatile ("movl %%esp, %[SavedEsp]\n" : : [SavedEsp]"m"(SavedEsp)); + +#define _SEH3$_NESTED_FUNC_CLOSE() \ + /* Restore esp and return to the caller */ \ + asm volatile ("movl %[SavedEsp], %%esp\nret\n" \ + : : "a"(result), [SavedEsp]"irm"(SavedEsp)); \ + } + +/* The filter function */ +#define _SEH3$_DEFINE_FILTER_FUNC(_Name, expression) \ + _SEH3$_NESTED_FUNC_OPEN() \ + { \ + /* Evaluate the filter expression */ \ + result = (expression); \ + } \ + _SEH3$_NESTED_FUNC_CLOSE() + +#define _SEH3$_FINALLY_FUNC_OPEN(_Name) \ + _SEH3$_NESTED_FUNC_OPEN() \ + /* This construct makes sure that the finally function returns */ \ + /* a proper value at the end */ \ + for (; ; (void)({asm volatile ("movl %[SavedEsp], %%esp\nret\n" \ + : : "a"(result), [SavedEsp]"irm"(SavedEsp)); 0;})) + +#define _SEH3$_FILTER(_Filter, _FilterExpression) (&&_SEH3$_l_FilterOrFinally) +#define _SEH3$_FINALLY(_Finally) 0 + +#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 _exception_code() (_SEH3$_TrylevelFrame.ExceptionPointers->ExceptionRecord->ExceptionCode) +#define _exception_info() (_SEH3$_TrylevelFrame.ExceptionPointers) + #else /* __cplusplus || __clang__ */
#define _SEH3$_DECLARE_EXCEPT_INTRINSICS() \ @@ -246,10 +290,16 @@ _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.ScopeTable != 0); } \ +\ + /* This construct makes sure that the finally function returns */ \ + /* a proper value at the end */ \ + for (; ; (void)({return 0; 0;}))
#define _SEH3$_FILTER(_Filter, _FilterExpression) \ (__builtin_constant_p(_FilterExpression) ? (void*)(unsigned long)(unsigned char)(unsigned long)(_FilterExpression) : _Filter) + +#define _SEH3$_FINALLY(_Finally) (_Finally)
#define _SEH3$_DEFINE_DUMMY_FINALLY(_Name) \ auto inline __attribute__((always_inline,gnu_inline)) int _Name(int Action) { (void)Action; return 0; } @@ -284,7 +334,9 @@ __label__ _SEH3$_l_EndTry; \ __label__ _SEH3$_l_HandlerTarget; \ __label__ _SEH3$_l_OnException; \ + __label__ _SEH3$_l_BeforeFilterOrFinally; \ __label__ _SEH3$_l_FilterOrFinally; \ + (void)&&_SEH3$_l_BeforeFilterOrFinally; \ (void)&&_SEH3$_l_FilterOrFinally; \ \ /* Count the try level. Outside of any __try, _SEH3$_TryLevel is 0 */ \ @@ -332,6 +384,10 @@ _SEH3$_DECLARE_EXCEPT_INTRINSICS(); \ \ goto _SEH3$_l_DoTry; \ +\ + _SEH3$_l_BeforeFilterOrFinally: (void)0; \ + /* Make sure the filter function doesn't use esp */ \ + _SEH3$_EnforceFramePointer(); \ \ _SEH3$_l_FilterOrFinally: (void)0; \ /* Emit the filter function */ \ @@ -363,7 +419,7 @@ _SEH3$_DECLARE_FILTER_FUNC(_SEH3$_FinallyFunction); \ \ /* Create a static data table that contains the finally function */ \ - static const SEH3$_SCOPE_TABLE _SEH3$_ScopeTable = { 0, &_SEH3$_FinallyFunction }; \ + static const SEH3$_SCOPE_TABLE _SEH3$_ScopeTable = { 0, _SEH3$_FINALLY(&_SEH3$_FinallyFunction) }; \ \ /* Register the registration record. */ \ if (_SEH3$_TryLevel == 1) _SEH3$_RegisterFrame_(&_SEH3$_TrylevelFrame, &_SEH3$_ScopeTable); \ @@ -374,11 +430,9 @@ _SEH3$_l_HandlerTarget: (void)0; \ _SEH3$_EnforceFramePointer(); \ \ + _SEH3$_l_BeforeFilterOrFinally: (void)0; \ _SEH3$_l_FilterOrFinally: (void)0; \ - _SEH3$_FINALLY_FUNC_OPEN(_SEH3$_FinallyFunction) \ - /* This construct makes sure that the finally function returns */ \ - /* a proper value at the end */ \ - for (; ; (void)({return 0; 0;})) + _SEH3$_FINALLY_FUNC_OPEN(_SEH3$_FinallyFunction)
#define _SEH3_END \ @@ -388,7 +442,7 @@ \ _SEH3$_l_OnException: (void)0; \ /* Force GCC to create proper code pathes */ \ - _SEH3$_SCARE_GCC() \ + _SEH3$_SCARE_GCC(); \ \ _SEH3$_l_EndTry:(void)0; \ _SEH3$_ASM_GOTO(_SEH3$_l_OnException); \ @@ -402,3 +456,8 @@ #define _SEH3_LEAVE goto _SEH3$_l_AfterTry
#define _SEH3_VOLATILE volatile + + +#ifdef __cplusplus +}; // extern "C" +#endif