Changeset 47e000c for libcfa


Ignore:
Timestamp:
Apr 13, 2021, 8:02:56 PM (3 years ago)
Author:
Peter A. Buhr <pabuhr@…>
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.
Message:

Merge branch 'master' of plg.uwaterloo.ca:software/cfa/cfa-cc

Location:
libcfa/src
Files:
14 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/concurrency/coroutine.cfa

    r0effb6a r47e000c  
    4646
    4747//-----------------------------------------------------------------------------
    48 FORALL_DATA_INSTANCE(CoroutineCancelled, (coroutine_t &), (coroutine_t))
    49 
    50 forall(T &)
    51 void mark_exception(CoroutineCancelled(T) *) {}
     48EHM_VIRTUAL_TABLE(SomeCoroutineCancelled, std_coroutine_cancelled);
    5249
    5350forall(T &)
     
    7168
    7269        // 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;
    7572        except.the_coroutine = &cor;
    7673        except.the_exception = except;
    77         throwResume except;
     74        // Why does this need a cast?
     75        throwResume (SomeCoroutineCancelled &)except;
    7876
    7977        except->virtual_table->free( except );
  • libcfa/src/concurrency/coroutine.hfa

    r0effb6a r47e000c  
    2222//-----------------------------------------------------------------------------
    2323// Exception thrown from resume when a coroutine stack is cancelled.
    24 FORALL_DATA_EXCEPTION(CoroutineCancelled, (coroutine_t &), (coroutine_t)) (
     24EHM_EXCEPTION(SomeCoroutineCancelled)(
     25        void * the_coroutine;
     26        exception_t * the_exception;
     27);
     28
     29EHM_EXTERN_VTABLE(SomeCoroutineCancelled, std_coroutine_cancelled);
     30
     31EHM_FORALL_EXCEPTION(CoroutineCancelled, (coroutine_t &), (coroutine_t)) (
    2532        coroutine_t * the_coroutine;
    2633        exception_t * the_exception;
     
    3744// Anything that implements this trait can be resumed.
    3845// Anything that is resumed is a coroutine.
    39 trait is_coroutine(T & | IS_RESUMPTION_EXCEPTION(CoroutineCancelled, (T))) {
     46trait is_coroutine(T & | IS_RESUMPTION_EXCEPTION(SomeCoroutineCancelled)) {
    4047        void main(T & this);
    4148        $coroutine * get_coroutine(T & this);
  • libcfa/src/concurrency/kernel.cfa

    r0effb6a r47e000c  
    359359                                #if !defined(__CFA_NO_STATISTICS__)
    360360                                        __tls_stats()->ready.threads.threads++;
     361                                        __push_stat( __tls_stats(), __tls_stats()->ready.threads.threads, false, "Processor", this );
    361362                                #endif
    362363                                // This is case 2, the racy case, someone tried to run this thread before it finished blocking
     
    376377        #if !defined(__CFA_NO_STATISTICS__)
    377378                __tls_stats()->ready.threads.threads--;
     379                __push_stat( __tls_stats(), __tls_stats()->ready.threads.threads, false, "Processor", this );
    378380        #endif
    379381
     
    455457                if( kernelTLS().this_stats ) {
    456458                        __tls_stats()->ready.threads.threads++;
     459                        __push_stat( __tls_stats(), __tls_stats()->ready.threads.threads, false, "Processor", kernelTLS().this_processor );
    457460                }
    458461                else {
    459462                        __atomic_fetch_add(&cl->stats->ready.threads.threads, 1, __ATOMIC_RELAXED);
     463                        __push_stat( cl->stats, cl->stats->ready.threads.threads, true, "Cluster", cl );
    460464                }
    461465        #endif
  • libcfa/src/concurrency/kernel/startup.cfa

    r0effb6a r47e000c  
    268268                        __print_stats( st, mainProcessor->print_stats, "Processor ", mainProcessor->name, (void*)mainProcessor );
    269269                }
     270                #if defined(CFA_STATS_ARRAY)
     271                        __flush_stat( st, "Processor", mainProcessor );
     272                #endif
    270273        #endif
    271274
     
    348351                        __print_stats( &local_stats, proc->print_stats, "Processor ", proc->name, (void*)proc );
    349352                }
     353                #if defined(CFA_STATS_ARRAY)
     354                        __flush_stat( &local_stats, "Processor", proc );
     355                #endif
    350356        #endif
    351357
     
    615621                        __print_stats( this.stats, this.print_stats, "Cluster", this.name, (void*)&this );
    616622                }
     623                #if defined(CFA_STATS_ARRAY)
     624                        __flush_stat( this.stats, "Cluster", &this );
     625                #endif
    617626                free( this.stats );
    618627        #endif
  • libcfa/src/concurrency/stats.cfa

    r0effb6a r47e000c  
    55#include <inttypes.h>
    66#include "bits/debug.hfa"
     7#include "bits/locks.hfa"
    78#include "stats.hfa"
    89
     
    4445                        stats->io.calls.errors.busy = 0;
    4546                        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;
    4652                #endif
    4753        }
     
    151157                #endif
    152158        }
     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
    153204#endif
  • libcfa/src/concurrency/stats.hfa

    r0effb6a r47e000c  
    11#pragma once
     2
     3// #define CFA_STATS_ARRAY 10000
    24
    35#include <stdint.h>
     
    109111        #endif
    110112
     113        #if defined(CFA_STATS_ARRAY)
     114                struct __stats_elem_t {
     115                        long long int ts;
     116                        int64_t value;
     117                };
     118        #endif
     119
    111120        struct __attribute__((aligned(128))) __stats_t {
    112121                __stats_readQ_t ready;
     
    114123                        __stats_io_t    io;
    115124                #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
    116133        };
    117134
     
    119136        void __tally_stats( struct __stats_t *, struct __stats_t * );
    120137        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
    121145#endif
    122146
  • libcfa/src/concurrency/thread.cfa

    r0effb6a r47e000c  
    6262}
    6363
    64 FORALL_DATA_INSTANCE(ThreadCancelled, (thread_t &), (thread_t))
     64EHM_VIRTUAL_TABLE(SomeThreadCancelled, std_thread_cancelled);
    6565
    6666forall(T &)
     
    7373forall(T &)
    7474const char * msg(ThreadCancelled(T) *) {
    75         return "ThreadCancelled";
     75        return "ThreadCancelled(...)";
    7676}
    7777
    7878forall(T &)
    7979static void default_thread_cancel_handler(ThreadCancelled(T) & ) {
     80        // Improve this error message, can I do formatting?
    8081        abort( "Unhandled thread cancellation.\n" );
    8182}
    8283
    83 forall(T & | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T)))
     84static void default_thread_cancel_handler(SomeThreadCancelled & ) {
     85        // Improve this error message, can I do formatting?
     86        abort( "Unhandled thread cancellation.\n" );
     87}
     88
     89forall(T & | is_thread(T) | IS_EXCEPTION(SomeThreadCancelled))
    8490void ?{}( thread_dtor_guard_t & this,
    85                 T & thrd, void(*cancelHandler)(ThreadCancelled(T) &)) {
    86         $monitor * m = get_monitor(thrd);
     91                T & thrd, void(*cancelHandler)(SomeThreadCancelled &)) {
     92        $monitor * m = get_monitor(thrd);
    8793        $thread * desc = get_thread(thrd);
    8894
    8995        // Setup the monitor guard
    9096        void (*dtor)(T& mutex this) = ^?{};
    91         bool join = cancelHandler != (void(*)(ThreadCancelled(T)&))0;
     97        bool join = cancelHandler != (void(*)(SomeThreadCancelled&))0;
    9298        (this.mg){&m, (void(*)())dtor, join};
    9399
     
    103109        }
    104110        desc->state = Cancelled;
    105         void(*defaultResumptionHandler)(ThreadCancelled(T) &) =
     111        void(*defaultResumptionHandler)(SomeThreadCancelled &) =
    106112                join ? cancelHandler : default_thread_cancel_handler;
    107113
    108         ThreadCancelled(T) except;
    109114        // 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;
    111117        except.the_thread = &thrd;
    112118        except.the_exception = __cfaehm_cancellation_exception( cancellation );
    113         throwResume except;
     119        // Why is this cast required?
     120        throwResume (SomeThreadCancelled &)except;
    114121
    115122        except.the_exception->virtual_table->free( except.the_exception );
     
    158165
    159166//-----------------------------------------------------------------------------
    160 forall(T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T)))
     167forall(T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(SomeThreadCancelled))
    161168T & join( T & this ) {
    162169        thread_dtor_guard_t guard = { this, defaultResumptionHandler };
  • libcfa/src/concurrency/thread.hfa

    r0effb6a r47e000c  
    3232};
    3333
    34 FORALL_DATA_EXCEPTION(ThreadCancelled, (thread_t &), (thread_t)) (
     34EHM_EXCEPTION(SomeThreadCancelled) (
     35        void * the_thread;
     36        exception_t * the_exception;
     37);
     38
     39EHM_EXTERN_VTABLE(SomeThreadCancelled, std_thread_cancelled);
     40
     41EHM_FORALL_EXCEPTION(ThreadCancelled, (thread_t &), (thread_t)) (
    3542        thread_t * the_thread;
    3643        exception_t * the_exception;
     
    7986};
    8087
    81 forall( T & | is_thread(T) | IS_EXCEPTION(ThreadCancelled, (T)) )
    82 void ?{}( thread_dtor_guard_t & this, T & thrd, void(*)(ThreadCancelled(T) &) );
     88forall( T & | is_thread(T) | IS_EXCEPTION(SomeThreadCancelled) )
     89void ?{}( thread_dtor_guard_t & this, T & thrd, void(*)(SomeThreadCancelled &) );
    8390void ^?{}( thread_dtor_guard_t & this );
    8491
     
    125132//----------
    126133// join
    127 forall( T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(ThreadCancelled, (T)) )
     134forall( T & | is_thread(T) | IS_RESUMPTION_EXCEPTION(SomeThreadCancelled) )
    128135T & join( T & this );
    129136
  • libcfa/src/exception.c

    r0effb6a r47e000c  
    1010// Created On       : Mon Jun 26 15:13:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Oct 27 16:27:00 2020
    13 // Update Count     : 35
     12// Last Modified On : Wed Feb 24 13:40:00 2021
     13// Update Count     : 36
    1414//
    1515
     
    2626#include "concurrency/invoke.h"
    2727#include "stdhdr/assert.h"
     28#include "virtual.h"
    2829
    2930#if defined( __ARM_ARCH )
     
    4647const _Unwind_Exception_Class __cfaehm_exception_class = 0x4c50575500414643;
    4748
    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:
     50struct __cfa__parent_vtable __cfatid_exception_t = {
     51        NULL,
    5652};
    5753
  • libcfa/src/exception.h

    r0effb6a r47e000c  
    1010// Created On       : Mon Jun 26 15:11:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Oct 27 14:45:00 2020
    13 // Update Count     : 11
     12// Last Modified On : Thr Apr  8 15:20:00 2021
     13// Update Count     : 12
    1414//
    1515
     
    2929struct __cfaehm_base_exception_t;
    3030typedef struct __cfaehm_base_exception_t exception_t;
     31struct __cfa__parent_vtable;
    3132struct __cfaehm_base_exception_t_vtable {
    32         const struct __cfaehm_base_exception_t_vtable * parent;
     33        const struct __cfa__parent_vtable * __cfavir_typeid;
    3334        size_t size;
    3435        void (*copy)(struct __cfaehm_base_exception_t *this,
     
    4041        struct __cfaehm_base_exception_t_vtable const * virtual_table;
    4142};
    42 extern struct __cfaehm_base_exception_t_vtable
    43         ___cfaehm_base_exception_t_vtable_instance;
     43extern struct __cfa__parent_vtable __cfatid_exception_t;
    4444
    4545
     
    104104        /* The first field must be a pointer to a virtual table.
    105105         * 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.
    106108         */
    107         virtualT const & get_exception_vtable(exceptT *);
    108         // Always returns the virtual table for this type (associated types hack).
    109109};
    110110
  • libcfa/src/exception.hfa

    r0effb6a r47e000c  
    1010// Created On       : Thu Apr  7 10:25:00 2020
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tue Aug  4 16:22:00 2020
    13 // Update Count     : 3
     12// Last Modified On : Thr Apr  8 15:16:00 2021
     13// Update Count     : 4
    1414//
    1515
     
    1818// -----------------------------------------------------------------------------------------------
    1919
    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, , )
    2528
    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)
    3033
    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)
    3840
    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)
    4750
    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)
    5456
    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)
    5965
    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)
    6767
    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
    12769
    12870// IS_EXCEPTION(exception_name [, (...parameters)])
     
    13577#define IS_TERMINATION_EXCEPTION(...) _IS_EXCEPTION(is_termination_exception, __VA_ARGS__, , ~)
    13678
    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.
    14380
    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
    15186
    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
    16090
    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, \
    17899        }
    179100
    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        }
    185107
    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        }
    194112
    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        }
    207118
    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        }
    219123
    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; \
    225132                size_t size; \
    226133                void (*copy)(exception_name parameters * this, exception_name parameters * other); \
    227134                void (*^?{})(exception_name parameters & this); \
    228135                const char * (*msg)(exception_name parameters * this); \
    229                 _CLOSE
     136        }
    230137
    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)
    245183
    246184#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  
    321321
    322322
     323EHM_VIRTUAL_TABLE(Open_Failure, Open_Failure_main_table);
    323324void ?{}( Open_Failure & this, ofstream & ostream ) {
    324         VTABLE_INIT(this, Open_Failure);
     325        this.virtual_table = &Open_Failure_main_table;
    325326        this.ostream = &ostream;
    326327        this.tag = 1;
    327328}
    328329void ?{}( Open_Failure & this, ifstream & istream ) {
    329         VTABLE_INIT(this, Open_Failure);
     330        this.virtual_table = &Open_Failure_main_table;
    330331        this.istream = &istream;
    331332        this.tag = 0;
    332333}
    333 const char * Open_Failure_msg(Open_Failure * this) {
    334         return "Open_Failure";
    335 }
    336 VTABLE_INSTANCE(Open_Failure)(Open_Failure_msg);
    337334void throwOpen_Failure( ofstream & ostream ) {
    338335        Open_Failure exc = { ostream };
  • libcfa/src/fstream.hfa

    r0effb6a r47e000c  
    133133
    134134
    135 DATA_EXCEPTION(Open_Failure)(
     135EHM_EXCEPTION(Open_Failure)(
    136136        union {
    137137                ofstream * ostream;
  • libcfa/src/virtual.c

    r0effb6a r47e000c  
    1515
    1616#include "virtual.h"
     17#include "assert.h"
    1718
    1819int __cfa__is_parent( struct __cfa__parent_vtable const * parent,
    1920        struct __cfa__parent_vtable const * child ) {
     21        assert( child );
    2022        do {
    2123                if ( parent == child )
     
    2830void * __cfa__virtual_cast( struct __cfa__parent_vtable const * parent,
    2931        struct __cfa__parent_vtable const * const * child ) {
     32        assert( child );
    3033        return (__cfa__is_parent(parent, *child)) ? (void *)child : (void *)0;
    3134}
Note: See TracChangeset for help on using the changeset viewer.