Changes in / [fe63ae6:56c8b86]
- Files:
-
- 43 edited
-
libcfa/src/concurrency/coroutine.cfa (modified) (2 diffs)
-
libcfa/src/concurrency/coroutine.hfa (modified) (2 diffs)
-
libcfa/src/concurrency/kernel.cfa (modified) (3 diffs)
-
libcfa/src/concurrency/kernel/startup.cfa (modified) (3 diffs)
-
libcfa/src/concurrency/stats.cfa (modified) (3 diffs)
-
libcfa/src/concurrency/stats.hfa (modified) (4 diffs)
-
libcfa/src/concurrency/thread.cfa (modified) (4 diffs)
-
libcfa/src/concurrency/thread.hfa (modified) (3 diffs)
-
libcfa/src/exception.c (modified) (3 diffs)
-
libcfa/src/exception.h (modified) (4 diffs)
-
libcfa/src/exception.hfa (modified) (3 diffs)
-
libcfa/src/fstream.cfa (modified) (1 diff)
-
libcfa/src/fstream.hfa (modified) (1 diff)
-
libcfa/src/virtual.c (modified) (2 diffs)
-
src/AST/Expr.cpp (modified) (1 diff)
-
src/AST/Expr.hpp (modified) (1 diff)
-
src/Concurrency/Keywords.cc (modified) (8 diffs)
-
src/SynTree/Constant.cc (modified) (1 diff)
-
src/SynTree/Constant.h (modified) (1 diff)
-
src/Virtual/ExpandCasts.cc (modified) (7 diffs)
-
src/Virtual/Tables.cc (modified) (4 diffs)
-
src/Virtual/Tables.h (modified) (3 diffs)
-
tests/exceptions/.expect/resume-threads.txt (modified) (1 diff)
-
tests/exceptions/.expect/resume.txt (modified) (1 diff)
-
tests/exceptions/.expect/terminate-threads.txt (modified) (1 diff)
-
tests/exceptions/.expect/terminate.txt (modified) (1 diff)
-
tests/exceptions/cancel/coroutine.cfa (modified) (3 diffs)
-
tests/exceptions/cancel/thread.cfa (modified) (4 diffs)
-
tests/exceptions/conditional.cfa (modified) (3 diffs)
-
tests/exceptions/data-except.cfa (modified) (1 diff)
-
tests/exceptions/defaults.cfa (modified) (5 diffs)
-
tests/exceptions/finally.cfa (modified) (1 diff)
-
tests/exceptions/interact.cfa (modified) (8 diffs)
-
tests/exceptions/polymorphic.cfa (modified) (5 diffs)
-
tests/exceptions/resume.cfa (modified) (8 diffs)
-
tests/exceptions/terminate.cfa (modified) (8 diffs)
-
tests/exceptions/trash.cfa (modified) (1 diff)
-
tests/exceptions/type-check.cfa (modified) (1 diff)
-
tests/exceptions/virtual-cast.cfa (modified) (4 diffs)
-
tests/exceptions/virtual-poly.cfa (modified) (7 diffs)
-
tests/linking/exception-nothreads.cfa (modified) (1 diff)
-
tests/linking/exception-withthreads.cfa (modified) (1 diff)
-
tests/quasiKeyword.cfa (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/concurrency/coroutine.cfa
rfe63ae6 r56c8b86 46 46 47 47 //----------------------------------------------------------------------------- 48 EHM_VIRTUAL_TABLE(SomeCoroutineCancelled, std_coroutine_cancelled); 48 FORALL_DATA_INSTANCE(CoroutineCancelled, (coroutine_t &), (coroutine_t)) 49 50 forall(T &) 51 void mark_exception(CoroutineCancelled(T) *) {} 49 52 50 53 forall(T &) … … 68 71 69 72 // TODO: Remove explitate vtable set once trac#186 is fixed. 70 SomeCoroutineCancelledexcept;71 except.virtual_table = & std_coroutine_cancelled;73 CoroutineCancelled(T) except; 74 except.virtual_table = &get_exception_vtable(&except); 72 75 except.the_coroutine = &cor; 73 76 except.the_exception = except; 74 // Why does this need a cast? 75 throwResume (SomeCoroutineCancelled &)except; 77 throwResume except; 76 78 77 79 except->virtual_table->free( except ); -
libcfa/src/concurrency/coroutine.hfa
rfe63ae6 r56c8b86 22 22 //----------------------------------------------------------------------------- 23 23 // Exception thrown from resume when a coroutine stack is cancelled. 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)) ( 24 FORALL_DATA_EXCEPTION(CoroutineCancelled, (coroutine_t &), (coroutine_t)) ( 32 25 coroutine_t * the_coroutine; 33 26 exception_t * the_exception; … … 44 37 // Anything that implements this trait can be resumed. 45 38 // Anything that is resumed is a coroutine. 46 trait is_coroutine(T & | IS_RESUMPTION_EXCEPTION( SomeCoroutineCancelled)) {39 trait is_coroutine(T & | IS_RESUMPTION_EXCEPTION(CoroutineCancelled, (T))) { 47 40 void main(T & this); 48 41 $coroutine * get_coroutine(T & this); -
libcfa/src/concurrency/kernel.cfa
rfe63ae6 r56c8b86 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 );362 361 #endif 363 362 // This is case 2, the racy case, someone tried to run this thread before it finished blocking … … 377 376 #if !defined(__CFA_NO_STATISTICS__) 378 377 __tls_stats()->ready.threads.threads--; 379 __push_stat( __tls_stats(), __tls_stats()->ready.threads.threads, false, "Processor", this );380 378 #endif 381 379 … … 457 455 if( kernelTLS().this_stats ) { 458 456 __tls_stats()->ready.threads.threads++; 459 __push_stat( __tls_stats(), __tls_stats()->ready.threads.threads, false, "Processor", kernelTLS().this_processor );460 457 } 461 458 else { 462 459 __atomic_fetch_add(&cl->stats->ready.threads.threads, 1, __ATOMIC_RELAXED); 463 __push_stat( cl->stats, cl->stats->ready.threads.threads, true, "Cluster", cl );464 460 } 465 461 #endif -
libcfa/src/concurrency/kernel/startup.cfa
rfe63ae6 r56c8b86 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 #endif273 270 #endif 274 271 … … 351 348 __print_stats( &local_stats, proc->print_stats, "Processor ", proc->name, (void*)proc ); 352 349 } 353 #if defined(CFA_STATS_ARRAY)354 __flush_stat( &local_stats, "Processor", proc );355 #endif356 350 #endif 357 351 … … 621 615 __print_stats( this.stats, this.print_stats, "Cluster", this.name, (void*)&this ); 622 616 } 623 #if defined(CFA_STATS_ARRAY)624 __flush_stat( this.stats, "Cluster", &this );625 #endif626 617 free( this.stats ); 627 618 #endif -
libcfa/src/concurrency/stats.cfa
rfe63ae6 r56c8b86 5 5 #include <inttypes.h> 6 6 #include "bits/debug.hfa" 7 #include "bits/locks.hfa"8 7 #include "stats.hfa" 9 8 … … 45 44 stats->io.calls.errors.busy = 0; 46 45 stats->io.poller.sleeps = 0; 47 #endif48 49 #if defined(CFA_STATS_ARRAY)50 stats->array.values = alloc(CFA_STATS_ARRAY);51 stats->array.cnt = 0;52 46 #endif 53 47 } … … 157 151 #endif 158 152 } 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 #endif204 153 #endif -
libcfa/src/concurrency/stats.hfa
rfe63ae6 r56c8b86 1 1 #pragma once 2 3 // #define CFA_STATS_ARRAY 100004 2 5 3 #include <stdint.h> … … 111 109 #endif 112 110 113 #if defined(CFA_STATS_ARRAY)114 struct __stats_elem_t {115 long long int ts;116 int64_t value;117 };118 #endif119 120 111 struct __attribute__((aligned(128))) __stats_t { 121 112 __stats_readQ_t ready; … … 123 114 __stats_io_t io; 124 115 #endif 125 126 #if defined(CFA_STATS_ARRAY)127 struct {128 __stats_elem_t * values;129 volatile size_t cnt;130 } array;131 #endif132 133 116 }; 134 117 … … 136 119 void __tally_stats( struct __stats_t *, struct __stats_t * ); 137 120 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 #else142 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 #endif145 121 #endif 146 122 -
libcfa/src/concurrency/thread.cfa
rfe63ae6 r56c8b86 62 62 } 63 63 64 EHM_VIRTUAL_TABLE(SomeThreadCancelled, std_thread_cancelled); 64 FORALL_DATA_INSTANCE(ThreadCancelled, (thread_t &), (thread_t)) 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?81 80 abort( "Unhandled thread cancellation.\n" ); 82 81 } 83 82 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)) 83 forall(T & | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T))) 90 84 void ?{}( thread_dtor_guard_t & this, 91 T & thrd, void(*cancelHandler)( SomeThreadCancelled&)) {92 $monitor * m = get_monitor(thrd);85 T & thrd, void(*cancelHandler)(ThreadCancelled(T) &)) { 86 $monitor * m = get_monitor(thrd); 93 87 $thread * desc = get_thread(thrd); 94 88 95 89 // Setup the monitor guard 96 90 void (*dtor)(T& mutex this) = ^?{}; 97 bool join = cancelHandler != (void(*)( SomeThreadCancelled&))0;91 bool join = cancelHandler != (void(*)(ThreadCancelled(T)&))0; 98 92 (this.mg){&m, (void(*)())dtor, join}; 99 93 … … 109 103 } 110 104 desc->state = Cancelled; 111 void(*defaultResumptionHandler)( SomeThreadCancelled &) =105 void(*defaultResumptionHandler)(ThreadCancelled(T) &) = 112 106 join ? cancelHandler : default_thread_cancel_handler; 113 107 108 ThreadCancelled(T) except; 114 109 // TODO: Remove explitate vtable set once trac#186 is fixed. 115 SomeThreadCancelled except; 116 except.virtual_table = &std_thread_cancelled; 110 except.virtual_table = &get_exception_vtable(&except); 117 111 except.the_thread = &thrd; 118 112 except.the_exception = __cfaehm_cancellation_exception( cancellation ); 119 // Why is this cast required? 120 throwResume (SomeThreadCancelled &)except; 113 throwResume except; 121 114 122 115 except.the_exception->virtual_table->free( except.the_exception ); … … 165 158 166 159 //----------------------------------------------------------------------------- 167 forall(T & | is_thread(T) | IS_RESUMPTION_EXCEPTION( SomeThreadCancelled))160 forall(T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T))) 168 161 T & join( T & this ) { 169 162 thread_dtor_guard_t guard = { this, defaultResumptionHandler }; -
libcfa/src/concurrency/thread.hfa
rfe63ae6 r56c8b86 32 32 }; 33 33 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)) ( 34 FORALL_DATA_EXCEPTION(ThreadCancelled, (thread_t &), (thread_t)) ( 42 35 thread_t * the_thread; 43 36 exception_t * the_exception; … … 86 79 }; 87 80 88 forall( T & | is_thread(T) | IS_EXCEPTION( SomeThreadCancelled) )89 void ?{}( thread_dtor_guard_t & this, T & thrd, void(*)( SomeThreadCancelled&) );81 forall( T & | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T)) ) 82 void ?{}( thread_dtor_guard_t & this, T & thrd, void(*)(ThreadCancelled(T) &) ); 90 83 void ^?{}( thread_dtor_guard_t & this ); 91 84 … … 132 125 //---------- 133 126 // join 134 forall( T & | is_thread(T) | IS_RESUMPTION_EXCEPTION( SomeThreadCancelled) )127 forall( T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T)) ) 135 128 T & join( T & this ); 136 129 -
libcfa/src/exception.c
rfe63ae6 r56c8b86 10 10 // Created On : Mon Jun 26 15:13:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Feb 24 13:40:00 202113 // Update Count : 3 612 // Last Modified On : Tue Oct 27 16:27:00 2020 13 // Update Count : 35 14 14 // 15 15 … … 26 26 #include "concurrency/invoke.h" 27 27 #include "stdhdr/assert.h" 28 #include "virtual.h"29 28 30 29 #if defined( __ARM_ARCH ) … … 47 46 const _Unwind_Exception_Class __cfaehm_exception_class = 0x4c50575500414643; 48 47 49 // Base Exception type id: 50 struct __cfa__parent_vtable __cfatid_exception_t = { 51 NULL, 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 52 56 }; 53 57 -
libcfa/src/exception.h
rfe63ae6 r56c8b86 10 10 // Created On : Mon Jun 26 15:11:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : T hr Apr 8 15:20:00 202113 // Update Count : 1 212 // Last Modified On : Tue Oct 27 14:45:00 2020 13 // Update Count : 11 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;32 31 struct __cfaehm_base_exception_t_vtable { 33 const struct __cfa __parent_vtable * __cfavir_typeid;32 const struct __cfaehm_base_exception_t_vtable * parent; 34 33 size_t size; 35 34 void (*copy)(struct __cfaehm_base_exception_t *this, … … 41 40 struct __cfaehm_base_exception_t_vtable const * virtual_table; 42 41 }; 43 extern struct __cfa__parent_vtable __cfatid_exception_t; 42 extern struct __cfaehm_base_exception_t_vtable 43 ___cfaehm_base_exception_t_vtable_instance; 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.108 106 */ 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
rfe63ae6 r56c8b86 10 10 // Created On : Thu Apr 7 10:25:00 2020 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : T hr Apr 8 15:16:00 202113 // Update Count : 412 // Last Modified On : Tue Aug 4 16:22:00 2020 13 // Update Count : 3 14 14 // 15 15 … … 18 18 // ----------------------------------------------------------------------------------------------- 19 19 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, , ) 28 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) 33 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) 40 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) 50 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) 56 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) 65 66 #define EHM_TYPE_ID(exception_name) _EHM_TYPE_ID_TYPE(exception_name) 67 68 #define EHM_MATCH_ALL __cfa__parent_vtable 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__) 25 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__) 30 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__) 38 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, ) 47 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) 54 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__) 59 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, ) 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); } 69 127 70 128 // IS_EXCEPTION(exception_name [, (...parameters)]) … … 77 135 #define IS_TERMINATION_EXCEPTION(...) _IS_EXCEPTION(is_termination_exception, __VA_ARGS__, , ~) 78 136 79 // Macros starting with a leading underscore are internal. 80 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 86 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 90 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, \ 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__ 143 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) 151 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)) 160 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); \ 99 178 } 100 179 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 } 107 108 #define _EHM_DEFINE_COPY(exception_name, arguments) \ 109 void copy(exception_name arguments * this, exception_name arguments * that) { \ 110 *this = *that; \ 111 } 112 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 } 118 119 #define _EHM_DEFINE_MSG(exception_name, arguments) \ 120 const char * msg(exception_name arguments * this) { \ 121 return #exception_name #arguments; \ 122 } 123 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; \ 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 185 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 194 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 207 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 219 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; \ 132 225 size_t size; \ 133 226 void (*copy)(exception_name parameters * this, exception_name parameters * other); \ 134 227 void (*^?{})(exception_name parameters & this); \ 135 228 const char * (*msg)(exception_name parameters * this); \ 136 } 137 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) 229 _CLOSE 230 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 183 245 184 246 #define _IS_EXCEPTION(kind, 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 247 kind(exception_name parameters, VTABLE_TYPE(exception_name) parameters) -
libcfa/src/fstream.cfa
rfe63ae6 r56c8b86 321 321 322 322 323 EHM_VIRTUAL_TABLE(Open_Failure, Open_Failure_main_table);324 323 void ?{}( Open_Failure & this, ofstream & ostream ) { 325 this.virtual_table = &Open_Failure_main_table;324 VTABLE_INIT(this, Open_Failure); 326 325 this.ostream = &ostream; 327 326 this.tag = 1; 328 327 } 329 328 void ?{}( Open_Failure & this, ifstream & istream ) { 330 this.virtual_table = &Open_Failure_main_table;329 VTABLE_INIT(this, Open_Failure); 331 330 this.istream = &istream; 332 331 this.tag = 0; 333 332 } 333 const char * Open_Failure_msg(Open_Failure * this) { 334 return "Open_Failure"; 335 } 336 VTABLE_INSTANCE(Open_Failure)(Open_Failure_msg); 334 337 void throwOpen_Failure( ofstream & ostream ) { 335 338 Open_Failure exc = { ostream }; -
libcfa/src/fstream.hfa
rfe63ae6 r56c8b86 133 133 134 134 135 EHM_EXCEPTION(Open_Failure)(135 DATA_EXCEPTION(Open_Failure)( 136 136 union { 137 137 ofstream * ostream; -
libcfa/src/virtual.c
rfe63ae6 r56c8b86 15 15 16 16 #include "virtual.h" 17 #include "assert.h"18 17 19 18 int __cfa__is_parent( struct __cfa__parent_vtable const * parent, 20 19 struct __cfa__parent_vtable const * child ) { 21 assert( child );22 20 do { 23 21 if ( parent == child ) … … 30 28 void * __cfa__virtual_cast( struct __cfa__parent_vtable const * parent, 31 29 struct __cfa__parent_vtable const * const * child ) { 32 assert( child );33 30 return (__cfa__is_parent(parent, *child)) ? (void *)child : (void *)0; 34 31 } -
src/AST/Expr.cpp
rfe63ae6 r56c8b86 260 260 } 261 261 262 ConstantExpr * ConstantExpr::from_string( const CodeLocation & loc, const std::string & str ) {263 const Type * charType = new BasicType( BasicType::Char );264 // Adjust the length of the string for the terminator.265 const Expr * strSize = from_ulong( loc, str.size() + 1 );266 const Type * strType = new ArrayType( charType, strSize, FixedLen, StaticDim );267 const std::string strValue = "\"" + str + "\"";268 return new ConstantExpr( loc, strType, strValue, std::nullopt );269 }270 271 262 ConstantExpr * ConstantExpr::null( const CodeLocation & loc, const Type * ptrType ) { 272 263 return new ConstantExpr{ -
src/AST/Expr.hpp
rfe63ae6 r56c8b86 438 438 long long int intValue() const; 439 439 440 /// Generates a boolean constant of the given bool.440 /// generates a boolean constant of the given bool 441 441 static ConstantExpr * from_bool( const CodeLocation & loc, bool b ); 442 /// Generates an integer constant of the given int.442 /// generates an integer constant of the given int 443 443 static ConstantExpr * from_int( const CodeLocation & loc, int i ); 444 /// Generates an integer constant of the given unsigned long int.444 /// generates an integer constant of the given unsigned long int 445 445 static ConstantExpr * from_ulong( const CodeLocation & loc, unsigned long i ); 446 /// Generates a string constant from the given string (char type, unquoted string). 447 static ConstantExpr * from_string( const CodeLocation & loc, const std::string & string ); 448 /// Generates a null pointer value for the given type. void * if omitted. 446 /// generates a null pointer value for the given type. void * if omitted. 449 447 static ConstantExpr * null( const CodeLocation & loc, const Type * ptrType = nullptr ); 450 448 -
src/Concurrency/Keywords.cc
rfe63ae6 r56c8b86 42 42 43 43 namespace Concurrency { 44 inline static std::string getTypeIdName( std::string const & exception_name ) {45 return exception_name.empty() ? std::string() : Virtual::typeIdType( exception_name );46 }47 44 inline static std::string getVTableName( std::string const & exception_name ) { 48 return exception_name.empty() ? std::string() : Virtual::vtableTypeName( exception_name);45 return exception_name.empty() ? std::string() : Virtual::vtableTypeName(exception_name); 49 46 } 50 47 … … 78 75 type_name( type_name ), field_name( field_name ), getter_name( getter_name ), 79 76 context_error( context_error ), exception_name( exception_name ), 80 typeid_name( getTypeIdName( exception_name ) ),81 77 vtable_name( getVTableName( exception_name ) ), 82 78 needs_main( needs_main ), cast_target( cast_target ) {} … … 88 84 89 85 void handle( StructDecl * ); 90 void addTypeId( StructDecl * );91 86 void addVtableForward( StructDecl * ); 92 87 FunctionDecl * forwardDeclare( StructDecl * ); … … 104 99 const std::string context_error; 105 100 const std::string exception_name; 106 const std::string typeid_name;107 101 const std::string vtable_name; 108 102 bool needs_main; … … 112 106 FunctionDecl * dtor_decl = nullptr; 113 107 StructDecl * except_decl = nullptr; 114 StructDecl * typeid_decl = nullptr;115 108 StructDecl * vtable_decl = nullptr; 116 109 }; … … 399 392 else if ( !except_decl && exception_name == decl->name && decl->body ) { 400 393 except_decl = decl; 401 }402 else if ( !typeid_decl && typeid_name == decl->name && decl->body ) {403 typeid_decl = decl;404 394 } 405 395 else if ( !vtable_decl && vtable_name == decl->name && decl->body ) { … … 458 448 if( !dtor_decl ) SemanticError( decl, context_error ); 459 449 460 if ( !exception_name.empty() ) { 461 if( !typeid_decl ) SemanticError( decl, context_error ); 462 if( !vtable_decl ) SemanticError( decl, context_error ); 463 464 addTypeId( decl ); 465 addVtableForward( decl ); 466 } 450 addVtableForward( decl ); 467 451 FunctionDecl * func = forwardDeclare( decl ); 468 452 ObjectDecl * field = addField( decl ); … … 470 454 } 471 455 472 void ConcurrentSueKeyword::addTypeId( StructDecl * decl ) { 473 assert( typeid_decl ); 474 StructInstType typeid_type( Type::Const, typeid_decl ); 475 typeid_type.parameters.push_back( new TypeExpr( 476 new StructInstType( noQualifiers, decl ) 456 void ConcurrentSueKeyword::addVtableForward( StructDecl * decl ) { 457 if ( vtable_decl ) { 458 std::list< Expression * > poly_args = { 459 new TypeExpr( new StructInstType( noQualifiers, decl ) ), 460 }; 461 declsToAddBefore.push_back( Virtual::makeGetExceptionForward( 462 vtable_decl->makeInst( poly_args ), 463 except_decl->makeInst( poly_args ) 477 464 ) ); 478 declsToAddBefore.push_back( Virtual::makeTypeIdInstance( &typeid_type ) ); 479 } 480 481 void ConcurrentSueKeyword::addVtableForward( StructDecl * decl ) { 482 assert( vtable_decl ); 483 std::list< Expression * > poly_args = { 484 new TypeExpr( new StructInstType( noQualifiers, decl ) ), 485 }; 486 declsToAddBefore.push_back( Virtual::makeGetExceptionForward( 487 vtable_decl->makeInst( poly_args ), 488 except_decl->makeInst( poly_args ) 489 ) ); 490 declsToAddBefore.push_back( Virtual::makeVtableForward( 491 vtable_decl->makeInst( move( poly_args ) ) ) ); 465 declsToAddBefore.push_back( Virtual::makeVtableForward( 466 vtable_decl->makeInst( move( poly_args ) ) ) ); 467 // Its only an error if we want a vtable and don't have one. 468 } else if ( ! vtable_name.empty() ) { 469 SemanticError( decl, context_error ); 470 } 492 471 } 493 472 -
src/SynTree/Constant.cc
rfe63ae6 r56c8b86 42 42 } 43 43 44 Constant Constant::from_string( const std::string & str ) {45 Type * charType = new BasicType( noQualifiers, BasicType::Char );46 // Adjust the length of the string for the terminator.47 Expression * strSize = new ConstantExpr( Constant::from_ulong( str.size() + 1 ) );48 Type * strType = new ArrayType( noQualifiers, charType, strSize, false, false );49 const std::string strValue = "\"" + str + "\"";50 return Constant( strType, strValue, std::nullopt );51 }52 53 44 Constant Constant::null( Type * ptrtype ) { 54 45 if ( nullptr == ptrtype ) { -
src/SynTree/Constant.h
rfe63ae6 r56c8b86 47 47 /// generates an integer constant of the given unsigned long int 48 48 static Constant from_ulong( unsigned long i ); 49 /// generates a string constant from the given string (char type, unquoted string)50 static Constant from_string( const std::string & string );51 49 52 50 /// generates a null pointer value for the given type. void * if omitted. -
src/Virtual/ExpandCasts.cc
rfe63ae6 r56c8b86 32 32 namespace Virtual { 33 33 34 static bool is_prefix( const std::string & prefix, const std::string& entire ) {35 size_t const p_size = prefix.size();36 return (p_size < entire.size() && prefix == entire.substr(0, p_size));37 }38 39 static bool is_type_id_object( const ObjectDecl * objectDecl ) {40 const std::string & objectName = objectDecl->name;41 return is_prefix( "__cfatid_", objectName );42 }43 44 34 // Indented until the new ast code gets added. 45 35 … … 76 66 }; 77 67 68 /* Currently virtual depends on the rather brittle name matching between 69 * a (strict/explicate) virtual type, its vtable type and the vtable 70 * instance. 71 * A stronger implementation, would probably keep track of those triads 72 * and use that information to create better error messages. 73 */ 74 75 namespace { 76 77 std::string get_vtable_name( std::string const & name ) { 78 return name + "_vtable"; 79 } 80 81 std::string get_vtable_inst_name( std::string const & name ) { 82 return std::string("_") + get_vtable_name( name ) + "_instance"; 83 } 84 85 std::string get_vtable_name_root( std::string const & name ) { 86 return name.substr(0, name.size() - 7 ); 87 } 88 89 std::string get_vtable_inst_name_root( std::string const & name ) { 90 return get_vtable_name_root( name.substr(1, name.size() - 10 ) ); 91 } 92 93 bool is_vtable_inst_name( std::string const & name ) { 94 return 17 < name.size() && 95 name == get_vtable_inst_name( get_vtable_inst_name_root( name ) ); 96 } 97 98 } // namespace 99 78 100 class VirtualCastCore { 79 CastExpr * cast_to_type_id( Expression * expr, int level_of_indirection) {101 Type * pointer_to_pvt(int level_of_indirection) { 80 102 Type * type = new StructInstType( 81 103 Type::Qualifiers( Type::Const ), pvt_decl ); … … 83 105 type = new PointerType( noQualifiers, type ); 84 106 } 85 return new CastExpr( expr, type );107 return type; 86 108 } 87 109 … … 119 141 120 142 void VirtualCastCore::premutate( ObjectDecl * objectDecl ) { 121 if ( is_type_id_object( objectDecl ) ) { 122 // Multiple definitions should be fine because of linkonce. 123 indexer.insert( objectDecl ); 143 if ( is_vtable_inst_name( objectDecl->get_name() ) ) { 144 if ( ObjectDecl * existing = indexer.insert( objectDecl ) ) { 145 std::string msg = "Repeated instance of virtual table, original found at: "; 146 msg += existing->location.filename; 147 msg += ":" + toString( existing->location.first_line ); 148 SemanticError( objectDecl->location, msg ); 149 } 124 150 } 125 151 } … … 144 170 } 145 171 146 /// Get the base type from a pointer or reference. 147 const Type * getBaseType( const Type * type ) { 148 if ( auto target = dynamic_cast<const PointerType *>( type ) ) { 149 return target->base; 150 } else if ( auto target = dynamic_cast<const ReferenceType *>( type ) ) { 151 return target->base; 172 /// Get the virtual table type used in a virtual cast. 173 Type * getVirtualTableType( const VirtualCastExpr * castExpr ) { 174 const Type * objectType; 175 if ( auto target = dynamic_cast<const PointerType *>( castExpr->result ) ) { 176 objectType = target->base; 177 } else if ( auto target = dynamic_cast<const ReferenceType *>( castExpr->result ) ) { 178 objectType = target->base; 152 179 } else { 153 return nullptr; 154 } 155 } 156 157 /* Attempt to follow the "head" field of the structure to get the... 158 * Returns nullptr on error, otherwise owner must free returned node. 159 */ 160 StructInstType * followHeadPointerType( 161 const StructInstType * oldType, 162 const std::string& fieldName, 163 const CodeLocation& errorLocation ) { 164 165 // First section of the function is all about trying to fill this variable in. 166 StructInstType * newType = nullptr; 167 { 168 const StructDecl * oldDecl = oldType->baseStruct; 169 assert( oldDecl ); 170 171 // Helper function for throwing semantic errors. 172 auto throwError = [&fieldName, &errorLocation, &oldDecl](const std::string& message) { 173 const std::string& context = "While following head pointer of " + 174 oldDecl->name + " named '" + fieldName + "': "; 175 SemanticError( errorLocation, context + message ); 176 }; 177 178 if ( oldDecl->members.empty() ) { 179 throwError( "Type has no fields." ); 180 } 181 const Declaration * memberDecl = oldDecl->members.front(); 180 castError( castExpr, "Virtual cast type must be a pointer or reference type." ); 181 } 182 assert( objectType ); 183 184 const StructInstType * structType = dynamic_cast<const StructInstType *>( objectType ); 185 if ( nullptr == structType ) { 186 castError( castExpr, "Virtual cast type must refer to a structure type." ); 187 } 188 const StructDecl * structDecl = structType->baseStruct; 189 assert( structDecl ); 190 191 const ObjectDecl * fieldDecl = nullptr; 192 if ( 0 < structDecl->members.size() ) { 193 const Declaration * memberDecl = structDecl->members.front(); 182 194 assert( memberDecl ); 183 const ObjectDecl * fieldDecl = dynamic_cast<const ObjectDecl *>( memberDecl ); 184 assert( fieldDecl ); 185 if ( fieldName != fieldDecl->name ) { 186 throwError( "Head field did not have expected name." ); 187 } 188 189 const Type * fieldType = fieldDecl->type; 190 if ( nullptr == fieldType ) { 191 throwError( "Could not get head field." ); 192 } 193 const PointerType * ptrType = dynamic_cast<const PointerType *>( fieldType ); 194 if ( nullptr == ptrType ) { 195 throwError( "First field is not a pointer type." ); 196 } 197 assert( ptrType->base ); 198 newType = dynamic_cast<StructInstType *>( ptrType->base ); 199 if ( nullptr == newType ) { 200 throwError( "First field does not point to a structure type." ); 201 } 202 } 203 204 // Now we can look into copying it. 205 newType = newType->clone(); 206 if ( ! oldType->parameters.empty() ) { 207 deleteAll( newType->parameters ); 208 newType->parameters.clear(); 209 cloneAll( oldType->parameters, newType->parameters ); 210 } 211 return newType; 212 } 213 214 /// Get the type-id type from a virtual type. 215 StructInstType * getTypeIdType( const Type * type, const CodeLocation& errorLocation ) { 216 const StructInstType * typeInst = dynamic_cast<const StructInstType *>( type ); 217 if ( nullptr == typeInst ) { 218 return nullptr; 219 } 220 StructInstType * tableInst = 221 followHeadPointerType( typeInst, "virtual_table", errorLocation ); 222 if ( nullptr == tableInst ) { 223 return nullptr; 224 } 225 StructInstType * typeIdInst = 226 followHeadPointerType( tableInst, "__cfavir_typeid", errorLocation ); 227 delete tableInst; 228 return typeIdInst; 195 fieldDecl = dynamic_cast<const ObjectDecl *>( memberDecl ); 196 if ( fieldDecl && fieldDecl->name != "virtual_table" ) { 197 fieldDecl = nullptr; 198 } 199 } 200 if ( nullptr == fieldDecl ) { 201 castError( castExpr, "Virtual cast type must have a leading virtual_table field." ); 202 } 203 const PointerType * fieldType = dynamic_cast<const PointerType *>( fieldDecl->type ); 204 if ( nullptr == fieldType ) { 205 castError( castExpr, "Virtual cast type virtual_table field is not a pointer." ); 206 } 207 assert( fieldType->base ); 208 auto virtualStructType = dynamic_cast<const StructInstType *>( fieldType->base ); 209 assert( virtualStructType ); 210 211 // Here is the type, but if it is polymorphic it will have lost information. 212 // (Always a clone so that it may always be deleted.) 213 StructInstType * virtualType = virtualStructType->clone(); 214 if ( ! structType->parameters.empty() ) { 215 deleteAll( virtualType->parameters ); 216 virtualType->parameters.clear(); 217 cloneAll( structType->parameters, virtualType->parameters ); 218 } 219 return virtualType; 229 220 } 230 221 … … 237 228 assert( pvt_decl ); 238 229 239 const Type * base_type = getBaseType( castExpr->result ); 240 if ( nullptr == base_type ) { 241 castError( castExpr, "Virtual cast target must be a pointer or reference type." ); 242 } 243 const Type * type_id_type = getTypeIdType( base_type, castLocation( castExpr ) ); 244 if ( nullptr == type_id_type ) { 245 castError( castExpr, "Ill formed virtual cast target type." ); 246 } 247 ObjectDecl * type_id = indexer.lookup( type_id_type ); 248 delete type_id_type; 249 if ( nullptr == type_id ) { 250 castError( castExpr, "Virtual cast does not target a virtual type." ); 230 const Type * vtable_type = getVirtualTableType( castExpr ); 231 ObjectDecl * table = indexer.lookup( vtable_type ); 232 if ( nullptr == table ) { 233 SemanticError( castLocation( castExpr ), 234 "Could not find virtual table instance." ); 251 235 } 252 236 253 237 Expression * result = new CastExpr( 254 238 new ApplicationExpr( VariableExpr::functionPointer( vcast_decl ), { 255 cast_to_type_id( new AddressExpr( new VariableExpr( type_id ) ), 1 ), 256 cast_to_type_id( castExpr->get_arg(), 2 ), 239 new CastExpr( 240 new AddressExpr( new VariableExpr( table ) ), 241 pointer_to_pvt(1) 242 ), 243 new CastExpr( 244 castExpr->get_arg(), 245 pointer_to_pvt(2) 246 ) 257 247 } ), 258 248 castExpr->get_result()->clone() … … 262 252 castExpr->set_result( nullptr ); 263 253 delete castExpr; 254 delete vtable_type; 264 255 return result; 265 256 } -
src/Virtual/Tables.cc
rfe63ae6 r56c8b86 10 10 // Created On : Mon Aug 31 11:11:00 2020 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : T hr Apr 8 15:51:00 202113 // Update Count : 112 // Last Modified On : Tue Sep 3 14:56:00 2020 13 // Update Count : 0 14 14 // 15 15 … … 22 22 namespace Virtual { 23 23 24 std::string typeIdType( std::string const & type_name ) {25 return "__cfatid_struct_" + type_name;26 }27 28 std::string typeIdName( std::string const & type_name ) {29 return "__cfatid_" + type_name;30 }31 32 static std::string typeIdTypeToInstance( std::string const & type_name ) {33 return typeIdName(type_name.substr(16));34 }35 36 24 std::string vtableTypeName( std::string const & name ) { 37 25 return name + "_vtable"; 38 }39 40 std::string baseTypeName( std::string const & vtable_type_name ) {41 return vtable_type_name.substr(0, vtable_type_name.size() - 7);42 26 } 43 27 … … 97 81 inits.push_back( 98 82 new SingleInit( new AddressExpr( new NameExpr( parentInstance ) ) ) ); 99 } else if ( std::string( "__cfavir_typeid" ) == field->name ) {100 std::string const & baseType = baseTypeName( vtableType->name );101 std::string const & typeId = typeIdName( baseType );102 inits.push_back( new SingleInit( new AddressExpr( new NameExpr( typeId ) ) ) );103 83 } else if ( std::string( "size" ) == field->name ) { 104 84 inits.push_back( new SingleInit( new SizeofExpr( objectType->clone() ) ) ); … … 167 147 } 168 148 169 ObjectDecl * makeTypeIdForward() {170 return nullptr;171 149 } 172 173 Attribute * linkonce( const std::string & subsection ) {174 const std::string section = ".gnu.linkonce." + subsection;175 return new Attribute( "section", {176 new ConstantExpr( Constant::from_string( section ) ),177 } );178 }179 180 ObjectDecl * makeTypeIdInstance( StructInstType const * typeIdType ) {181 assert( typeIdType );182 StructInstType * type = typeIdType->clone();183 type->tq.is_const = true;184 std::string const & typeid_name = typeIdTypeToInstance( typeIdType->name );185 return new ObjectDecl(186 typeid_name,187 noStorageClasses,188 LinkageSpec::Cforall,189 /* bitfieldWidth */ nullptr,190 type,191 new ListInit( { new SingleInit(192 new AddressExpr( new NameExpr( "__cfatid_exception_t" ) )193 ) } ),194 { linkonce( typeid_name ) },195 noFuncSpecifiers196 );197 }198 199 } -
src/Virtual/Tables.h
rfe63ae6 r56c8b86 10 10 // Created On : Mon Aug 31 11:07:00 2020 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : T hr Apr 8 15:55:00 202113 // Update Count : 112 // Last Modified On : Tue Sep 1 14:29:00 2020 13 // Update Count : 0 14 14 // 15 15 … … 22 22 namespace Virtual { 23 23 24 std::string typeIdType( std::string const & type_name );25 std::string typeIdName( std::string const & type_name );26 24 std::string vtableTypeName( std::string const & type_name ); 27 25 std::string instanceName( std::string const & vtable_name ); … … 52 50 */ 53 51 54 ObjectDecl * makeTypeIdInstance( StructInstType const * typeIdType );55 /* Build an instance of the type-id from the type of the type-id.56 * TODO: Should take the parent type. Currently locked to the exception_t.57 */58 59 52 } -
tests/exceptions/.expect/resume-threads.txt
rfe63ae6 r56c8b86 6 6 7 7 catch-all 8 9 throwing child exception 10 inner parent match 8 11 9 12 caught yin as yin -
tests/exceptions/.expect/resume.txt
rfe63ae6 r56c8b86 6 6 7 7 catch-all 8 9 throwing child exception 10 inner parent match 8 11 9 12 caught yin as yin -
tests/exceptions/.expect/terminate-threads.txt
rfe63ae6 r56c8b86 5 5 6 6 catch-all 7 8 throwing child exception 9 inner parent match 7 10 8 11 caught yin as yin -
tests/exceptions/.expect/terminate.txt
rfe63ae6 r56c8b86 5 5 6 6 catch-all 7 8 throwing child exception 9 inner parent match 7 10 8 11 caught yin as yin -
tests/exceptions/cancel/coroutine.cfa
rfe63ae6 r56c8b86 4 4 #include <exception.hfa> 5 5 6 EHM_EXCEPTION(internal_error)(); 7 EHM_VIRTUAL_TABLE(internal_error, internal_vt); 6 TRIVIAL_EXCEPTION(internal_error); 8 7 9 8 coroutine WillCancel {}; … … 15 14 void main(WillCancel & wc) { 16 15 printf("1"); 17 cancel_stack((internal_error){ &internal_vt});16 cancel_stack((internal_error){}); 18 17 printf("!"); 19 18 } … … 25 24 resume(cancel); 26 25 printf("4"); 27 } catchResume ( SomeCoroutineCancelled* error) {26 } catchResume (CoroutineCancelled(WillCancel) * error) { 28 27 printf("2"); 29 28 if ((virtual internal_error *)error->the_exception) { -
tests/exceptions/cancel/thread.cfa
rfe63ae6 r56c8b86 4 4 #include <exception.hfa> 5 5 6 EHM_EXCEPTION(internal_error)(); 7 EHM_VIRTUAL_TABLE(internal_error, internal_vt); 6 TRIVIAL_EXCEPTION(internal_error); 8 7 9 8 thread WillCancel {}; … … 15 14 void main(WillCancel &) { 16 15 printf("1"); 17 cancel_stack((internal_error){ &internal_vt});16 cancel_stack((internal_error){}); 18 17 printf("!"); 19 18 } … … 26 25 join(cancel); 27 26 printf("4"); 28 } catchResume ( SomeThreadCancelled* error) {27 } catchResume (ThreadCancelled(WillCancel) * error) { 29 28 printf("2"); 30 29 if ((virtual internal_error *)error->the_exception) { … … 43 42 } 44 43 printf("4"); 45 } catchResume ( SomeThreadCancelled* error) {44 } catchResume (ThreadCancelled(WillCancel) * error) { 46 45 printf("2"); 47 46 if ((virtual internal_error *)error->the_exception) { -
tests/exceptions/conditional.cfa
rfe63ae6 r56c8b86 6 6 #include <exception.hfa> 7 7 8 EHM_EXCEPTION(num_error)(9 int num;8 VTABLE_DECLARATION(num_error)( 9 int (*code)(num_error *this); 10 10 ); 11 11 12 EHM_VIRTUAL_TABLE(num_error, num_error_vt); 12 struct num_error { 13 VTABLE_FIELD(num_error); 14 char * msg; 15 int num; 16 }; 17 18 const char * num_error_msg(num_error * this) { 19 if ( ! this->msg ) { 20 static const char * base = "Num Error with code: X"; 21 this->msg = (char *)malloc(22); 22 for (int i = 0 ; (this->msg[i] = base[i]) ; ++i); 23 } 24 this->msg[21] = '0' + this->num; 25 return this->msg; 26 } 27 void ?{}(num_error & this, int num) { 28 VTABLE_INIT(this, num_error); 29 this.msg = 0; 30 this.num = num; 31 } 32 void ?{}(num_error & this, num_error & other) { 33 this.virtual_table = other.virtual_table; 34 this.msg = 0; 35 this.num = other.num; 36 } 37 void ^?{}(num_error & this) { 38 if( this.msg ) free( this.msg ); 39 } 40 int num_error_code( num_error * this ) { 41 return this->num; 42 } 43 44 VTABLE_INSTANCE(num_error)( 45 num_error_msg, 46 num_error_code, 47 ); 13 48 14 49 void caught_num_error(int expect, num_error * actual) { … … 17 52 18 53 int main(int argc, char * argv[]) { 19 num_error exc = {&num_error_vt, 2};54 num_error exc = 2; 20 55 21 56 try { 22 57 throw exc; 23 } catch (num_error * error ; 3 == error-> num) {58 } catch (num_error * error ; 3 == error->virtual_table->code( error )) { 24 59 caught_num_error(3, error); 25 } catch (num_error * error ; 2 == error-> num) {60 } catch (num_error * error ; 2 == error->virtual_table->code( error )) { 26 61 caught_num_error(2, error); 27 62 } … … 29 64 try { 30 65 throwResume exc; 31 } catchResume (num_error * error ; 3 == error-> num) {66 } catchResume (num_error * error ; 3 == error->virtual_table->code( error )) { 32 67 caught_num_error(3, error); 33 } catchResume (num_error * error ; 2 == error-> num) {68 } catchResume (num_error * error ; 2 == error->virtual_table->code( error )) { 34 69 caught_num_error(2, error); 35 70 } -
tests/exceptions/data-except.cfa
rfe63ae6 r56c8b86 3 3 #include <exception.hfa> 4 4 5 EHM_EXCEPTION(paired)(5 DATA_EXCEPTION(paired)( 6 6 int first; 7 7 int second; 8 8 ); 9 9 10 EHM_VIRTUAL_TABLE(paired, paired_vt); 10 void ?{}(paired & this, int first, int second) { 11 VTABLE_INIT(this, paired); 12 this.first = first; 13 this.second = second; 14 } 11 15 12 const char * virtual_msg(paired * this) { 13 return this->virtual_table->msg(this); 16 const char * paired_msg(paired * this) { 17 return "paired"; 18 } 19 20 VTABLE_INSTANCE(paired)(paired_msg); 21 22 void throwPaired(int first, int second) { 23 paired exc = {first, second}; 14 24 } 15 25 16 26 int main(int argc, char * argv[]) { 17 paired except = { &paired_vt,3, 13};27 paired except = {3, 13}; 18 28 19 29 try { 20 30 throw except; 21 31 } catch (paired * exc) { 22 printf("%s(%d, %d)\n", virtual_msg(exc), exc->first, exc->second);32 printf("%s(%d, %d)\n", paired_msg(exc), exc->first, exc->second); 23 33 ++exc->first; 24 34 } 25 35 26 printf("%s(%d, %d)\n", virtual_msg(&except), except.first, except.second);36 printf("%s(%d, %d)\n", paired_msg(&except), except.first, except.second); 27 37 28 38 try { 29 39 throwResume except; 30 40 } catchResume (paired * exc) { 31 printf("%s(%d, %d)\n", virtual_msg(exc), exc->first, exc->second);41 printf("%s(%d, %d)\n", paired_msg(exc), exc->first, exc->second); 32 42 ++exc->first; 33 43 } 34 44 35 printf("%s(%d, %d)\n", virtual_msg(&except), except.first, except.second);45 printf("%s(%d, %d)\n", paired_msg(&except), except.first, except.second); 36 46 } -
tests/exceptions/defaults.cfa
rfe63ae6 r56c8b86 4 4 #include <exception.hfa> 5 5 6 EHM_EXCEPTION(log_message)(6 DATA_EXCEPTION(log_message)( 7 7 char * msg; 8 8 ); 9 9 10 _EHM_DEFINE_COPY(log_message, ) 11 const char * msg(log_message * this) { 10 void ?{}(log_message & this, char * msg) { 11 VTABLE_INIT(this, log_message); 12 this.msg = msg; 13 } 14 15 const char * get_log_message(log_message * this) { 12 16 return this->msg; 13 17 } 14 _EHM_VIRTUAL_TABLE(log_message, , log_vt); 18 19 VTABLE_INSTANCE(log_message)(get_log_message); 15 20 16 21 // Logging messages don't have to be handled. … … 23 28 // We can catch log: 24 29 try { 25 throwResume (log_message){ &log_vt,"Should be printed.\n"};30 throwResume (log_message){"Should be printed.\n"}; 26 31 } catchResume (log_message * this) { 27 32 printf("%s", this->virtual_table->msg(this)); 28 33 } 29 34 // But we don't have to: 30 throwResume (log_message){ &log_vt,"Should not be printed.\n"};35 throwResume (log_message){"Should not be printed.\n"}; 31 36 } 32 37 33 38 // I don't have a good use case for doing the same with termination. 34 EHM_EXCEPTION(jump)();39 TRIVIAL_EXCEPTION(jump); 35 40 void defaultTerminationHandler(jump &) { 36 41 printf("jump default handler.\n"); 37 42 } 38 43 39 EHM_VIRTUAL_TABLE(jump, jump_vt);40 41 44 void jump_test(void) { 42 45 try { 43 throw (jump){ &jump_vt};46 throw (jump){}; 44 47 } catch (jump * this) { 45 48 printf("jump catch handler.\n"); 46 49 } 47 throw (jump){ &jump_vt};50 throw (jump){}; 48 51 } 49 52 50 EHM_EXCEPTION(first)(); 51 EHM_VIRTUAL_TABLE(first, first_vt); 52 53 EHM_EXCEPTION(unhandled_exception)(); 54 EHM_VIRTUAL_TABLE(unhandled_exception, unhandled_vt); 53 TRIVIAL_EXCEPTION(first); 54 TRIVIAL_EXCEPTION(unhandled_exception); 55 55 56 56 void unhandled_test(void) { 57 57 forall(T &, V & | is_exception(T, V)) 58 58 void defaultTerminationHandler(T &) { 59 throw (unhandled_exception){ &unhandled_vt};59 throw (unhandled_exception){}; 60 60 } 61 61 void defaultTerminationHandler(unhandled_exception &) { … … 63 63 } 64 64 try { 65 throw (first){ &first_vt};65 throw (first){}; 66 66 } catch (unhandled_exception * t) { 67 67 printf("Catch unhandled_exception.\n"); … … 69 69 } 70 70 71 EHM_EXCEPTION(second)(); 72 EHM_VIRTUAL_TABLE(second, second_vt); 71 TRIVIAL_EXCEPTION(second); 73 72 74 73 void cross_test(void) { 75 74 void defaultTerminationHandler(first &) { 76 75 printf("cross terminate default\n"); 77 throw (second){ &second_vt};76 throw (second){}; 78 77 } 79 78 void defaultResumptionHandler(first &) { 80 79 printf("cross resume default\n"); 81 throwResume (second){ &second_vt};80 throwResume (second){}; 82 81 } 83 82 try { 84 83 printf("cross terminate throw\n"); 85 throw (first){ &first_vt};84 throw (first){}; 86 85 } catch (second *) { 87 86 printf("cross terminate catch\n"); … … 89 88 try { 90 89 printf("cross resume throw\n"); 91 throwResume (first){ &first_vt};90 throwResume (first){}; 92 91 } catchResume (second *) { 93 92 printf("cross resume catch\n"); -
tests/exceptions/finally.cfa
rfe63ae6 r56c8b86 4 4 #include "except-io.hfa" 5 5 6 EHM_EXCEPTION(myth)(); 7 8 EHM_VIRTUAL_TABLE(myth, myth_vt); 6 TRIVIAL_EXCEPTION(myth); 9 7 10 8 int main(int argc, char * argv[]) { 11 myth exc = {&myth_vt};9 myth exc; 12 10 13 11 try { -
tests/exceptions/interact.cfa
rfe63ae6 r56c8b86 4 4 #include "except-io.hfa" 5 5 6 EHM_EXCEPTION(star)(); 7 EHM_EXCEPTION(moon)(); 8 9 EHM_VIRTUAL_TABLE(star, star_vt); 10 EHM_VIRTUAL_TABLE(moon, moon_vt); 6 TRIVIAL_EXCEPTION(star); 7 TRIVIAL_EXCEPTION(moon); 11 8 12 9 int main(int argc, char * argv[]) { 13 10 // Resume falls back to terminate. 14 11 try { 15 throwResume (star){ &star_vt};12 throwResume (star){}; 16 13 } catch (star *) { 17 14 printf("caught as termination\n"); … … 20 17 try { 21 18 loud_region a = "try block with resume throw"; 22 throwResume (star){ &star_vt};19 throwResume (star){}; 23 20 } catch (star *) { 24 21 printf("caught as termination\n"); … … 32 29 try { 33 30 try { 34 throw (star){ &star_vt};31 throw (star){}; 35 32 } catchResume (star *) { 36 33 printf("resume catch on terminate\n"); … … 46 43 try { 47 44 try { 48 throwResume (star){ &star_vt};45 throwResume (star){}; 49 46 } catch (star *) { 50 47 printf("terminate catch on resume\n"); … … 61 58 try { 62 59 try { 63 throw (star){ &star_vt};60 throw (star){}; 64 61 } catchResume (star *) { 65 62 printf("inner resume catch (error)\n"); … … 78 75 try { 79 76 try { 80 throwResume (star){ &star_vt};77 throwResume (star){}; 81 78 } catch (star *) { 82 79 printf("inner termination catch\n"); … … 97 94 try { 98 95 printf("throwing resume moon\n"); 99 throwResume (moon){ &moon_vt};96 throwResume (moon){}; 100 97 } catch (star *) { 101 98 printf("termination catch\n"); 102 99 } 103 100 printf("throwing resume star\n"); 104 throwResume (star){ &star_vt};101 throwResume (star){}; 105 102 } catchResume (star *) { 106 103 printf("resumption star catch\n"); … … 108 105 } catchResume (moon *) { 109 106 printf("resumption moon catch, will terminate\n"); 110 throw (star){ &star_vt};107 throw (star){}; 111 108 } 112 109 } catchResume (star *) { -
tests/exceptions/polymorphic.cfa
rfe63ae6 r56c8b86 3 3 #include <exception.hfa> 4 4 5 EHM_FORALL_EXCEPTION(proxy, (T&), (T))(); 5 FORALL_TRIVIAL_EXCEPTION(proxy, (T), (T)); 6 FORALL_TRIVIAL_INSTANCE(proxy, (U), (U)) 6 7 7 EHM_FORALL_VIRTUAL_TABLE(proxy, (int), proxy_int); 8 EHM_FORALL_VIRTUAL_TABLE(proxy, (char), proxy_char); 8 const char * msg(proxy(int) * this) { return "proxy(int)"; } 9 const char * msg(proxy(char) * this) { return "proxy(char)"; } 10 POLY_VTABLE_INSTANCE(proxy, int)(msg); 11 POLY_VTABLE_INSTANCE(proxy, char)(msg); 9 12 10 13 void proxy_test(void) { 11 proxy(int) an_int = {&proxy_int};12 proxy(char) a_char = {&proxy_char};13 14 14 try { 15 throw an_int;15 throw (proxy(int)){}; 16 16 } catch (proxy(int) *) { 17 17 printf("terminate catch\n"); … … 19 19 20 20 try { 21 throwResume a_char;21 throwResume (proxy(char)){}; 22 22 } catchResume (proxy(char) *) { 23 23 printf("resume catch\n"); … … 25 25 26 26 try { 27 throw a_char;27 throw (proxy(char)){}; 28 28 } catch (proxy(int) *) { 29 29 printf("caught proxy(int)\n"); … … 33 33 } 34 34 35 EHM_FORALL_EXCEPTION(cell, (T), (T))(35 FORALL_DATA_EXCEPTION(cell, (T), (T))( 36 36 T data; 37 37 ); 38 38 39 EHM_FORALL_VIRTUAL_TABLE(cell, (int), int_cell); 40 EHM_FORALL_VIRTUAL_TABLE(cell, (char), char_cell); 41 EHM_FORALL_VIRTUAL_TABLE(cell, (bool), bool_cell); 39 FORALL_DATA_INSTANCE(cell, (T), (T)) 40 41 const char * msg(cell(int) * this) { return "cell(int)"; } 42 const char * msg(cell(char) * this) { return "cell(char)"; } 43 const char * msg(cell(bool) * this) { return "cell(bool)"; } 44 POLY_VTABLE_INSTANCE(cell, int)(msg); 45 POLY_VTABLE_INSTANCE(cell, char)(msg); 46 POLY_VTABLE_INSTANCE(cell, bool)(msg); 42 47 43 48 void cell_test(void) { 44 49 try { 45 cell(int) except = {&int_cell, -7}; 50 cell(int) except; 51 except.data = -7; 46 52 throw except; 47 53 } catch (cell(int) * error) { … … 50 56 51 57 try { 52 cell(bool) ball = {&bool_cell, false}; 58 cell(bool) ball; 59 ball.data = false; 53 60 throwResume ball; 54 61 printf("%i\n", ball.data); -
tests/exceptions/resume.cfa
rfe63ae6 r56c8b86 4 4 #include "except-io.hfa" 5 5 6 EHM_EXCEPTION(yin)(); 7 EHM_EXCEPTION(yang)(); 8 EHM_EXCEPTION(zen)(); 9 10 EHM_VIRTUAL_TABLE(yin, yin_vt); 11 EHM_VIRTUAL_TABLE(yang, yang_vt); 12 EHM_VIRTUAL_TABLE(zen, zen_vt); 6 TRIVIAL_EXCEPTION(yin); 7 TRIVIAL_EXCEPTION(yang); 8 TRIVIAL_EXCEPTION(zen); 9 TRIVIAL_EXCEPTION(moment_of, zen); 13 10 14 11 void in_void(void); 15 12 16 13 int main(int argc, char * argv[]) { 17 yin a_yin = {&yin_vt};18 yang a_yang = {&yang_vt};19 zen a_zen = {&zen_vt};20 21 14 // The simple throw catchResume test. 22 15 try { 23 16 loud_exit a = "simple try clause"; 24 17 printf("simple throw\n"); 25 throwResume a_zen;18 throwResume (zen){}; 26 19 printf("end of try clause\n"); 27 20 } catchResume (zen * error) { … … 33 26 // Throw catch-all test. 34 27 try { 35 throwResume a_zen;28 throwResume (zen){}; 36 29 } catchResume (exception_t * error) { 37 30 printf("catch-all\n"); 31 } 32 printf("\n"); 33 34 // Catch a parent of the given exception. 35 try { 36 printf("throwing child exception\n"); 37 throwResume (moment_of){}; 38 } catchResume (zen *) { 39 printf("inner parent match\n"); 40 } catchResume (moment_of *) { 41 printf("outer exact match\n"); 38 42 } 39 43 printf("\n"); … … 42 46 try { 43 47 try { 44 throwResume a_yin;48 throwResume (yin){}; 45 49 } catchResume (zen *) { 46 50 printf("caught yin as zen\n"); … … 58 62 loud_exit a = "rethrow inner try"; 59 63 printf("rethrow inner try\n"); 60 throwResume a_zen;64 throwResume (zen){}; 61 65 } catchResume (zen *) { 62 66 loud_exit a = "rethrowing catch clause"; … … 73 77 try { 74 78 try { 75 throwResume a_yin;79 throwResume (yin){}; 76 80 } catchResume (yin *) { 77 81 printf("caught yin, will throw yang\n"); 78 throwResume a_yang;82 throwResume (yang){}; 79 83 } catchResume (yang *) { 80 84 printf("caught exception from same try\n"); … … 89 93 try { 90 94 printf("throwing first exception\n"); 91 throwResume a_yin;95 throwResume (yin){}; 92 96 } catchResume (yin *) { 93 97 printf("caught first exception\n"); 94 98 try { 95 99 printf("throwing second exception\n"); 96 throwResume a_yang;100 throwResume (yang){}; 97 101 } catchResume (yang *) { 98 102 printf("caught second exception\n"); … … 110 114 try { 111 115 try { 112 throwResume a_zen;113 throwResume a_zen;116 throwResume (zen){}; 117 throwResume (zen){}; 114 118 } catchResume (zen *) { 115 119 printf("inner catch\n"); 116 120 } 117 throwResume a_zen;121 throwResume (zen){}; 118 122 } catchResume (zen *) { 119 123 printf("outer catch\n"); … … 126 130 // Do a throw and rethrow in a void function. 127 131 void in_void(void) { 128 zen a_zen = {&zen_vt};129 132 try { 130 133 try { 131 134 printf("throw\n"); 132 throwResume a_zen;135 throwResume (zen){}; 133 136 } catchResume (zen *) { 134 137 printf("rethrow\n"); -
tests/exceptions/terminate.cfa
rfe63ae6 r56c8b86 4 4 #include "except-io.hfa" 5 5 6 EHM_EXCEPTION(yin)(); 7 EHM_EXCEPTION(yang)(); 8 EHM_EXCEPTION(zen)(); 9 10 EHM_VIRTUAL_TABLE(yin, yin_vt); 11 EHM_VIRTUAL_TABLE(yang, yang_vt); 12 EHM_VIRTUAL_TABLE(zen, zen_vt); 6 TRIVIAL_EXCEPTION(yin); 7 TRIVIAL_EXCEPTION(yang); 8 TRIVIAL_EXCEPTION(zen); 9 TRIVIAL_EXCEPTION(moment_of, zen); 13 10 14 11 void in_void(void); 15 12 16 13 int main(int argc, char * argv[]) { 17 yin a_yin = {&yin_vt};18 yang a_yang = {&yang_vt};19 zen a_zen = {&zen_vt};20 21 14 // The simple throw catch test. 22 15 try { 23 16 loud_exit a = "simple try clause"; 24 17 printf("simple throw\n"); 25 throw a_zen;18 throw (zen){}; 26 19 printf("end of try clause\n"); 27 20 } catch (zen * error) { … … 33 26 // Throw catch-all test. 34 27 try { 35 throw a_zen;28 throw (zen){}; 36 29 } catch (exception_t * error) { 37 30 printf("catch-all\n"); 31 } 32 printf("\n"); 33 34 // Catch a parent of the given exception. 35 try { 36 printf("throwing child exception\n"); 37 throw (moment_of){}; 38 } catch (zen *) { 39 printf("inner parent match\n"); 40 } catch (moment_of *) { 41 printf("outer exact match\n"); 38 42 } 39 43 printf("\n"); … … 42 46 try { 43 47 try { 44 throw a_yin;48 throw (yin){}; 45 49 } catch (zen *) { 46 50 printf("caught yin as zen\n"); … … 58 62 loud_exit a = "rethrow inner try"; 59 63 printf("rethrow inner try\n"); 60 throw a_zen;64 throw (zen){}; 61 65 } catch (zen *) { 62 66 loud_exit a = "rethrowing catch clause"; … … 73 77 try { 74 78 try { 75 throw a_yin;79 throw (yin){}; 76 80 } catch (yin *) { 77 81 printf("caught yin, will throw yang\n"); 78 throw a_yang;82 throw (yang){}; 79 83 } catch (yang *) { 80 84 printf("caught exception from same try\n"); … … 89 93 try { 90 94 printf("throwing first exception\n"); 91 throw a_yin;95 throw (yin){}; 92 96 } catch (yin *) { 93 97 printf("caught first exception\n"); 94 98 try { 95 99 printf("throwing second exception\n"); 96 throw a_yang;100 throw (yang){}; 97 101 } catch (yang *) { 98 102 printf("caught second exception\n"); … … 110 114 try { 111 115 try { 112 throw a_zen;113 throw a_zen;116 throw (zen){}; 117 throw (zen){}; 114 118 } catch (zen *) { 115 119 printf("inner catch\n"); 116 120 } 117 throw a_zen;121 throw (zen){}; 118 122 } catch (zen *) { 119 123 printf("outer catch\n"); … … 126 130 // Do a throw and rethrow in a void function. 127 131 void in_void(void) { 128 zen a_zen = {&zen_vt};129 132 try { 130 133 try { 131 134 printf("throw\n"); 132 throw a_zen;135 throw (zen){}; 133 136 } catch (zen *) { 134 137 printf("rethrow\n"); -
tests/exceptions/trash.cfa
rfe63ae6 r56c8b86 3 3 #include <exception.hfa> 4 4 5 EHM_EXCEPTION(yin)(); 6 EHM_EXCEPTION(yang)(); 7 8 EHM_VIRTUAL_TABLE(yin, yin_vt); 9 EHM_VIRTUAL_TABLE(yang, yang_vt); 5 TRIVIAL_EXCEPTION(yin); 6 TRIVIAL_EXCEPTION(yang); 10 7 11 8 int main(int argc, char * argv[]) { 12 9 try { 13 10 try { 14 throw (yin){ &yin_vt};11 throw (yin){}; 15 12 } finally { 16 13 try { 17 throw (yang){ &yang_vt};14 throw (yang){}; 18 15 } catch (yin *) { 19 16 printf("inner yin\n"); -
tests/exceptions/type-check.cfa
rfe63ae6 r56c8b86 3 3 #include <exception.hfa> 4 4 5 EHM_EXCEPTION(truth)();5 TRIVIAL_EXCEPTION(truth); 6 6 7 7 int main(int argc, char * argv[]) { -
tests/exceptions/virtual-cast.cfa
rfe63ae6 r56c8b86 12 12 #include <assert.h> 13 13 14 15 16 // Hand defined alpha virtual type:17 struct __cfatid_struct_alpha {18 __cfa__parent_vtable const * parent;19 };20 21 __attribute__(( section(".gnu.linkonce.__cfatid_alpha") ))22 struct __cfatid_struct_alpha __cfatid_alpha = {23 (__cfa__parent_vtable *)0,24 };25 26 14 struct alpha_vtable { 27 struct __cfatid_struct_alpha const * const __cfavir_typeid;15 alpha_vtable const * const parent; 28 16 char (*code)(void); 29 17 }; … … 39 27 40 28 41 // Hand defined beta virtual type:42 struct __cfatid_struct_beta {43 __cfatid_struct_alpha const * parent;44 };45 46 __attribute__(( section(".gnu.linkonce.__cfatid_beta") ))47 struct __cfatid_struct_beta __cfatid_beta = {48 &__cfatid_alpha,49 };50 51 29 struct beta_vtable { 52 struct __cfatid_struct_beta const * const __cfavir_typeid;30 alpha_vtable const * const parent; 53 31 char (*code)(void); 54 32 }; … … 64 42 65 43 66 // Hand defined gamma virtual type:67 struct __cfatid_struct_gamma {68 __cfatid_struct_beta const * parent;69 };70 71 __attribute__(( section(".gnu.linkonce.__cfatid_gamma") ))72 struct __cfatid_struct_gamma __cfatid_gamma = {73 &__cfatid_beta,74 };75 76 44 struct gamma_vtable { 77 struct __cfatid_struct_gamma const * const __cfavir_typeid;45 beta_vtable const * const parent; 78 46 char (*code)(void); 79 47 }; … … 89 57 90 58 extern "C" { 91 alpha_vtable _alpha_vtable_instance = { &__cfatid_alpha, ret_a };92 beta_vtable _beta_vtable_instance = { &_ _cfatid_beta, ret_b };93 gamma_vtable _gamma_vtable_instance = { &_ _cfatid_gamma, ret_g };59 alpha_vtable _alpha_vtable_instance = { 0, ret_a }; 60 beta_vtable _beta_vtable_instance = { &_alpha_vtable_instance, ret_b }; 61 gamma_vtable _gamma_vtable_instance = { &_beta_vtable_instance, ret_g }; 94 62 } 95 63 -
tests/exceptions/virtual-poly.cfa
rfe63ae6 r56c8b86 8 8 #include <assert.h> 9 9 10 11 struct __cfatid_struct_mono_base {12 __cfa__parent_vtable const * parent;13 };14 15 __attribute__(( section(".gnu.linkonce.__cfatid_mono_base") ))16 struct __cfatid_struct_mono_base __cfatid_mono_base = {17 (__cfa__parent_vtable *)0,18 };19 20 10 struct mono_base_vtable { 21 __cfatid_struct_mono_base const * const __cfavir_typeid;11 mono_base_vtable const * const parent; 22 12 }; 23 13 … … 27 17 28 18 forall(T) 29 struct __cfatid_struct_mono_child {30 __cfatid_struct_mono_base const * parent;31 };32 33 forall(T)34 19 struct mono_child_vtable { 35 __cfatid_struct_mono_child(T) const * const __cfavir_typeid;20 mono_base_vtable const * const parent; 36 21 }; 37 22 … … 41 26 }; 42 27 43 __cfatid_struct_mono_child(int) __cfatid_mono_child @= { 44 &__cfatid_mono_base, 45 }; 46 28 mono_base_vtable _mono_base_vtable_instance @= { 0 }; 47 29 mono_child_vtable(int) _mono_child_vtable_instance @= { 48 &_ _cfatid_mono_child,30 &_mono_base_vtable_instance 49 31 }; 50 32 … … 55 37 } 56 38 57 58 forall(U)59 struct __cfatid_struct_poly_base {60 __cfa__parent_vtable const * parent;61 };62 63 39 forall(U) 64 40 struct poly_base_vtable { 65 __cfatid_struct_poly_base(U) const * const __cfavir_typeid;41 poly_base_vtable(U) const * const parent; 66 42 }; 67 43 … … 72 48 73 49 forall(V) 74 struct __cfatid_struct_poly_child {75 __cfatid_struct_poly_base(V) const * parent;76 };77 78 forall(V)79 50 struct poly_child_vtable { 80 __cfatid_struct_poly_child(V) const * const __cfavir_typeid;51 poly_base_vtable(V) const * const parent; 81 52 }; 82 53 … … 86 57 }; 87 58 88 __cfatid_struct_poly_base(int) __cfatid_poly_base @= { 89 (__cfa__parent_vtable *)0, 59 poly_base_vtable(int) _poly_base_vtable_instance @= { 0 }; 60 poly_child_vtable(int) _poly_child_vtable_instance @= { 61 &_poly_base_vtable_instance 90 62 }; 91 __cfatid_struct_poly_child(int) __cfatid_poly_child = { 92 &__cfatid_poly_base, 63 /* Resolver bug keeps me from adding these. 64 poly_base_vtable(char) _poly_base_vtable_instance @= { 0 }; 65 poly_child_vtable(char) _poly_child_vtable_instance @= { 66 &_poly_base_vtable_instance 93 67 }; 94 poly_child_vtable(int) _poly_child_vtable_instance @= { 95 &__cfatid_poly_child, 96 }; 68 */ 97 69 98 70 void poly_poly_test() { … … 105 77 mono_poly_test(); 106 78 poly_poly_test(); 107 printf( "done\n" ); 79 printf( "done\n" ); // non-empty .expect file 108 80 } -
tests/linking/exception-nothreads.cfa
rfe63ae6 r56c8b86 17 17 #include <exception.hfa> 18 18 19 EHM_EXCEPTION(ping)(); 20 EHM_VIRTUAL_TABLE(ping, ping_vt); 19 TRIVIAL_EXCEPTION(ping); 21 20 22 21 int main(void) { 23 22 try { 24 throwResume (ping){ &ping_vt};23 throwResume (ping){}; 25 24 } catchResume (ping *) { 26 25 printf("%s threads\n", threading_enabled() ? "with" : "no"); -
tests/linking/exception-withthreads.cfa
rfe63ae6 r56c8b86 18 18 #include "../exceptions/with-threads.hfa" 19 19 20 EHM_EXCEPTION(ping)(); 21 EHM_VIRTUAL_TABLE(ping, ping_vt); 20 TRIVIAL_EXCEPTION(ping); 22 21 23 22 int main(void) { 24 23 try { 25 throwResume (ping){ &ping_vt};24 throwResume (ping){}; 26 25 } catchResume (ping *) { 27 26 printf("%s threads\n", threading_enabled() ? "with" : "no"); -
tests/quasiKeyword.cfa
rfe63ae6 r56c8b86 14 14 #include <exception.hfa> 15 15 16 EHM_EXCEPTION( E )();16 TRIVIAL_EXCEPTION( E ); 17 17 18 18 void catch( int i ) {}
Note:
See TracChangeset
for help on using the changeset viewer.