FreeCalypso > hg > ffs-editor
diff src/cs/riviera/support/exception.h @ 0:92470e5d0b9e
src: partial import from FC Selenite
author | Mychaela Falconia <falcon@freecalypso.org> |
---|---|
date | Fri, 15 May 2020 01:28:16 +0000 |
parents | |
children |
line wrap: on
line diff
--- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/src/cs/riviera/support/exception.h Fri May 15 01:28:16 2020 +0000 @@ -0,0 +1,123 @@ +/* + ****************************** + * + * + * Initialial version: Laurent Deniau, Laurent.Deniau@cern.ch + * + * For more information, please see the paper: + * http://cern.ch/Laurent.Deniau/html/oopc/exception.html + * + * ----------------------------------------------------------- + * + * Strong rework and adaption to riviera by Christophe Favergeon + * + ****************************** + */ + +#ifndef RVF_EXCEPTION_H +#define RVF_EXCEPTION_H + +#include "rvf/rvf_api.h" +#include "rvf/rvf_target.h" + +#include <string.h> + + + +//#ifndef __STDC__ +//# error "exception.h needs ISO C compiler to work properly" +//#endif + +#include <setjmp.h> + +typedef enum K_RVF_EXCEPTIONS { E_invalid=1, E_not_enough_memory,E_unknown } T_RVF_EXCEPTIONS; + +typedef void (*T_RVF_RELEASE_PROTECTED_POINTER)(void *p); + +/* + choose context savings +*/ + +#define rvf_save_context_buffer_(context) setjmp(context) +#define rvf_restore_context_buffer_(context, val) longjmp(context, val) + +/* + some hidden types used to handle exceptions +*/ + +/* type of stack of protected pointer */ +struct _protectedPtr_ { + struct _protectedPtr_ *next; + struct _protectedPtr_ *previous; + void *ptr; + T_RVF_RELEASE_PROTECTED_POINTER func; +}; + +/* type of stack of exception */ +struct _exceptionContext_ { + struct _exceptionContext_ *next; + struct _protectedPtr_ *stack; + jmp_buf context; +}; + +extern struct _exceptionContext_ *const _returnExceptionContext_[MAX_RVF_TASKS]; +extern struct _exceptionContext_ *_currentExceptionContext_[MAX_RVF_TASKS]; + +/* exception keywords */ +#define try \ + do { \ + struct _exceptionContext_ _localExceptionContext_ ;\ + memset(&_localExceptionContext_,0,sizeof(struct _exceptionContext_));\ + _localExceptionContext_.next=_currentExceptionContext_[rvf_get_taskid()];\ + _currentExceptionContext_[rvf_get_taskid()] = &_localExceptionContext_; \ + do { \ + int const exception = \ + rvf_save_context_buffer_(_currentExceptionContext_[rvf_get_taskid()]->context); \ + if (!exception) { + +#define catch(except) \ + } else if ((int)(except) == exception) { \ + _currentExceptionContext_[rvf_get_taskid()] = _currentExceptionContext_[rvf_get_taskid()]->next; + +#define catch_any \ + } else { \ + _currentExceptionContext_[rvf_get_taskid()] = _currentExceptionContext_[rvf_get_taskid()]->next; + +#define endtry \ + } \ + } while(0); \ + if (_currentExceptionContext_[rvf_get_taskid()] == &_localExceptionContext_) { \ + rvf_forget_protected_ptr();\ + _currentExceptionContext_[rvf_get_taskid()] = _currentExceptionContext_[rvf_get_taskid()]->next; \ + } \ + } while(0) + +#define rethrow throw(exception) +#define break_try break + +/* +#define return_try(...) \ + do { \ + _currentExceptionContext_ = _returnExceptionContext_; \ + return __VA_ARGS__; \ + } while(0) +*/ + +#define throw(except) _exceptionThrow_((int)(except)) + + +/* + extern declarations +*/ + +extern void _exceptionThrow_(int except); + +extern void rvf_forget_protected_ptr(); +extern void rvf_protect_pointer(T_RVF_MB_ID mb_id,void *p,T_RVF_RELEASE_PROTECTED_POINTER func); + +#define RVF_PROTECT(bank,p) rvf_protect_pointer(bank,p,(T_RVF_RELEASE_PROTECTED_POINTER)rvf_free_buf) + +#define THROW_IF_ERROR(err) if (err!=0) throw(E_unknown) +#define THROW_IF_NULL(p) if (p==NULL) throw(E_not_enough_memory) +#define THROW_IF_YELLOW(b,p) if ((p==NULL) || (rvf_get_mb_status(b)==RVF_YELLOW)) throw(E_not_enough_memory) +#endif