Not a member of Pastebin yet?
Sign Up,
it unlocks many cool features!
- #ifndef _CEXC_H_
- #define _CEXC_H_
- #include <assert.h>
- #include <setjmp.h>
- #include <unistd.h>
- #include <unwind.h>
- struct cexc_ctx {
- struct _Unwind_Exception uexc;
- void *exc;
- };
- typedef void * cexc_t;
- #define CEXC_TRY { \
- jmp_buf cexc_jmp_; \
- struct cexc_ctx cexc_ctx_ = { \
- .exc = NULL \
- }; \
- \
- if (cexc_ctx == NULL) \
- cexc_ctx = &cexc_ctx_; \
- \
- if (setjmp(cexc_jmp_) == 0) { \
- void cexc_landingpad_(int *unwind_) \
- { \
- if (*unwind_ == 0) \
- return; \
- \
- longjmp(cexc_jmp_, 1); \
- } \
- __attribute__((cleanup(cexc_landingpad_))) int cexc_unwind_ = 1;
- #define CEXC_CATCH(exc_...) \
- cexc_unwind_ = 0; \
- if (cexc_ctx == &cexc_ctx_) \
- cexc_ctx = NULL; \
- } else { \
- cexc_t unused_exc_ __attribute__((unused)), ##exc_ = cexc_ctx->exc; \
- \
- if (cexc_ctx == &cexc_ctx_) \
- cexc_ctx = NULL;
- #define CEXC_END \
- } \
- }
- #define CEXC_THROW(e_...) ({ \
- assert("uncaught throw" && cexc_ctx != NULL); \
- _Pragma("GCC diagnostic ignored \"-Wunused-value\"") \
- cexc_ctx->exc = (cexc_ctx->exc, ##e_); \
- _Pragma("GCC diagnostic pop") \
- _Unwind_ForcedUnwind(&cexc_ctx->uexc, cexc_unwind_stop, 0); \
- assert("exception handling must be enabled (-fexceptions)" && 0); \
- *(int *)0 = 0; \
- })
- static inline _Unwind_Reason_Code cexc_unwind_stop()
- {
- return _URC_NO_REASON;
- }
- #ifndef CEXC_SOURCE
- extern
- #endif
- struct cexc_ctx *cexc_ctx;
- #endif // _CEXC_H_
Add Comment
Please, Sign In to add comment