// // Cforall Version 1.0.0 Copyright (C) 2016 University of Waterloo // // The contents of this file are covered under the licence agreement in the // file "LICENCE" distributed with Cforall. // // exception.h -- Builtins for exception handling. // // Author : Andrew Beach // Created On : Mon Jun 26 15:11:00 2017 // Last Modified By : Andrew Beach // Last Modified On : Tue May 19 14:17:00 2020 // Update Count : 10 // #pragma once #ifdef __cforall extern "C" { #endif struct __cfaehm_base_exception_t; typedef struct __cfaehm_base_exception_t exception_t; struct __cfaehm_base_exception_t_vtable { const struct __cfaehm_base_exception_t_vtable * parent; size_t size; void (*copy)(struct __cfaehm_base_exception_t *this, struct __cfaehm_base_exception_t * other); void (*free)(struct __cfaehm_base_exception_t *this); const char * (*msg)(struct __cfaehm_base_exception_t *this); }; struct __cfaehm_base_exception_t { struct __cfaehm_base_exception_t_vtable const * virtual_table; }; extern struct __cfaehm_base_exception_t_vtable ___cfaehm_base_exception_t_vtable_instance; void __cfaehm_cancel_stack(exception_t * except) __attribute__((noreturn)); // Used in throw statement translation. void __cfaehm_throw_terminate(exception_t * except, void (*)(exception_t *)); void __cfaehm_rethrow_terminate() __attribute__((noreturn)); void __cfaehm_throw_resume(exception_t * except, void (*)(exception_t *)); // Function catches termination exceptions. void __cfaehm_try_terminate( void (*try_block)(), void (*catch_block)(int index, exception_t * except), int (*match_block)(exception_t * except)); // Clean-up the exception in catch blocks. void __cfaehm_cleanup_terminate(void * except); // Data structure creates a list of resume handlers. struct __cfaehm_try_resume_node { struct __cfaehm_try_resume_node * next; _Bool (*handler)(exception_t * except); }; // These act as constructor and destructor for the resume node. void __cfaehm_try_resume_setup( struct __cfaehm_try_resume_node * node, _Bool (*handler)(exception_t * except)); void __cfaehm_try_resume_cleanup( struct __cfaehm_try_resume_node * node); // Check for a standard way to call fake deconstructors. struct __cfaehm_cleanup_hook {}; #ifdef __cforall } // Not all the built-ins can be expressed in C. These can't be // implemented in the .c file either so they all have to be inline. trait is_exception(dtype exceptT, dtype virtualT) { /* The first field must be a pointer to a virtual table. * That virtual table must be a decendent of the base exception virtual table. */ virtualT const & get_exception_vtable(exceptT *); // Always returns the virtual table for this type (associated types hack). }; trait is_termination_exception(dtype exceptT, dtype virtualT | is_exception(exceptT, virtualT)) { void defaultTerminationHandler(exceptT &); }; trait is_resumption_exception(dtype exceptT, dtype virtualT | is_exception(exceptT, virtualT)) { void defaultResumptionHandler(exceptT &); }; forall(dtype exceptT, dtype virtualT | is_termination_exception(exceptT, virtualT)) static inline void $throw(exceptT & except) { __cfaehm_throw_terminate( (exception_t *)&except, (void(*)(exception_t *))defaultTerminationHandler ); } forall(dtype exceptT, dtype virtualT | is_resumption_exception(exceptT, virtualT)) static inline void $throwResume(exceptT & except) { __cfaehm_throw_resume( (exception_t *)&except, (void(*)(exception_t *))defaultResumptionHandler ); } forall(dtype exceptT, dtype virtualT | is_exception(exceptT, virtualT)) static inline void cancel_stack(exceptT & except) __attribute__((noreturn)) { __cfaehm_cancel_stack( (exception_t *)&except ); } forall(dtype exceptT, dtype virtualT | is_exception(exceptT, virtualT)) static inline void defaultTerminationHandler(exceptT & except) { return cancel_stack( except ); } forall(dtype exceptT, dtype virtualT | is_exception(exceptT, virtualT)) static inline void defaultResumptionHandler(exceptT & except) { throw except; } #endif