Changeset 69c5c00


Ignore:
Timestamp:
Oct 7, 2020, 6:08:35 PM (4 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
Children:
6fbe9a5
Parents:
41b8ea4
Message:

Rework exceptions mark_exception -> get_exception_vtable and the needed follow up.

Files:
10 edited

Legend:

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

    r41b8ea4 r69c5c00  
    4747
    4848//-----------------------------------------------------------------------------
    49 FORALL_DATA_INSTANCE(CoroutineCancelled,
    50                 (dtype coroutine_t | sized(coroutine_t)), (coroutine_t))
     49FORALL_DATA_INSTANCE(CoroutineCancelled, (dtype coroutine_t), (coroutine_t))
    5150
    5251struct __cfaehm_node {
     
    5958void mark_exception(CoroutineCancelled(T) *) {}
    6059
    61 forall(dtype T | sized(T))
     60forall(dtype T)
    6261void copy(CoroutineCancelled(T) * dst, CoroutineCancelled(T) * src) {
    6362        dst->the_coroutine = src->the_coroutine;
     
    7776        exception_t * except = (exception_t *)(1 + (__cfaehm_node *)desc->cancellation);
    7877
     78        // TODO: Remove explitate vtable set once trac#186 is fixed.
    7979        CoroutineCancelled(T) except;
     80        except.virtual_table = &get_exception_vtable(&except);
    8081        except.the_coroutine = &cor;
    8182        except.the_exception = except;
  • libcfa/src/concurrency/coroutine.hfa

    r41b8ea4 r69c5c00  
    2222//-----------------------------------------------------------------------------
    2323// Exception thrown from resume when a coroutine stack is cancelled.
    24 // Should not have to be be sized (see trac #196).
    25 FORALL_DATA_EXCEPTION(CoroutineCancelled,
    26                 (dtype coroutine_t | sized(coroutine_t)), (coroutine_t)) (
     24FORALL_DATA_EXCEPTION(CoroutineCancelled, (dtype coroutine_t), (coroutine_t)) (
    2725        coroutine_t * the_coroutine;
    2826        exception_t * the_exception;
     
    3028
    3129forall(dtype T)
    32 void mark_exception(CoroutineCancelled(T) *);
    33 
    34 forall(dtype T | sized(T))
    3530void copy(CoroutineCancelled(T) * dst, CoroutineCancelled(T) * src);
    3631
     
    4237// Anything that implements this trait can be resumed.
    4338// Anything that is resumed is a coroutine.
    44 trait is_coroutine(dtype T | sized(T)
    45                 | is_resumption_exception(CoroutineCancelled(T))
    46                 | VTABLE_ASSERTION(CoroutineCancelled, (T))) {
     39trait is_coroutine(dtype T
     40                | is_resumption_exception(CoroutineCancelled(T),
     41                        CoroutineCancelled_vtable(T))) {
    4742        void main(T & this);
    4843        $coroutine * get_coroutine(T & this);
  • libcfa/src/exception.h

    r41b8ea4 r69c5c00  
    7676// implemented in the .c file either so they all have to be inline.
    7777
    78 trait is_exception(dtype exceptT) {
     78trait is_exception(dtype exceptT, dtype virtualT) {
    7979        /* The first field must be a pointer to a virtual table.
    80          * That virtual table must be a decendent of the base exception virtual tab$
     80         * That virtual table must be a decendent of the base exception virtual table.
    8181         */
    82         void mark_exception(exceptT *);
    83         // This is never used and should be a no-op.
     82        virtualT const & get_exception_vtable(exceptT *);
     83        // Always returns the virtual table for this type (associated types hack).
    8484};
    8585
    86 trait is_termination_exception(dtype exceptT | is_exception(exceptT)) {
     86trait is_termination_exception(dtype exceptT, dtype virtualT | is_exception(exceptT, virtualT)) {
    8787        void defaultTerminationHandler(exceptT &);
    8888};
    8989
    90 trait is_resumption_exception(dtype exceptT | is_exception(exceptT)) {
     90trait is_resumption_exception(dtype exceptT, dtype virtualT | is_exception(exceptT, virtualT)) {
    9191        void defaultResumptionHandler(exceptT &);
    9292};
    9393
    94 forall(dtype exceptT | is_termination_exception(exceptT))
     94forall(dtype exceptT, dtype virtualT | is_termination_exception(exceptT, virtualT))
    9595static inline void $throw(exceptT & except) {
    9696        __cfaehm_throw_terminate(
     
    100100}
    101101
    102 forall(dtype exceptT | is_resumption_exception(exceptT))
     102forall(dtype exceptT, dtype virtualT | is_resumption_exception(exceptT, virtualT))
    103103static inline void $throwResume(exceptT & except) {
    104104        __cfaehm_throw_resume(
     
    108108}
    109109
    110 forall(dtype exceptT | is_exception(exceptT))
     110forall(dtype exceptT, dtype virtualT | is_exception(exceptT, virtualT))
    111111static inline void cancel_stack(exceptT & except) __attribute__((noreturn)) {
    112112        __cfaehm_cancel_stack( (exception_t *)&except );
    113113}
    114114
    115 forall(dtype exceptT | is_exception(exceptT))
     115forall(dtype exceptT, dtype virtualT | is_exception(exceptT, virtualT))
    116116static inline void defaultTerminationHandler(exceptT & except) {
    117117        return cancel_stack( except );
    118118}
    119119
    120 forall(dtype exceptT | is_exception(exceptT))
     120forall(dtype exceptT, dtype virtualT | is_exception(exceptT, virtualT))
    121121static inline void defaultResumptionHandler(exceptT & except) {
    122122        throw except;
  • libcfa/src/exception.hfa

    r41b8ea4 r69c5c00  
    9595// visible anywhere you use the instantiation of the exception is used.
    9696#define POLY_VTABLE_DECLARATION(exception_name, ...) \
    97         void mark_exception(exception_name(__VA_ARGS__) *); \
     97        VTABLE_TYPE(exception_name)(__VA_ARGS__) const & get_exception_vtable(exception_name(__VA_ARGS__) *); \
    9898        extern VTABLE_TYPE(exception_name)(__VA_ARGS__) VTABLE_NAME(exception_name)
    9999
     
    160160
    161161#define _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters) \
    162         forall(_UNPACK assertions | VTABLE_ASSERTION(exception_name, parameters) ) \
     162        forall(_UNPACK assertions | \
     163                is_exception(exception_name parameters, VTABLE_TYPE(exception_name) parameters)) \
    163164        void ?{}(exception_name parameters & this)
    164165
    165166#define _FORALL_CTOR0_INSTANCE(exception_name, assertions, parameters) \
    166167        _FORALL_CTOR0_DECLARATION(exception_name, assertions, parameters) { \
    167                 VTABLE_INIT(this, exception_name); \
     168                (this).virtual_table = &get_exception_vtable(&this); \
    168169        }
    169170
     
    185186#define _VTABLE_DECLARATION(exception_name, parent_name, ...) \
    186187        struct exception_name; \
    187         void mark_exception(exception_name *); \
    188188        VTABLE_TYPE(exception_name); \
     189        VTABLE_TYPE(exception_name) const & get_exception_vtable(exception_name *); \
    189190        extern VTABLE_TYPE(exception_name) VTABLE_NAME(exception_name); \
    190191        VTABLE_TYPE(exception_name) { \
     
    197198
    198199#define _VTABLE_INSTANCE(exception_name, parent_name, ...) \
    199         void mark_exception(exception_name *) {} \
     200        VTABLE_TYPE(exception_name) const & get_exception_vtable(exception_name *) { \
     201                return VTABLE_NAME(exception_name); \
     202        } \
    200203        void _GLUE2(exception_name,_copy)(exception_name * this, exception_name * other) { \
    201204                *this = *other; \
     
    218221
    219222#define _POLY_VTABLE_INSTANCE(exception_name, parent_name, ...) \
    220         void mark_exception(exception_name(__VA_ARGS__) *) {} \
     223        extern VTABLE_TYPE(exception_name)(__VA_ARGS__) VTABLE_NAME(exception_name); \
     224        VTABLE_TYPE(exception_name)(__VA_ARGS__) const & get_exception_vtable( \
     225                        exception_name(__VA_ARGS__) *) { \
     226                return VTABLE_NAME(exception_name); \
     227        } \
    221228        void _GLUE2(exception_name,_copy)( \
    222229                        exception_name(__VA_ARGS__) * this, exception_name(__VA_ARGS__) * other) { \
  • src/Concurrency/Keywords.cc

    r41b8ea4 r69c5c00  
    6666                        bool needs_main, AggregateDecl::Aggregate cast_target ) :
    6767                  type_name( type_name ), field_name( field_name ), getter_name( getter_name ),
    68                   context_error( context_error ), vtable_name( getVTableName( exception_name ) ),
     68                  context_error( context_error ), exception_name( exception_name ),
     69                  vtable_name( getVTableName( exception_name ) ),
    6970                  needs_main( needs_main ), cast_target( cast_target ) {}
    7071
     
    8990                const std::string getter_name;
    9091                const std::string context_error;
     92                const std::string exception_name;
    9193                const std::string vtable_name;
    9294                bool needs_main;
     
    9597                StructDecl   * type_decl = nullptr;
    9698                FunctionDecl * dtor_decl = nullptr;
     99                StructDecl * except_decl = nullptr;
    97100                StructDecl * vtable_decl = nullptr;
    98101        };
     
    376379                else if ( is_target(decl) ) {
    377380                        handle( decl );
     381                }
     382                else if ( !except_decl && exception_name == decl->name && decl->body ) {
     383                        except_decl = decl;
    378384                }
    379385                else if ( !vtable_decl && vtable_name == decl->name && decl->body ) {
     
    398404                        assert( struct_type );
    399405
    400                         declsToAddAfter.push_back( Virtual::makeVtableInstance( vtable_decl, {
    401                                 new TypeExpr( struct_type->clone() ),
    402                         }, struct_type, nullptr ) );
     406                        std::list< Expression * > poly_args = { new TypeExpr( struct_type->clone() ) };
     407                        ObjectDecl * vtable_object = Virtual::makeVtableInstance(
     408                                vtable_decl->makeInst( poly_args ), struct_type, nullptr );
     409                        declsToAddAfter.push_back( vtable_object );
     410                        declsToAddAfter.push_back( Virtual::makeGetExceptionFunction(
     411                                vtable_object, except_decl->makeInst( std::move( poly_args ) )
     412                        ) );
    403413                }
    404414
     
    434444        void ConcurrentSueKeyword::addVtableForward( StructDecl * decl ) {
    435445                if ( vtable_decl ) {
    436                         declsToAddBefore.push_back( Virtual::makeVtableForward( vtable_decl, {
     446                        std::list< Expression * > poly_args = {
    437447                                new TypeExpr( new StructInstType( noQualifiers, decl ) ),
    438                         } ) );
     448                        };
     449                        declsToAddBefore.push_back( Virtual::makeGetExceptionForward(
     450                                vtable_decl->makeInst( poly_args ),
     451                                except_decl->makeInst( poly_args )
     452                        ) );
     453                        declsToAddBefore.push_back( Virtual::makeVtableForward(
     454                                vtable_decl->makeInst( move( poly_args ) ) ) );
    439455                // Its only an error if we want a vtable and don't have one.
    440456                } else if ( ! vtable_name.empty() ) {
  • src/SynTree/AggregateDecl.cc

    r41b8ea4 r69c5c00  
    2121#include "Common/utility.h"      // for printAll, cloneAll, deleteAll
    2222#include "Declaration.h"         // for AggregateDecl, TypeDecl, Declaration
     23#include "Expression.h"
    2324#include "Initializer.h"
    2425#include "LinkageSpec.h"         // for Spec, linkageName, Cforall
     
    8889const char * StructDecl::typeString() const { return aggrString( kind ); }
    8990
     91StructInstType * StructDecl::makeInst( std::list< Expression * > const & new_parameters ) {
     92        std::list< Expression * > copy_parameters;
     93        cloneAll( new_parameters, copy_parameters );
     94        return makeInst( move( copy( copy_parameters ) ) );
     95}
     96
     97StructInstType * StructDecl::makeInst( std::list< Expression * > && new_parameters ) {
     98        assert( parameters.size() == new_parameters.size() );
     99        StructInstType * type = new StructInstType( noQualifiers, this );
     100        type->parameters = std::move( new_parameters );
     101        return type;
     102}
     103
    90104const char * UnionDecl::typeString() const { return aggrString( Union ); }
    91105
  • src/SynTree/Declaration.h

    r41b8ea4 r69c5c00  
    306306        bool is_thread   () { return kind == Thread   ; }
    307307
     308        // Make a type instance of this declaration.
     309        StructInstType * makeInst( std::list< Expression * > const & parameters );
     310        StructInstType * makeInst( std::list< Expression * > && parameters );
     311
    308312        virtual StructDecl * clone() const override { return new StructDecl( *this ); }
    309313        virtual void accept( Visitor & v ) override { v.visit( this ); }
  • src/Virtual/Tables.cc

    r41b8ea4 r69c5c00  
    1414//
    1515
     16#include <SynTree/Attribute.h>
    1617#include <SynTree/Declaration.h>
    1718#include <SynTree/Expression.h>
     19#include <SynTree/Statement.h>
    1820#include <SynTree/Type.h>
    1921
     
    3840}
    3941
    40 // Fuse base polymorphic declaration and forall arguments into a new type.
    41 static StructInstType * vtableInstType(
    42                 StructDecl * polyDecl, std::list< Expression * > && parameters ) {
    43         assert( parameters.size() == polyDecl->parameters.size() );
    44         StructInstType * type = new StructInstType(
    45                         Type::Qualifiers( /* Type::Const */ ), polyDecl );
    46         type->parameters = std::move( parameters );
    47         return type;
    48 }
    49 
    5042static ObjectDecl * makeVtableDeclaration(
    5143                StructInstType * type, Initializer * init ) {
     
    6658
    6759ObjectDecl * makeVtableForward( StructInstType * type ) {
     60        assert( type );
    6861        return makeVtableDeclaration( type, nullptr );
    6962}
    7063
    71 ObjectDecl * makeVtableForward(
    72                 StructDecl * polyDecl, std::list< Expression * > && parameters ) {
    73         return makeVtableForward( vtableInstType( polyDecl, std::move( parameters ) ) );
    74 }
    75 
    7664ObjectDecl * makeVtableInstance(
    77                 StructInstType * vtableType, Type * vobject_type, Initializer * init ) {
     65                StructInstType * vtableType, Type * objectType, Initializer * init ) {
     66        assert( vtableType );
     67        assert( objectType );
    7868        StructDecl * vtableStruct = vtableType->baseStruct;
    7969        // Build the initialization
     
    9282                                                new SingleInit( new AddressExpr( new NameExpr( parentInstance ) ) ) );
    9383                        } else if ( std::string( "size" ) == field->name ) {
    94                                 inits.push_back( new SingleInit( new SizeofExpr( vobject_type->clone() ) ) );
     84                                inits.push_back( new SingleInit( new SizeofExpr( objectType->clone() ) ) );
    9585                        } else if ( std::string( "align" ) == field->name ) {
    96                                 inits.push_back( new SingleInit( new AlignofExpr( vobject_type->clone() ) ) );
     86                                inits.push_back( new SingleInit( new AlignofExpr( objectType->clone() ) ) );
    9787                        } else {
    9888                                inits.push_back( new SingleInit( new NameExpr( field->name ) ) );
     
    10898}
    10999
    110 ObjectDecl * makeVtableInstance(
    111                 StructDecl * polyDecl, std::list< Expression * > && parameters,
    112                 Type * vobject, Initializer * init ) {
    113         return makeVtableInstance(
    114                 vtableInstType( polyDecl, std::move( parameters ) ), vobject, init );
     100namespace {
     101        std::string const functionName = "get_exception_vtable";
     102}
     103
     104FunctionDecl * makeGetExceptionForward(
     105                Type * vtableType, Type * exceptType ) {
     106        assert( vtableType );
     107        assert( exceptType );
     108        FunctionType * type = new FunctionType( noQualifiers, false );
     109        vtableType->tq.is_const = true;
     110        type->returnVals.push_back( new ObjectDecl(
     111                "_retvalue",
     112                noStorageClasses,
     113                LinkageSpec::Cforall,
     114                nullptr,
     115                new ReferenceType( noQualifiers, vtableType ),
     116                nullptr,
     117        { new Attribute("unused") }
     118        ) );
     119        type->parameters.push_back( new ObjectDecl(
     120                "__unused",
     121                noStorageClasses,
     122                LinkageSpec::Cforall,
     123                nullptr,
     124                new PointerType( noQualifiers, exceptType ),
     125                nullptr,
     126                { new Attribute("unused") }
     127        ) );
     128        return new FunctionDecl(
     129                functionName,
     130                noStorageClasses,
     131                LinkageSpec::Cforall,
     132                type,
     133                nullptr
     134        );
     135}
     136
     137FunctionDecl * makeGetExceptionFunction(
     138                ObjectDecl * vtableInstance, Type * exceptType ) {
     139        assert( vtableInstance );
     140        assert( exceptType );
     141        FunctionDecl * func = makeGetExceptionForward(
     142                vtableInstance->type->clone(), exceptType );
     143        func->statements = new CompoundStmt( {
     144                new ReturnStmt( new VariableExpr( vtableInstance ) ),
     145        } );
     146        return func;
    115147}
    116148
  • src/Virtual/Tables.h

    r41b8ea4 r69c5c00  
    2727bool isVTableInstanceName( std::string const & name );
    2828
    29 /// Converts exceptions into regular structures.
    30 //void ( std::list< Declaration * > & translationUnit );
    31 
    32 ObjectDecl * makeVtableForward( StructInstType * );
    33 ObjectDecl * makeVtableForward( StructDecl *, std::list< Expression * > && );
    34 /* Create a forward definition of a vtable of the given type.
    35  *
    36  * Instead of the virtual table type you may provide the declaration and all
    37  * the forall parameters.
     29ObjectDecl * makeVtableForward( StructInstType * vtableType );
     30/* Create a forward declaration of a vtable of the given type.
     31 * vtableType node is consumed.
    3832 */
    3933
    40 ObjectDecl * makeVtableInstance( StructInstType *, Type *, Initializer * );
    41 ObjectDecl * makeVtableInstance(
    42         StructDecl *, std::list< Expression * > &&, Type *, Initializer * );
     34ObjectDecl * makeVtableInstance( StructInstType * vtableType, Type * objectType,
     35        Initializer * init = nullptr );
    4336/* Create an initialized definition of a vtable.
    44  *
    45  * The parameters are the virtual table type (or the base declaration and the
    46  * forall parameters), the object type and optionally an initializer.
    47  *
    48  * Instead of the virtual table type you may provide the declaration and all
    49  * the forall parameters.
     37 * vtableType and init (if provided) nodes are consumed.
     38 */
     39
     40// Some special code for how exceptions interact with virtual tables.
     41FunctionDecl * makeGetExceptionForward( Type * vtableType, Type * exceptType );
     42/* Create a forward declaration of the exception virtual function
     43 * linking the vtableType to the exceptType. Both nodes are consumed.
     44 */
     45
     46FunctionDecl * makeGetExceptionFunction(
     47        ObjectDecl * vtableInstance, Type * exceptType );
     48/* Create the definition of the exception virtual function.
     49 * exceptType node is consumed.
    5050 */
    5151
  • tests/exceptions/defaults.cfa

    r41b8ea4 r69c5c00  
    5555
    5656void unhandled_test(void) {
    57         forall(dtype T | is_exception(T))
     57        forall(dtype T, dtype V | is_exception(T, V))
    5858        void defaultTerminationHandler(T &) {
    5959                throw (unhandled_exception){};
Note: See TracChangeset for help on using the changeset viewer.