exception

This commit is contained in:
Shengliang Guan 2022-02-28 09:50:30 +08:00
parent 0fae01c975
commit a6b327fb69
2 changed files with 158 additions and 169 deletions

View File

@ -13,8 +13,8 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#ifndef _TD_UTIL_EXCEPTION_H
#define _TD_UTIL_EXCEPTION_H
#ifndef _TD_UTIL_EXCEPTION_H_
#define _TD_UTIL_EXCEPTION_H_
#include "os.h"
@ -49,7 +49,6 @@ typedef struct SCleanupAction {
} arg1, arg2;
} SCleanupAction;
/*
* exception hander registration
*/
@ -77,8 +76,10 @@ void cleanupExecuteTo( int32_t anchor, bool failed );
void cleanupExecute(SExceptionNode* node, bool failed);
bool cleanupExceedLimit();
#define CLEANUP_PUSH_VOID_PTR_PTR( failOnly, func, arg1, arg2 ) cleanupPush_void_ptr_ptr( (failOnly), (void*)(func), (void*)(arg1), (void*)(arg2) )
#define CLEANUP_PUSH_VOID_PTR_BOOL( failOnly, func, arg1, arg2 ) cleanupPush_void_ptr_bool( (failOnly), (void*)(func), (void*)(arg1), (bool)(arg2) )
#define CLEANUP_PUSH_VOID_PTR_PTR(failOnly, func, arg1, arg2) \
cleanupPush_void_ptr_ptr((failOnly), (void*)(func), (void*)(arg1), (void*)(arg2))
#define CLEANUP_PUSH_VOID_PTR_BOOL(failOnly, func, arg1, arg2) \
cleanupPush_void_ptr_bool((failOnly), (void*)(func), (void*)(arg1), (bool)(arg2))
#define CLEANUP_PUSH_VOID_PTR(failOnly, func, arg) cleanupPush_void_ptr((failOnly), (void*)(func), (void*)(arg))
#define CLEANUP_PUSH_INT_INT(failOnly, func, arg) cleanupPush_void_ptr((failOnly), (void*)(func), (int)(arg))
#define CLEANUP_PUSH_VOID(failOnly, func) cleanupPush_void((failOnly), (void*)(func))
@ -98,7 +99,8 @@ void exceptionPushNode( SExceptionNode* node );
int32_t exceptionPopNode();
void exceptionThrow(int32_t code);
#define TRY(maxCleanupActions) do { \
#define TRY(maxCleanupActions) \
do { \
SExceptionNode exceptionNode = {0}; \
SCleanupAction cleanupActions[(maxCleanupActions) > 0 ? (maxCleanupActions) : 1]; \
exceptionNode.maxCleanupAction = (maxCleanupActions) > 0 ? (maxCleanupActions) : 1; \
@ -107,12 +109,16 @@ void exceptionThrow( int32_t code );
int caughtException = setjmp(exceptionNode.jb); \
if (caughtException == 0)
#define CATCH( code ) int32_t code = exceptionPopNode(); \
#define CATCH(code) \
int32_t code = exceptionPopNode(); \
if (caughtException == 1)
#define FINALLY(code) int32_t code = exceptionPopNode();
#define END_TRY } while( 0 );
#define END_TRY \
} \
while (0) \
;
#define THROW(x) exceptionThrow((x))
#define CAUGHT_EXCEPTION() ((bool)(caughtException == 1))
@ -122,4 +128,4 @@ void exceptionThrow( int32_t code );
}
#endif
#endif /*_TD_UTIL_EXCEPTION_H*/
#endif /*_TD_UTIL_EXCEPTION_H_*/

View File

@ -13,7 +13,7 @@
* along with this program. If not, see <http://www.gnu.org/licenses/>.
*/
#include "os.h"
#define _DEFAULT_SOURCE
#include "exception.h"
static threadlocal SExceptionNode* expList;
@ -34,8 +34,6 @@ void exceptionThrow( int32_t code ) {
longjmp(expList->jb, 1);
}
static void cleanupWrapper_void_ptr_ptr(SCleanupAction* ca) {
void (*func)(void*, void*) = ca->func;
func(ca->arg1.Ptr, ca->arg2.Ptr);
@ -52,7 +50,7 @@ static void cleanupWrapper_void_ptr( SCleanupAction* ca ) {
}
static void cleanupWrapper_int_int(SCleanupAction* ca) {
int (*func)( int ) = ca->func;
int32_t (*func)(int32_t) = ca->func;
func(ca->arg1.Int);
}
@ -62,21 +60,16 @@ static void cleanupWrapper_void( SCleanupAction* ca ) {
}
static void cleanupWrapper_int_ptr(SCleanupAction* ca) {
int (*func)( void* ) = ca->func;
int32_t (*func)(void*) = ca->func;
func(ca->arg1.Ptr);
}
typedef void (*wrapper)(SCleanupAction*);
static wrapper wrappers[] = {
cleanupWrapper_void_ptr_ptr,
cleanupWrapper_void_ptr_bool,
cleanupWrapper_void_ptr,
cleanupWrapper_int_int,
cleanupWrapper_void,
cleanupWrapper_int_ptr,
cleanupWrapper_void_ptr_ptr, cleanupWrapper_void_ptr_bool, cleanupWrapper_void_ptr,
cleanupWrapper_int_int, cleanupWrapper_void, cleanupWrapper_int_ptr,
};
void cleanupPush_void_ptr_ptr(bool failOnly, void* func, void* arg1, void* arg2) {
assert(expList->numCleanupAction < expList->maxCleanupAction);
@ -109,7 +102,7 @@ void cleanupPush_void_ptr( bool failOnly, void* func, void* arg ) {
ca->arg1.Ptr = arg;
}
void cleanupPush_int_int( bool failOnly, void* func, int arg ) {
void cleanupPush_int_int(bool failOnly, void* func, int32_t arg) {
assert(expList->numCleanupAction < expList->maxCleanupAction);
SCleanupAction* ca = expList->cleanupActions + expList->numCleanupAction++;
@ -138,11 +131,7 @@ void cleanupPush_int_ptr( bool failOnly, void* func, void* arg ) {
ca->arg1.Ptr = arg;
}
int32_t cleanupGetActionCount() {
return expList->numCleanupAction;
}
int32_t cleanupGetActionCount() { return expList->numCleanupAction; }
static void doExecuteCleanup(SExceptionNode* node, int32_t anchor, bool failed) {
while (node->numCleanupAction > anchor) {
@ -154,13 +143,7 @@ static void doExecuteCleanup( SExceptionNode* node, int32_t anchor, bool failed
}
}
void cleanupExecuteTo( int32_t anchor, bool failed ) {
doExecuteCleanup( expList, anchor, failed );
}
void cleanupExecuteTo(int32_t anchor, bool failed) { doExecuteCleanup(expList, anchor, failed); }
void cleanupExecute( SExceptionNode* node, bool failed ) {
doExecuteCleanup( node, 0, failed );
}
bool cleanupExceedLimit() {
return expList->numCleanupAction >= expList->maxCleanupAction;
}
void cleanupExecute(SExceptionNode* node, bool failed) { doExecuteCleanup(node, 0, failed); }
bool cleanupExceedLimit() { return expList->numCleanupAction >= expList->maxCleanupAction; }