- Timestamp:
- Apr 13, 2021, 8:02:56 PM (3 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- e56cfb41
- Parents:
- 0effb6a (diff), 7f5683e (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- libcfa/src
- Files:
-
- 14 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/coroutine.cfa
r0effb6a r47e000c 46 46 47 47 //----------------------------------------------------------------------------- 48 FORALL_DATA_INSTANCE(CoroutineCancelled, (coroutine_t &), (coroutine_t)) 49 50 forall(T &) 51 void mark_exception(CoroutineCancelled(T) *) {} 48 EHM_VIRTUAL_TABLE(SomeCoroutineCancelled, std_coroutine_cancelled); 52 49 53 50 forall(T &) … … 71 68 72 69 // TODO: Remove explitate vtable set once trac#186 is fixed. 73 CoroutineCancelled(T)except;74 except.virtual_table = & get_exception_vtable(&except);70 SomeCoroutineCancelled except; 71 except.virtual_table = &std_coroutine_cancelled; 75 72 except.the_coroutine = &cor; 76 73 except.the_exception = except; 77 throwResume except; 74 // Why does this need a cast? 75 throwResume (SomeCoroutineCancelled &)except; 78 76 79 77 except->virtual_table->free( except ); -
libcfa/src/concurrency/coroutine.hfa
r0effb6a r47e000c 22 22 //----------------------------------------------------------------------------- 23 23 // Exception thrown from resume when a coroutine stack is cancelled. 24 FORALL_DATA_EXCEPTION(CoroutineCancelled, (coroutine_t &), (coroutine_t)) ( 24 EHM_EXCEPTION(SomeCoroutineCancelled)( 25 void * the_coroutine; 26 exception_t * the_exception; 27 ); 28 29 EHM_EXTERN_VTABLE(SomeCoroutineCancelled, std_coroutine_cancelled); 30 31 EHM_FORALL_EXCEPTION(CoroutineCancelled, (coroutine_t &), (coroutine_t)) ( 25 32 coroutine_t * the_coroutine; 26 33 exception_t * the_exception; … … 37 44 // Anything that implements this trait can be resumed. 38 45 // Anything that is resumed is a coroutine. 39 trait is_coroutine(T & | IS_RESUMPTION_EXCEPTION( CoroutineCancelled, (T))) {46 trait is_coroutine(T & | IS_RESUMPTION_EXCEPTION(SomeCoroutineCancelled)) { 40 47 void main(T & this); 41 48 $coroutine * get_coroutine(T & this); -
libcfa/src/concurrency/kernel.cfa
r0effb6a r47e000c 359 359 #if !defined(__CFA_NO_STATISTICS__) 360 360 __tls_stats()->ready.threads.threads++; 361 __push_stat( __tls_stats(), __tls_stats()->ready.threads.threads, false, "Processor", this ); 361 362 #endif 362 363 // This is case 2, the racy case, someone tried to run this thread before it finished blocking … … 376 377 #if !defined(__CFA_NO_STATISTICS__) 377 378 __tls_stats()->ready.threads.threads--; 379 __push_stat( __tls_stats(), __tls_stats()->ready.threads.threads, false, "Processor", this ); 378 380 #endif 379 381 … … 455 457 if( kernelTLS().this_stats ) { 456 458 __tls_stats()->ready.threads.threads++; 459 __push_stat( __tls_stats(), __tls_stats()->ready.threads.threads, false, "Processor", kernelTLS().this_processor ); 457 460 } 458 461 else { 459 462 __atomic_fetch_add(&cl->stats->ready.threads.threads, 1, __ATOMIC_RELAXED); 463 __push_stat( cl->stats, cl->stats->ready.threads.threads, true, "Cluster", cl ); 460 464 } 461 465 #endif -
libcfa/src/concurrency/kernel/startup.cfa
r0effb6a r47e000c 268 268 __print_stats( st, mainProcessor->print_stats, "Processor ", mainProcessor->name, (void*)mainProcessor ); 269 269 } 270 #if defined(CFA_STATS_ARRAY) 271 __flush_stat( st, "Processor", mainProcessor ); 272 #endif 270 273 #endif 271 274 … … 348 351 __print_stats( &local_stats, proc->print_stats, "Processor ", proc->name, (void*)proc ); 349 352 } 353 #if defined(CFA_STATS_ARRAY) 354 __flush_stat( &local_stats, "Processor", proc ); 355 #endif 350 356 #endif 351 357 … … 615 621 __print_stats( this.stats, this.print_stats, "Cluster", this.name, (void*)&this ); 616 622 } 623 #if defined(CFA_STATS_ARRAY) 624 __flush_stat( this.stats, "Cluster", &this ); 625 #endif 617 626 free( this.stats ); 618 627 #endif -
libcfa/src/concurrency/stats.cfa
r0effb6a r47e000c 5 5 #include <inttypes.h> 6 6 #include "bits/debug.hfa" 7 #include "bits/locks.hfa" 7 8 #include "stats.hfa" 8 9 … … 44 45 stats->io.calls.errors.busy = 0; 45 46 stats->io.poller.sleeps = 0; 47 #endif 48 49 #if defined(CFA_STATS_ARRAY) 50 stats->array.values = alloc(CFA_STATS_ARRAY); 51 stats->array.cnt = 0; 46 52 #endif 47 53 } … … 151 157 #endif 152 158 } 159 160 #if defined(CFA_STATS_ARRAY) 161 extern "C" { 162 #include <stdio.h> 163 #include <errno.h> 164 #include <sys/stat.h> 165 #include <fcntl.h> 166 } 167 168 void __flush_stat( struct __stats_t * this, const char * name, void * handle) { 169 int ret = mkdir(".cfadata", 0755); 170 if(ret < 0 && errno != EEXIST) abort("Failed to create directory .cfadata: %d\n", errno); 171 172 char filename[100]; 173 snprintf(filename, 100, ".cfadata/%s%p.data", name, handle); 174 175 int fd = open(filename, O_WRONLY | O_APPEND | O_CREAT, 0644); 176 if(fd < 0) abort("Failed to create file %s: %d\n", filename, errno); 177 178 for(i; this->array.cnt) { 179 char line[100]; 180 size_t n = snprintf(line, 100, "%llu, %lld\n", this->array.values[i].ts, this->array.values[i].value); 181 write(fd, line, n); 182 } 183 184 this->array.cnt = 0; 185 close(fd); 186 } 187 188 static __spinlock_t stats_lock; 189 190 void __push_stat( struct __stats_t * this, int64_t value, bool external, const char * name, void * handle ) { 191 if(external) lock(stats_lock __cfaabi_dbg_ctx2); 192 193 if( this->array.cnt >= CFA_STATS_ARRAY ) __flush_stat( this, name, handle ); 194 195 size_t idx = this->array.cnt; 196 this->array.cnt++; 197 198 if(external) unlock(stats_lock); 199 200 this->array.values[idx].ts = rdtscl(); 201 this->array.values[idx].value = value; 202 } 203 #endif 153 204 #endif -
libcfa/src/concurrency/stats.hfa
r0effb6a r47e000c 1 1 #pragma once 2 3 // #define CFA_STATS_ARRAY 10000 2 4 3 5 #include <stdint.h> … … 109 111 #endif 110 112 113 #if defined(CFA_STATS_ARRAY) 114 struct __stats_elem_t { 115 long long int ts; 116 int64_t value; 117 }; 118 #endif 119 111 120 struct __attribute__((aligned(128))) __stats_t { 112 121 __stats_readQ_t ready; … … 114 123 __stats_io_t io; 115 124 #endif 125 126 #if defined(CFA_STATS_ARRAY) 127 struct { 128 __stats_elem_t * values; 129 volatile size_t cnt; 130 } array; 131 #endif 132 116 133 }; 117 134 … … 119 136 void __tally_stats( struct __stats_t *, struct __stats_t * ); 120 137 void __print_stats( struct __stats_t *, int, const char *, const char *, void * ); 138 #if defined(CFA_STATS_ARRAY) 139 void __push_stat ( struct __stats_t *, int64_t value, bool external, const char * name, void * handle); 140 void __flush_stat( struct __stats_t *, const char *, void * ); 141 #else 142 static inline void __push_stat ( struct __stats_t *, int64_t, bool, const char *, void * ) {} 143 static inline void __flush_stat( struct __stats_t *, const char *, void * ) {} 144 #endif 121 145 #endif 122 146 -
libcfa/src/concurrency/thread.cfa
r0effb6a r47e000c 62 62 } 63 63 64 FORALL_DATA_INSTANCE(ThreadCancelled, (thread_t &), (thread_t)) 64 EHM_VIRTUAL_TABLE(SomeThreadCancelled, std_thread_cancelled); 65 65 66 66 forall(T &) … … 73 73 forall(T &) 74 74 const char * msg(ThreadCancelled(T) *) { 75 return "ThreadCancelled ";75 return "ThreadCancelled(...)"; 76 76 } 77 77 78 78 forall(T &) 79 79 static void default_thread_cancel_handler(ThreadCancelled(T) & ) { 80 // Improve this error message, can I do formatting? 80 81 abort( "Unhandled thread cancellation.\n" ); 81 82 } 82 83 83 forall(T & | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T))) 84 static void default_thread_cancel_handler(SomeThreadCancelled & ) { 85 // Improve this error message, can I do formatting? 86 abort( "Unhandled thread cancellation.\n" ); 87 } 88 89 forall(T & | is_thread(T) | IS_EXCEPTION(SomeThreadCancelled)) 84 90 void ?{}( thread_dtor_guard_t & this, 85 T & thrd, void(*cancelHandler)( ThreadCancelled(T)&)) {86 91 T & thrd, void(*cancelHandler)(SomeThreadCancelled &)) { 92 $monitor * m = get_monitor(thrd); 87 93 $thread * desc = get_thread(thrd); 88 94 89 95 // Setup the monitor guard 90 96 void (*dtor)(T& mutex this) = ^?{}; 91 bool join = cancelHandler != (void(*)( ThreadCancelled(T)&))0;97 bool join = cancelHandler != (void(*)(SomeThreadCancelled&))0; 92 98 (this.mg){&m, (void(*)())dtor, join}; 93 99 … … 103 109 } 104 110 desc->state = Cancelled; 105 void(*defaultResumptionHandler)( ThreadCancelled(T) &) =111 void(*defaultResumptionHandler)(SomeThreadCancelled &) = 106 112 join ? cancelHandler : default_thread_cancel_handler; 107 113 108 ThreadCancelled(T) except;109 114 // TODO: Remove explitate vtable set once trac#186 is fixed. 110 except.virtual_table = &get_exception_vtable(&except); 115 SomeThreadCancelled except; 116 except.virtual_table = &std_thread_cancelled; 111 117 except.the_thread = &thrd; 112 118 except.the_exception = __cfaehm_cancellation_exception( cancellation ); 113 throwResume except; 119 // Why is this cast required? 120 throwResume (SomeThreadCancelled &)except; 114 121 115 122 except.the_exception->virtual_table->free( except.the_exception ); … … 158 165 159 166 //----------------------------------------------------------------------------- 160 forall(T & | is_thread(T) | IS_RESUMPTION_EXCEPTION( ThreadCancelled, (T)))167 forall(T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(SomeThreadCancelled)) 161 168 T & join( T & this ) { 162 169 thread_dtor_guard_t guard = { this, defaultResumptionHandler }; -
libcfa/src/concurrency/thread.hfa
r0effb6a r47e000c 32 32 }; 33 33 34 FORALL_DATA_EXCEPTION(ThreadCancelled, (thread_t &), (thread_t)) ( 34 EHM_EXCEPTION(SomeThreadCancelled) ( 35 void * the_thread; 36 exception_t * the_exception; 37 ); 38 39 EHM_EXTERN_VTABLE(SomeThreadCancelled, std_thread_cancelled); 40 41 EHM_FORALL_EXCEPTION(ThreadCancelled, (thread_t &), (thread_t)) ( 35 42 thread_t * the_thread; 36 43 exception_t * the_exception; … … 79 86 }; 80 87 81 forall( T & | is_thread(T) | IS_EXCEPTION( ThreadCancelled, (T)) )82 void ?{}( thread_dtor_guard_t & this, T & thrd, void(*)( ThreadCancelled(T)&) );88 forall( T & | is_thread(T) | IS_EXCEPTION(SomeThreadCancelled) ) 89 void ?{}( thread_dtor_guard_t & this, T & thrd, void(*)(SomeThreadCancelled &) ); 83 90 void ^?{}( thread_dtor_guard_t & this ); 84 91 … … 125 132 //---------- 126 133 // join 127 forall( T & | is_thread(T) | IS_RESUMPTION_EXCEPTION( ThreadCancelled, (T)) )134 forall( T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(SomeThreadCancelled) ) 128 135 T & join( T & this ); 129 136 -
libcfa/src/exception.c
r0effb6a r47e000c 10 10 // Created On : Mon Jun 26 15:13:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Oct 27 16:27:00 202013 // Update Count : 3 512 // Last Modified On : Wed Feb 24 13:40:00 2021 13 // Update Count : 36 14 14 // 15 15 … … 26 26 #include "concurrency/invoke.h" 27 27 #include "stdhdr/assert.h" 28 #include "virtual.h" 28 29 29 30 #if defined( __ARM_ARCH ) … … 46 47 const _Unwind_Exception_Class __cfaehm_exception_class = 0x4c50575500414643; 47 48 48 // Base exception vtable is abstract, you should not have base exceptions. 49 struct __cfaehm_base_exception_t_vtable 50 ___cfaehm_base_exception_t_vtable_instance = { 51 .parent = NULL, 52 .size = 0, 53 .copy = NULL, 54 .free = NULL, 55 .msg = NULL 49 // Base Exception type id: 50 struct __cfa__parent_vtable __cfatid_exception_t = { 51 NULL, 56 52 }; 57 53 -
libcfa/src/exception.h
r0effb6a r47e000c 10 10 // Created On : Mon Jun 26 15:11:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : T ue Oct 27 14:45:00 202013 // Update Count : 1 112 // Last Modified On : Thr Apr 8 15:20:00 2021 13 // Update Count : 12 14 14 // 15 15 … … 29 29 struct __cfaehm_base_exception_t; 30 30 typedef struct __cfaehm_base_exception_t exception_t; 31 struct __cfa__parent_vtable; 31 32 struct __cfaehm_base_exception_t_vtable { 32 const struct __cfa ehm_base_exception_t_vtable * parent;33 const struct __cfa__parent_vtable * __cfavir_typeid; 33 34 size_t size; 34 35 void (*copy)(struct __cfaehm_base_exception_t *this, … … 40 41 struct __cfaehm_base_exception_t_vtable const * virtual_table; 41 42 }; 42 extern struct __cfaehm_base_exception_t_vtable 43 ___cfaehm_base_exception_t_vtable_instance; 43 extern struct __cfa__parent_vtable __cfatid_exception_t; 44 44 45 45 … … 104 104 /* The first field must be a pointer to a virtual table. 105 105 * That virtual table must be a decendent of the base exception virtual table. 106 * The virtual table must point at the prober type-id. 107 * None of these can be enforced in an assertion. 106 108 */ 107 virtualT const & get_exception_vtable(exceptT *);108 // Always returns the virtual table for this type (associated types hack).109 109 }; 110 110 -
libcfa/src/exception.hfa
r0effb6a r47e000c 10 10 // Created On : Thu Apr 7 10:25:00 2020 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : T ue Aug 4 16:22:00 202013 // Update Count : 312 // Last Modified On : Thr Apr 8 15:16:00 2021 13 // Update Count : 4 14 14 // 15 15 … … 18 18 // ----------------------------------------------------------------------------------------------- 19 19 20 // TRIVIAL_EXCEPTION_DECLARATION(exception_name); 21 // Declare a trivial exception, one that adds no fields or features. 22 // This will make the exception visible and may go in a .hfa or .cfa file. 23 #define TRIVIAL_EXCEPTION_DECLARATION(...) \ 24 _EXC_DISPATCH(_TRIVIAL_EXCEPTION_DECLARATION, __VA_ARGS__) 20 // EHM_EXCEPTION(exception_name)(fields...); 21 // Create an exception (a virtual structure that inherits from exception_t) 22 // with the given name and fields. 23 #define EHM_EXCEPTION(exception_name) \ 24 _EHM_TYPE_ID_STRUCT(exception_name, ); \ 25 _EHM_TYPE_ID_VALUE(exception_name, ); \ 26 _EHM_VIRTUAL_TABLE_STRUCT(exception_name, , ); \ 27 _EHM_EXCEPTION_STRUCT(exception_name, , ) 25 28 26 // TRIVIAL_EXCEPTION_INSTANCE(exception_name);27 // Create the trival exception. This must be used exactly once and should be used in a .cfa file,28 // as it creates the unique instance of the virtual table. 29 #define TRIVIAL_EXCEPTION_INSTANCE(...) _EXC_DISPATCH(_TRIVIAL_EXCEPTION_INSTANCE, __VA_ARGS__)29 // EHM_EXTERN_VTABLE(exception_name, table_name); 30 // Forward declare a virtual table called table_name for exception_name type. 31 #define EHM_EXTERN_VTABLE(exception_name, table_name) \ 32 _EHM_EXTERN_VTABLE(exception_name, , table_name) 30 33 31 // TRIVIAL_EXCEPTION(exception_name[, parent_name]); 32 // Does both of the above, a short hand if the exception is only used in one .cfa file. 33 // For legacy reasons this is the only one that official supports having a parent other than the 34 // base exception. This feature may be removed or changed. 35 #define TRIVIAL_EXCEPTION(...) \ 36 _EXC_DISPATCH(_TRIVIAL_EXCEPTION_DECLARATION, __VA_ARGS__); \ 37 _EXC_DISPATCH(_TRIVIAL_EXCEPTION_INSTANCE, __VA_ARGS__) 34 // EHM_VIRTUAL_TABLE(exception_name, table_name); 35 // Define a virtual table called table_name for exception_name type. 36 #define EHM_VIRTUAL_TABLE(exception_name, table_name) \ 37 _EHM_DEFINE_COPY(exception_name, ) \ 38 _EHM_DEFINE_MSG(exception_name, ) \ 39 _EHM_VIRTUAL_TABLE(exception_name, , table_name) 38 40 39 // FORALL_TRIVIAL_EXCEPTION(exception_name, (assertions...), (parameters...)); 40 // Forward declare a polymorphic but otherwise trivial exception type. You must provide the entire 41 // assertion list (exactly what would go in the forall clause) and parameters list (only the 42 // parameter names from the assertion list, same order and comma seperated). This should be 43 // visible where ever use the exception. This just generates the polymorphic framework, see 44 // POLY_VTABLE_DECLARATION to allow instantiations. 45 #define FORALL_TRIVIAL_EXCEPTION(exception_name, assertions, parameters) \ 46 _FORALL_TRIVIAL_EXCEPTION(exception_name, __cfaehm_base_exception_t, assertions, parameters, ) 41 // EHM_FORALL_EXCEPTION(exception_name, (assertions), (parameters))(fields...); 42 // As EHM_EXCEPTION but for polymorphic types instead of monomorphic ones. 43 // The assertions list should include all polymorphic parameters and 44 // assertions inside a parentisized list. Parameters should include all the 45 // polymorphic parameter names inside a parentisized list (same order). 46 #define EHM_FORALL_EXCEPTION(exception_name, assertions, parameters) \ 47 _EHM_TYPE_ID_STRUCT(exception_name, forall assertions); \ 48 _EHM_VIRTUAL_TABLE_STRUCT(exception_name, forall assertions, parameters); \ 49 _EHM_EXCEPTION_STRUCT(exception_name, forall assertions, parameters) 47 50 48 // FORALL_TRIVIAL_INSTANCE(exception_name, (assertions...), (parameters...)) 49 // Create the forall trivial exception. The assertion list and parameters must match. 50 // There must be exactly one use of this in a program for each exception type. This just 51 // generates the polymorphic framework, see POLY_VTABLE_INSTANCE to allow instantiations. 52 #define FORALL_TRIVIAL_INSTANCE(exception_name, assertions, parameters) \ 53 _FORALL_CTOR0_INSTANCE(exception_name, assertions, parameters) 51 // EHM_FORALL_EXTERN_VTABLE(exception_name, (arguments), table_name); 52 // As EHM_EXTERN_VTABLE but for polymorphic types instead of monomorphic ones. 53 // Arguments should be the parentisized list of polymorphic arguments. 54 #define EHM_FORALL_EXTERN_VTABLE(exception_name, arguments, table_name) \ 55 _EHM_EXTERN_VTABLE(exception_name, arguments, table_name) 54 56 55 // DATA_EXCEPTION(exception_name)(fields...); 56 // Forward declare an exception that adds fields but no features. The added fields go in the 57 // second argument list. The virtual table instance must be provided later (see VTABLE_INSTANCE). 58 #define DATA_EXCEPTION(...) _EXC_DISPATCH(_DATA_EXCEPTION, __VA_ARGS__) 57 // EHM_FORALL_VIRTUAL_TABLE(exception_name, (arguments), table_name); 58 // As EHM_VIRTUAL_TABLE but for polymorphic types instead of monomorphic ones. 59 // Arguments should be the parentisized list of polymorphic arguments. 60 #define EHM_FORALL_VIRTUAL_TABLE(exception_name, arguments, table_name) \ 61 _EHM_TYPE_ID_VALUE(exception_name, arguments); \ 62 _EHM_DEFINE_COPY(exception_name, arguments) \ 63 _EHM_DEFINE_MSG(exception_name, arguments) \ 64 _EHM_VIRTUAL_TABLE(exception_name, arguments, table_name) 59 65 60 // FORALL_DATA_EXCEPTION(exception_name, (assertions...), (parameters...))(fields...); 61 // Define a polymorphic exception that adds fields but no additional features. The assertion list 62 // and matching parameters must match. Then you can give the list of fields. This should be 63 // visible where ever you use the exception. This just generates the polymorphic framework, see 64 // POLY_VTABLE_DECLARATION to allow instantiations. 65 #define FORALL_DATA_EXCEPTION(exception_name, assertions, parameters) \ 66 _FORALL_DATA_EXCEPTION(exception_name, __cfaehm_base_exception_t, assertions, parameters, ) 66 #define EHM_TYPE_ID(exception_name) _EHM_TYPE_ID_TYPE(exception_name) 67 67 68 // FORALL_DATA_INSTANCE(exception_name, (assertions...), (parameters...)) 69 // Create a polymorphic data exception. The assertion list and parameters must match. This should 70 // appear once in each program. This just generates the polymorphic framework, see 71 // POLY_VTABLE_INSTANCE to allow instantiations. 72 #define FORALL_DATA_INSTANCE(exception_name, assertions, parameters) \ 73 _FORALL_CTOR0_INSTANCE(exception_name, assertions, parameters) 74 75 // VTABLE_DECLARATION(exception_name)([new_features...]); 76 // Declare a virtual table type for an exception with exception_name. You may also add features 77 // (fields on the virtual table) by including them in the second list. 78 #define VTABLE_DECLARATION(...) _EXC_DISPATCH(_VTABLE_DECLARATION, __VA_ARGS__) 79 80 // VTABLE_INSTANCE(exception_name)(msg [, others...]); 81 // Create the instance of the virtual table. There must be exactly one instance of a virtual table 82 // for each exception type. This fills in most of the fields of the virtual table (uses ?=? and 83 // ^?{}) but you must provide the message function and any other fields added in the declaration. 84 #define VTABLE_INSTANCE(...) _EXC_DISPATCH(_VTABLE_INSTANCE, __VA_ARGS__) 85 86 // FORALL_VTABLE_DECLARATION(exception_name, (assertions...), (parameters...))([new_features...]); 87 // Declare a polymorphic virtual table type for an exception with exception_name, the given 88 // assertions and parameters. You may also add features (fields on the virtual table). This just 89 // generates the polymorphic framework, see POLY_VTABLE_DECLARATION to allow instantiations. 90 #define FORALL_VTABLE_DECLARATION(exception_name, assertions, parameters) \ 91 _FORALL_VTABLE_DECLARATION(exception_name, __cfaehm_base_exception_t, assertions, parameters, ) 92 93 // POLY_VTABLE_DECLARATION(exception_name, types...); 94 // Declares that an instantiation for this exception exists for the given types. This should be 95 // visible anywhere you use the instantiation of the exception is used. 96 #define POLY_VTABLE_DECLARATION(exception_name, ...) \ 97 VTABLE_TYPE(exception_name)(__VA_ARGS__) const & get_exception_vtable(exception_name(__VA_ARGS__) *); \ 98 extern VTABLE_TYPE(exception_name)(__VA_ARGS__) VTABLE_NAME(exception_name) 99 100 // POLY_VTABLE_INSTANCE(exception_name, types...)(msg [, others...]); 101 // Creates an instantiation for the given exception for the given types. This should occur only 102 // once in the entire program. You must fill in all features, message and any others given in the 103 // initial declaration. 104 #define POLY_VTABLE_INSTANCE(exception_name, ...) \ 105 _POLY_VTABLE_INSTANCE(exception_name, __cfaehm_base_exception_t, __VA_ARGS__) 106 107 // VTABLE_TYPE(exception_name) | VTABLE_NAME(exception_name) 108 // Get the name of the vtable type or the name of the vtable instance for an exception type. 109 #define VTABLE_TYPE(exception_name) struct _GLUE2(exception_name,_vtable) 110 #define VTABLE_NAME(exception_name) _GLUE3(_,exception_name,_vtable_instance) 111 112 // VTABLE_FIELD(exception_name); 113 // FORALL_VTABLE_FIELD(exception_name, (parameters-or-types)); 114 // The declaration of the virtual table field. Should be the first declaration in a virtual type. 115 #define VTABLE_FIELD(exception_name) VTABLE_TYPE(exception_name) const * virtual_table 116 #define FORALL_VTABLE_FIELD(exception_name, parameters) \ 117 VTABLE_TYPE(exception_name) parameters const * virtual_table 118 119 // VTABLE_INIT(object_reference, exception_name); 120 // Sets a virtual table field on an object to the virtual table instance for the type. 121 #define VTABLE_INIT(this, exception_name) (this).virtual_table = &VTABLE_NAME(exception_name) 122 123 // VTABLE_ASSERTION(exception_name, (parameters...)) 124 // The assertion that there is an instantiation of the vtable for the exception and types. 125 #define VTABLE_ASSERTION(exception_name, parameters) \ 126 { VTABLE_TYPE(exception_name) parameters VTABLE_NAME(exception_name); } 68 #define EHM_MATCH_ALL __cfa__parent_vtable 127 69 128 70 // IS_EXCEPTION(exception_name [, (...parameters)]) … … 135 77 #define IS_TERMINATION_EXCEPTION(...) _IS_EXCEPTION(is_termination_exception, __VA_ARGS__, , ~) 136 78 137 // All internal helper macros begin with an underscore. 138 #define _CLOSE(...) __VA_ARGS__ } 139 #define _GLUE2(left, right) left##right 140 #define _GLUE3(left, middle, right) left##middle##right 141 #define _EXC_DISPATCH(to, ...) to(__VA_ARGS__,__cfaehm_base_exception_t,) 142 #define _UNPACK(...) __VA_ARGS__ 79 // Macros starting with a leading underscore are internal. 143 80 144 #define _TRIVIAL_EXCEPTION_DECLARATION(exception_name, parent_name, ...) \ 145 _VTABLE_DECLARATION(exception_name, parent_name)(); \ 146 struct exception_name { \ 147 VTABLE_FIELD(exception_name); \ 148 }; \ 149 void ?{}(exception_name & this); \ 150 const char * _GLUE2(exception_name,_msg)(exception_name * this) 81 // Create an exception type definition. must be tailing, can be polymorphic. 82 #define _EHM_EXCEPTION_STRUCT(exception_name, forall_clause, parameters) \ 83 forall_clause struct exception_name { \ 84 _EHM_VTABLE_TYPE(exception_name) parameters const * virtual_table; \ 85 _CLOSE 151 86 152 #define _TRIVIAL_EXCEPTION_INSTANCE(exception_name, parent_name, ...) \ 153 void ?{}(exception_name & this) { \ 154 VTABLE_INIT(this, exception_name); \ 155 } \ 156 const char * _GLUE2(exception_name,_msg)(exception_name * this) { \ 157 return #exception_name; \ 158 } \ 159 _VTABLE_INSTANCE(exception_name, parent_name,)(_GLUE2(exception_name,_msg)) 87 // Create a (possibly polymorphic) virtual table forward declaration. 88 #define _EHM_EXTERN_VTABLE(exception_name, arguments, table_name) \ 89 extern const _EHM_VTABLE_TYPE(exception_name) arguments table_name 160 90 161 #define _FORALL_TRIVIAL_EXCEPTION(exception_name, parent_name, assertions, \ 162 parameters, parent_parameters) \ 163 _FORALL_VTABLE_DECLARATION(exception_name, parent_name, assertions, \ 164 parameters, parent_parameters)(); \ 165 forall assertions struct exception_name { \ 166 FORALL_VTABLE_FIELD(exception_name, parameters); \ 167 }; \ 168 _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters) 169 170 #define _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters) \ 171 forall(_UNPACK assertions | \ 172 is_exception(exception_name parameters, VTABLE_TYPE(exception_name) parameters)) \ 173 void ?{}(exception_name parameters & this) 174 175 #define _FORALL_CTOR0_INSTANCE(exception_name, assertions, parameters) \ 176 _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters) { \ 177 (this).virtual_table = &get_exception_vtable(&this); \ 91 // Create a (possibly polymorphic) virtual table definition. 92 #define _EHM_VIRTUAL_TABLE(exception_type, arguments, table_name) \ 93 const _EHM_VTABLE_TYPE(exception_type) arguments table_name @= { \ 94 .__cfavir_typeid : &_EHM_TYPE_ID_NAME(exception_type), \ 95 .size : sizeof(struct exception_type arguments), \ 96 .copy : copy, \ 97 .^?{} : ^?{}, \ 98 .msg : msg, \ 178 99 } 179 100 180 #define _DATA_EXCEPTION(exception_name, parent_name, ...) \ 181 _VTABLE_DECLARATION(exception_name, parent_name)(); \ 182 struct exception_name { \ 183 VTABLE_FIELD(exception_name); \ 184 _CLOSE 101 // Create a (possibly polymorphic) copy function from an assignment operator. 102 #define _EHM_DEFINE_FORALL_COPY(exception_name, forall_clause, parameters) \ 103 forall_clause void copy(exception_name parameters * this, \ 104 exception_name parameters * that) { \ 105 *this = *that; \ 106 } 185 107 186 #define _FORALL_DATA_EXCEPTION(exception_name, parent_name, \ 187 assertions, parameters, parent_parameters) \ 188 _FORALL_VTABLE_DECLARATION(exception_name, parent_name, \ 189 assertions, parameters, parent_parameters)(); \ 190 _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters); \ 191 forall assertions struct exception_name { \ 192 FORALL_VTABLE_FIELD(exception_name, parameters); \ 193 _CLOSE 108 #define _EHM_DEFINE_COPY(exception_name, arguments) \ 109 void copy(exception_name arguments * this, exception_name arguments * that) { \ 110 *this = *that; \ 111 } 194 112 195 #define _VTABLE_DECLARATION(exception_name, parent_name, ...) \ 196 struct exception_name; \ 197 VTABLE_TYPE(exception_name); \ 198 VTABLE_TYPE(exception_name) const & get_exception_vtable(exception_name *); \ 199 extern VTABLE_TYPE(exception_name) VTABLE_NAME(exception_name); \ 200 VTABLE_TYPE(exception_name) { \ 201 VTABLE_TYPE(parent_name) const * parent; \ 202 size_t size; \ 203 void (*copy)(exception_name * this, exception_name * other); \ 204 void (*^?{})(exception_name & this); \ 205 const char * (*msg)(exception_name * this); \ 206 _CLOSE 113 // Create a (possibly polymorphic) msg function 114 #define _EHM_DEFINE_FORALL_MSG(exception_name, forall_clause, parameters) \ 115 forall_clause const char * msg(exception_name parameters * this) { \ 116 return #exception_name #parameters; \ 117 } 207 118 208 #define _VTABLE_INSTANCE(exception_name, parent_name, ...) \ 209 VTABLE_TYPE(exception_name) const & get_exception_vtable(exception_name *) { \ 210 return VTABLE_NAME(exception_name); \ 211 } \ 212 void _GLUE2(exception_name,_copy)(exception_name * this, exception_name * other) { \ 213 *this = *other; \ 214 } \ 215 VTABLE_TYPE(exception_name) VTABLE_NAME(exception_name) @= { \ 216 &VTABLE_NAME(parent_name), sizeof(exception_name), \ 217 _GLUE2(exception_name,_copy), ^?{}, \ 218 _CLOSE 119 #define _EHM_DEFINE_MSG(exception_name, arguments) \ 120 const char * msg(exception_name arguments * this) { \ 121 return #exception_name #arguments; \ 122 } 219 123 220 #define _FORALL_VTABLE_DECLARATION(exception_name, parent_name, assertions, \ 221 parameters, parent_parameters) \ 222 forall assertions struct exception_name; \ 223 forall assertions VTABLE_TYPE(exception_name) { \ 224 VTABLE_TYPE(parent_name) parent_parameters const * parent; \ 124 // Produces the C compatable name of the virtual table type for a virtual type. 125 #define _EHM_VTABLE_TYPE(type_name) struct _GLUE2(type_name,_vtable) 126 127 // Create the vtable type for exception name. 128 #define _EHM_VIRTUAL_TABLE_STRUCT(exception_name, forall_clause, parameters) \ 129 forall_clause struct exception_name; \ 130 forall_clause _EHM_VTABLE_TYPE(exception_name) { \ 131 _EHM_TYPE_ID_TYPE(exception_name) parameters const * __cfavir_typeid; \ 225 132 size_t size; \ 226 133 void (*copy)(exception_name parameters * this, exception_name parameters * other); \ 227 134 void (*^?{})(exception_name parameters & this); \ 228 135 const char * (*msg)(exception_name parameters * this); \ 229 _CLOSE136 } 230 137 231 #define _POLY_VTABLE_INSTANCE(exception_name, parent_name, ...) \ 232 extern VTABLE_TYPE(exception_name)(__VA_ARGS__) VTABLE_NAME(exception_name); \ 233 VTABLE_TYPE(exception_name)(__VA_ARGS__) const & get_exception_vtable( \ 234 exception_name(__VA_ARGS__) *) { \ 235 return VTABLE_NAME(exception_name); \ 236 } \ 237 void _GLUE2(exception_name,_copy)( \ 238 exception_name(__VA_ARGS__) * this, exception_name(__VA_ARGS__) * other) { \ 239 *this = *other; \ 240 } \ 241 VTABLE_TYPE(exception_name)(__VA_ARGS__) VTABLE_NAME(exception_name) @= { \ 242 &VTABLE_NAME(parent_name), sizeof(exception_name(__VA_ARGS__)), \ 243 _GLUE2(exception_name,_copy), ^?{}, \ 244 _CLOSE 138 // Define the function required to satify the trait for exceptions. 139 #define _EHM_TRAIT_FUNCTION(exception_name, forall_clause, parameters) \ 140 forall_clause inline void mark_exception( \ 141 exception_name parameters const &, \ 142 _EHM_VTABLE_TYPE(exception_name) parameters const &) {} \ 143 144 #define _EHM_TRAIT_FUNCTION2(exception_name, forall_clause, parameters) \ 145 forall_clause _EHM_VTABLE_TYPE(exception_name) parameters const & \ 146 get_exception_vtable(exception_name parameters const & this) 147 148 #define __EHM_TRAIT_FUNCTION(exception_name, forall_clause, parameters) \ 149 forall_clause inline _EHM_VTABLE_TYPE(exception_name) parameters const & \ 150 get_exception_vtable(exception_name parameters const & this) { \ 151 /* This comes before the structure definition, but we know the offset. */ \ 152 /* return (_EHM_VTABLE_TYPE(exception_name) parameters const &)this; */ \ 153 assert(false); \ 154 } 155 156 // Generates a new type-id structure. This is used to mangle the name of the 157 // type-id instance so it also includes polymorphic information. Must be the 158 // direct decendent of exception_t. 159 // The second field is used to recover type information about the exception. 160 #define _EHM_TYPE_ID_STRUCT(exception_name, forall_clause) \ 161 forall_clause _EHM_TYPE_ID_TYPE(exception_name) { \ 162 __cfa__parent_vtable const * parent; \ 163 } 164 165 // Generate a new type-id value. 166 #define _EHM_TYPE_ID_VALUE(exception_name, arguments) \ 167 __attribute__(( section(".gnu.linkonce." "__cfatid_" #exception_name) )) \ 168 _EHM_TYPE_ID_TYPE(exception_name) arguments const \ 169 _EHM_TYPE_ID_NAME(exception_name) = { \ 170 &__cfatid_exception_t, \ 171 } 172 173 // _EHM_TYPE_ID_STRUCT and _EHM_TYPE_ID_VALUE are the two that would need to 174 // be updated to extend the hierarchy if we are still using macros when that 175 // is added. 176 177 // Produce the C compatable name of the type-id type for an exception type. 178 #define _EHM_TYPE_ID_TYPE(exception_name) \ 179 struct _GLUE2(__cfatid_struct_, exception_name) 180 181 // Produce the name of the instance of the type-id for an exception type. 182 #define _EHM_TYPE_ID_NAME(exception_name) _GLUE2(__cfatid_,exception_name) 245 183 246 184 #define _IS_EXCEPTION(kind, exception_name, parameters, ...) \ 247 kind(exception_name parameters, VTABLE_TYPE(exception_name) parameters) 185 kind(exception_name parameters, _EHM_VTABLE_TYPE(exception_name) parameters) 186 187 // Internal helper macros: 188 #define _CLOSE(...) __VA_ARGS__ } 189 #define _GLUE2(left, right) left##right -
libcfa/src/fstream.cfa
r0effb6a r47e000c 321 321 322 322 323 EHM_VIRTUAL_TABLE(Open_Failure, Open_Failure_main_table); 323 324 void ?{}( Open_Failure & this, ofstream & ostream ) { 324 VTABLE_INIT(this, Open_Failure);325 this.virtual_table = &Open_Failure_main_table; 325 326 this.ostream = &ostream; 326 327 this.tag = 1; 327 328 } 328 329 void ?{}( Open_Failure & this, ifstream & istream ) { 329 VTABLE_INIT(this, Open_Failure);330 this.virtual_table = &Open_Failure_main_table; 330 331 this.istream = &istream; 331 332 this.tag = 0; 332 333 } 333 const char * Open_Failure_msg(Open_Failure * this) {334 return "Open_Failure";335 }336 VTABLE_INSTANCE(Open_Failure)(Open_Failure_msg);337 334 void throwOpen_Failure( ofstream & ostream ) { 338 335 Open_Failure exc = { ostream }; -
libcfa/src/fstream.hfa
r0effb6a r47e000c 133 133 134 134 135 DATA_EXCEPTION(Open_Failure)(135 EHM_EXCEPTION(Open_Failure)( 136 136 union { 137 137 ofstream * ostream; -
libcfa/src/virtual.c
r0effb6a r47e000c 15 15 16 16 #include "virtual.h" 17 #include "assert.h" 17 18 18 19 int __cfa__is_parent( struct __cfa__parent_vtable const * parent, 19 20 struct __cfa__parent_vtable const * child ) { 21 assert( child ); 20 22 do { 21 23 if ( parent == child ) … … 28 30 void * __cfa__virtual_cast( struct __cfa__parent_vtable const * parent, 29 31 struct __cfa__parent_vtable const * const * child ) { 32 assert( child ); 30 33 return (__cfa__is_parent(parent, *child)) ? (void *)child : (void *)0; 31 34 }
Note: See TracChangeset
for help on using the changeset viewer.