Ignore:
Timestamp:
Apr 9, 2021, 2:11:43 PM (8 months ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
arm-eh, jacob/cs343-translation, master, new-ast-unique-expr
Children:
b91bfde
Parents:
e07b589
Message:

Major exception update, seperating type-ids from virtual tables. The major interface changes are done. There is a regression of ?Cancelled(T) to Some?Cancelled. There is some bits of code for the new verion of the ?Cancelled(T) interface already there. Not connected yet but I just reached the limit of what I wanted to do in one commit and then spent over a day cleaning up, so it will replace Some?Cancelled in a future commit.

File:
1 edited

Legend:

Unmodified
Added
Removed
  • libcfa/src/exception.hfa

    re07b589 recfd758  
    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
Note: See TracChangeset for help on using the changeset viewer.