Changeset cbce272 for src


Ignore:
Timestamp:
Aug 9, 2017, 2:08:14 PM (4 years ago)
Author:
Andrew Beach <ajbeach@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, with_gc
Children:
65cdc1e
Parents:
e195093
Message:

Structure based exception handling.

Location:
src
Files:
12 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/ExceptTranslate.cc

    re195093 rcbce272  
    1010// Created On       : Wed Jun 14 16:49:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Aug 02 12:09:00 2017
     12// Last Modified On : Tus Aug  8 16:54:00 2017
    1313// Update Count     : 7
    1414//
     
    116116                        handle_func_t( noQualifiers, false ),
    117117                        finally_func_t( noQualifiers, false )
    118                 {
    119                         init_func_types();
    120                 }
     118                {}
    121119
    122120                void premutate( CatchStmt *catchStmt );
     
    127125
    128126        void ExceptionMutatorCore::init_func_types() {
     127                assert( except_decl );
     128
    129129                ObjectDecl index_obj(
    130130                        "__handler_index",
     
    142142                        new PointerType(
    143143                                noQualifiers,
    144                                 //new StructInstType( noQualifiers, except_decl )
    145                                 new BasicType( noQualifiers, BasicType::SignedInt )
     144                                new StructInstType( noQualifiers, except_decl )
    146145                                ),
    147146                        /*init*/ NULL
     
    183182        Statement * ExceptionMutatorCore::create_given_throw(
    184183                        const char * throwFunc, ThrowStmt * throwStmt ) {
    185                 // There is an extra copy here we might be able to remove with
    186                 // references.
    187                 // { int NAME = EXPR; throwFunc( &NAME ); }
    188                 CompoundStmt * result = new CompoundStmt( noLabels );
    189                 ObjectDecl * local = new ObjectDecl(
    190                         "__local_exception_copy",
    191                         Type::StorageClasses(),
    192                         LinkageSpec::Cforall,
    193                         NULL,
    194                         new BasicType( noQualifiers, BasicType::SignedInt ),
    195                         new SingleInit( throwStmt->get_expr() )
    196                         );
    197                 appendDeclStmt( result, local );
     184                // `throwFunc`( `throwStmt->get_name` );
    198185                UntypedExpr * call = new UntypedExpr( new NameExpr( throwFunc ) );
    199                 call->get_args().push_back( new AddressExpr( nameOf( local ) ) );
    200                 result->push_back( new ExprStmt( throwStmt->get_labels(), call ) );
     186                call->get_args().push_back( throwStmt->get_expr() );
    201187                throwStmt->set_expr( nullptr );
    202188                delete throwStmt;
    203                 return result;
     189                return new ExprStmt( noLabels, call );
    204190        }
    205191
    206192        Statement * ExceptionMutatorCore::create_terminate_throw(
    207193                        ThrowStmt *throwStmt ) {
    208                 // { int NAME = EXPR; __throw_terminate( &NAME ); }
     194                // __throw_terminate( `throwStmt->get_name()` ); }
    209195                return create_given_throw( "__cfaehm__throw_terminate", throwStmt );
    210196        }
     
    236222        Statement * ExceptionMutatorCore::create_resume_throw(
    237223                        ThrowStmt *throwStmt ) {
    238                 // __throw_resume( EXPR );
     224                // __throw_resume( `throwStmt->get_name` );
    239225                return create_given_throw( "__cfaehm__throw_resume", throwStmt );
    240226        }
     
    253239        // TryStmt Mutation Helpers
    254240
    255         // XXX: Leave out?
    256241        CompoundStmt * ExceptionMutatorCore::take_try_block( TryStmt *tryStmt ) {
    257242                CompoundStmt * block = tryStmt->get_block();
     
    282267                        CatchStmt * handler = *it;
    283268
    284                         // INTEGERconstant Version
    285                         // case `index`:
    286                         // {
    287                         //     `handler.decl` {inserted} = { except_obj };
    288                         //     `handler.body`
    289                         // }
    290                         // return;
    291                         CompoundStmt * block = new CompoundStmt( noLabels );
    292 
    293                         // Just copy the exception value. (Post Validation)
    294                         ObjectDecl * handler_decl =
    295                                 static_cast<ObjectDecl *>( handler->get_decl() );
    296                         ObjectDecl * local_except = handler_decl->clone();
    297                         local_except->set_init(
    298                                 new ListInit({ new SingleInit( nameOf( except_obj ) ) }) );
    299 #if 0
    300                         // Virtual Exception Vision
    301269                        // case `index`:
    302270                        // {
     
    305273                        // }
    306274                        // return;
    307 
    308                         // Save a cast copy of the exception (should always succeed).
     275                        CompoundStmt * block = new CompoundStmt( noLabels );
     276
     277                        // Just copy the exception value. (Post Validation)
     278                        ObjectDecl * handler_decl =
     279                                static_cast<ObjectDecl *>( handler->get_decl() );
     280                        ObjectDecl * local_except = handler_decl->clone();
    309281                        local_except->set_init(
    310282                                new ListInit({ new SingleInit(
     
    314286                                        ) })
    315287                                );
    316 #endif
    317288                        block->push_back( new DeclStmt( noLabels, local_except ) );
    318289
     
    366337        CompoundStmt * ExceptionMutatorCore::create_single_matcher(
    367338                        DeclarationWithType * except_obj, CatchStmt * modded_handler ) {
     339                // {
     340                //     `modded_handler.decl`
     341                //     if ( `decl.name = (virtual `decl.type`)`except`
     342                //             [&& `modded_handler.cond`] ) {
     343                //         `modded_handler.body`
     344                //     }
     345                // }
     346
    368347                CompoundStmt * block = new CompoundStmt( noLabels );
    369348
     349                // Local Declaration
    370350                ObjectDecl * local_except =
    371351                        dynamic_cast<ObjectDecl *>( modded_handler->get_decl() );
    372352                assert( local_except );
    373353                block->push_back( new DeclStmt( noLabels, local_except ) );
    374 #if 0
    375                 // Virtual Exception Version
    376                 // {
    377                 //     `modded_handler.decl`
    378                 //     if ( `decl.name = (virtual)`except`
    379                 //             [&& `modded_handler.cond`] ) {
    380                 //         `modded_handler.body`
    381                 //     }
    382                 // }
    383354
    384355                // Check for type match.
     
    386357                        new VirtualCastExpr( nameOf( except_obj ),
    387358                                local_except->get_type()->clone() ) );
    388 #endif
    389 
    390                 // INTEGERconstant Version
    391                 // {
    392                 //     `modded_handler.decl` = *`except`
    393                 //     if ( `decl.name` == `modded_handler.cond` ) {
    394                 //         `modded_handler.body`
    395                 //     }
    396                 // }
    397                 ConstantExpr * number =
    398                         dynamic_cast<ConstantExpr*>( modded_handler->get_cond() );
    399                 assert( number );
    400                 modded_handler->set_cond( nullptr );
    401 
    402                 Expression * cond;
    403                 {
    404                         std::list<Expression *> args;
    405                         args.push_back( number );
    406 
    407                         std::list<Expression *> rhs_args;
    408                         rhs_args.push_back( nameOf( except_obj ) );
    409                         Expression * rhs = new UntypedExpr(
    410                                 new NameExpr( "*?" ), rhs_args );
    411                         args.push_back( rhs );
    412 
    413                         cond = new UntypedExpr( new NameExpr( "?==?" /*???*/), args );
    414                 }
    415359
    416360                // Add the check on the conditional if it is provided.
     
    607551        // Visiting/Mutating Functions
    608552        void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) {
    609                 // Currently, we make up the declaration, as there isn't one for
    610                 // integers.
    611                 assert( ! catchStmt->get_decl() );
    612                 ObjectDecl * tmp = new ObjectDecl(
    613                         "_hidden_local",
    614                         Type::StorageClasses(),
    615                         LinkageSpec::Cforall,
    616                         nullptr,
    617                         new PointerType(
    618                                 noQualifiers,
    619                                 new BasicType( noQualifiers, BasicType::SignedInt )
    620                                 ),
    621                         nullptr
    622                         );
    623                 catchStmt->set_decl( tmp );
    624 
    625553                // Validate the Statement's form.
    626554                ObjectDecl * decl =
     
    650578                        // Skip children?
    651579                        return;
     580                } else if ( structDecl->get_name() == "__cfaehm__base_exception_t" ) {
     581                        assert( nullptr == except_decl );
     582                        except_decl = structDecl;
     583                        init_func_types();
    652584                } else if ( structDecl->get_name() == "__cfaehm__try_resume_node" ) {
    653585                        assert( nullptr == node_decl );
     
    661593
    662594        Statement * ExceptionMutatorCore::postmutate( ThrowStmt *throwStmt ) {
     595                assert( except_decl );
     596
    663597                // Ignoring throwStmt->get_target() for now.
    664598                if ( ThrowStmt::Terminate == throwStmt->get_kind() ) {
     
    688622
    689623        Statement * ExceptionMutatorCore::postmutate( TryStmt *tryStmt ) {
     624                assert( except_decl );
    690625                assert( node_decl );
    691626                assert( hook_decl );
  • src/Parser/TypeData.cc

    re195093 rcbce272  
    1010// Created On       : Sat May 16 15:12:51 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tus Jul 18 10:10:00 2017
    13 // Update Count     : 566
     12// Last Modified On : Wed Aug  9 13:50:00 2017
     13// Update Count     : 567
    1414//
    1515
     
    748748} // buildAggInst
    749749
    750 NamedTypeDecl * buildSymbolic( const TypeData * td, const string & name, Type::StorageClasses scs ) {
     750NamedTypeDecl * buildSymbolic( const TypeData * td, const string & name, Type::StorageClasses scs, LinkageSpec::Spec linkage ) {
    751751        assert( td->kind == TypeData::Symbolic );
    752752        NamedTypeDecl * ret;
    753753        assert( td->base );
    754754        if ( td->symbolic.isTypedef ) {
    755                 ret = new TypedefDecl( name, scs, typebuild( td->base ) );
     755                ret = new TypedefDecl( name, scs, typebuild( td->base ), linkage );
    756756        } else {
    757757                ret = new TypeDecl( name, scs, typebuild( td->base ), TypeDecl::Any );
     
    817817                return buildEnum( td, attributes );
    818818        } else if ( td->kind == TypeData::Symbolic ) {
    819                 return buildSymbolic( td, name, scs );
     819                return buildSymbolic( td, name, scs, linkage );
    820820        } else {
    821821                return (new ObjectDecl( name, scs, linkage, bitfieldWidth, typebuild( td ), init, attributes ))->set_asmName( asmName );
  • src/Parser/parser.yy

    re195093 rcbce272  
    99// Author           : Peter A. Buhr
    1010// Created On       : Sat Sep  1 20:22:55 2001
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Mon Jul 31 14:54:32 2017
    13 // Update Count     : 2474
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Aug  4 13:33:00 2017
     13// Update Count     : 2475
    1414//
    1515
     
    182182%type<en> asm_clobbers_list_opt
    183183%type<flag> asm_volatile_opt
     184%type<en> handler_predicate_opt
    184185
    185186// statements
     
    968969
    969970handler_clause:
    970         // TEMPORARY, TEST EXCEPTIONS
    971         handler_key '(' push push INTEGERconstant pop ')' compound_statement pop
    972                 { $$ = new StatementNode( build_catch( $1, nullptr, new ExpressionNode( build_constantInteger( *$5 ) ), $8 ) ); }
    973         | handler_clause handler_key '(' push push INTEGERconstant pop ')' compound_statement pop
    974                 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, nullptr, new ExpressionNode( build_constantInteger( *$6 ) ), $9 ) ) ); }
    975 
    976         | handler_key '(' push push exception_declaration pop handler_predicate_opt ')' compound_statement pop
    977                 { $$ = new StatementNode( build_catch( $1, $5, nullptr, $9 ) ); }
     971        handler_key '(' push push exception_declaration pop handler_predicate_opt ')' compound_statement pop
     972                { $$ = new StatementNode( build_catch( $1, $5, $7, $9 ) ); }
    978973        | handler_clause handler_key '(' push push exception_declaration pop handler_predicate_opt ')' compound_statement pop
    979                 { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $6, nullptr, $10 ) ) ); }
     974                { $$ = (StatementNode *)$1->set_last( new StatementNode( build_catch( $2, $6, $8, $10 ) ) ); }
    980975        ;
    981976
    982977handler_predicate_opt:
    983978        //empty
     979                { $$ = nullptr; }
    984980        | ';' conditional_expression
     981                { $$ = $2; }
    985982        ;
    986983
     
    16741671        | aggregate_key attribute_list_opt typegen_name         // CFA
    16751672                { $$ = $3->addQualifiers( $2 ); }
    1676 
    1677 // Temp, testing TreeStruct
    1678     | STRUCT TRY attribute_list_opt no_attr_identifier_or_type_name
    1679         {
    1680             typedefTable.makeTypedef( *$4 );            // create typedef
    1681             if ( forall ) typedefTable.changeKind( *$4, TypedefTable::TG ); // $
    1682             forall = false;                             // reset
    1683         }
    1684       '{' field_declaration_list '}'
    1685         {
    1686             $$ = DeclarationNode::newTreeStruct( DeclarationNode::Struct,
    1687                 $4, nullptr, nullptr, $7, true )->addQualifiers( $3 );
    1688         }
    1689     | STRUCT TRY attribute_list_opt no_attr_identifier_or_type_name TYPEDEFname
    1690         {
    1691             typedefTable.makeTypedef( *$4 );            // create typedef
    1692             if ( forall ) typedefTable.changeKind( *$4, TypedefTable::TG ); // $
    1693             forall = false;                             // reset
    1694         }
    1695       '{' field_declaration_list '}'
    1696         {
    1697             $$ = DeclarationNode::newTreeStruct( DeclarationNode::Struct,
    1698                 $4, $5, nullptr, $8, true )->addQualifiers( $3 );
    1699         }
    17001673        ;
    17011674
  • src/ResolvExpr/Resolver.cc

    re195093 rcbce272  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 12:17:01 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 23 17:23:14 2017
    13 // Update Count     : 211
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tus Aug  8 16:06:00 2017
     13// Update Count     : 212
    1414//
    1515
     
    7171                virtual void visit( ReturnStmt *returnStmt ) override;
    7272                virtual void visit( ThrowStmt *throwStmt ) override;
     73                virtual void visit( CatchStmt *catchStmt ) override;
    7374
    7475                virtual void visit( SingleInit *singleInit ) override;
     
    368369
    369370        void Resolver::visit( ThrowStmt *throwStmt ) {
     371                // TODO: Replace *exception type with &exception type.
    370372                if ( throwStmt->get_expr() ) {
    371                         Expression * wrapped = new CastExpr( throwStmt->get_expr(), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) );
     373                        StructDecl * exception_decl =
     374                                lookupStruct( "__cfaehm__base_exception_t" );
     375                        assert( exception_decl );
     376                        Expression * wrapped = new CastExpr(
     377                                throwStmt->get_expr(),
     378                                new PointerType(
     379                                        noQualifiers,
     380                                        new StructInstType(
     381                                                noQualifiers,
     382                                                exception_decl
     383                                                )
     384                                        )
     385                                );
    372386                        Expression * newExpr = findSingleExpression( wrapped, *this );
    373387                        throwStmt->set_expr( newExpr );
     388                }
     389        }
     390
     391        void Resolver::visit( CatchStmt *catchStmt ) {
     392                if ( catchStmt->get_cond() ) {
     393                        Expression * wrapped = new CastExpr(
     394                                catchStmt->get_cond(),
     395                                new BasicType( noQualifiers, BasicType::Bool )
     396                                );
     397                        catchStmt->set_cond( findSingleExpression( wrapped, *this ) );
    374398                }
    375399        }
  • src/SymTab/Validate.cc

    re195093 rcbce272  
    99// Author           : Richard C. Bilson
    1010// Created On       : Sun May 17 21:50:04 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 30 16:50:13 2017
    13 // Update Count     : 357
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tus Aug  8 13:27:00 2017
     13// Update Count     : 358
    1414//
    1515
     
    686686                Type *designatorType = tyDecl->get_base()->stripDeclarator();
    687687                if ( StructInstType *aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) {
    688                         return new StructDecl( aggDecl->get_name() );
     688                        return new StructDecl( aggDecl->get_name(), DeclarationNode::Struct, noAttributes, tyDecl->get_linkage() );
    689689                } else if ( UnionInstType *aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) {
    690                         return new UnionDecl( aggDecl->get_name() );
     690                        return new UnionDecl( aggDecl->get_name(), noAttributes, tyDecl->get_linkage() );
    691691                } else if ( EnumInstType *enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) {
    692                         return new EnumDecl( enumDecl->get_name() );
     692                        return new EnumDecl( enumDecl->get_name(), noAttributes, tyDecl->get_linkage() );
    693693                } else {
    694694                        return ret->clone();
     
    783783                                type = new EnumInstType( Type::Qualifiers(), newDeclEnumDecl->get_name() );
    784784                        } // if
    785                         TypedefDeclPtr tyDecl( new TypedefDecl( aggDecl->get_name(), Type::StorageClasses(), type ) );
     785                        TypedefDeclPtr tyDecl( new TypedefDecl( aggDecl->get_name(), Type::StorageClasses(), type, aggDecl->get_linkage() ) );
    786786                        typedefNames[ aggDecl->get_name() ] = std::make_pair( std::move( tyDecl ), scopeLevel );
    787787                } // if
  • src/SynTree/AggregateDecl.cc

    re195093 rcbce272  
    1010// Created On       : Sun May 17 23:56:39 2015
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tus Jun 27 15:30:00 2017
    13 // Update Count     : 21
     12// Last Modified On : Fri Aug  4 14:22:00 2017
     13// Update Count     : 22
    1414//
    1515
     
    4040        using std::endl;
    4141
    42         os << typeString() << " " << get_name();
    43         os << string( indent+2, ' ' ) << "with body " << has_body() << endl;
     42        os << typeString() << " " << get_name() << ":";
     43        if ( get_linkage() != LinkageSpec::Cforall ) {
     44                os << " " << LinkageSpec::linkageName( get_linkage() );
     45        } // if
     46        os << " with body " << has_body() << endl;
    4447
    4548        if ( ! parameters.empty() ) {
  • src/SynTree/Declaration.h

    re195093 rcbce272  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Sat Jul 22 09:52:59 2017
    13 // Update Count     : 124
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Tus Aug  8 13:25:00 2017
     13// Update Count     : 125
    1414//
    1515
     
    223223        typedef NamedTypeDecl Parent;
    224224  public:
    225         TypedefDecl( const std::string &name, Type::StorageClasses scs, Type *type ) : Parent( name, scs, type ) {}
     225        TypedefDecl( const std::string &name, Type::StorageClasses scs, Type *type, LinkageSpec::Spec spec = LinkageSpec::Cforall ) : Parent( name, scs, type ) { set_linkage( spec ); }
    226226        TypedefDecl( const TypedefDecl &other ) : Parent( other ) {}
    227227
  • src/SynTree/NamedTypeDecl.cc

    re195093 rcbce272  
    99// Author           : Richard C. Bilson
    1010// Created On       : Mon May 18 07:44:20 2015
    11 // Last Modified By : Peter A. Buhr
    12 // Last Modified On : Thu Mar 16 07:49:44 2017
    13 // Update Count     : 13
     11// Last Modified By : Andrew Beach
     12// Last Modified On : Wed Aug  9 13:28:00 2017
     13// Update Count     : 14
    1414//
    1515
     
    3838        if ( get_name() != "" ) {
    3939                os << get_name() << ": ";
     40        } // if
     41        if ( get_linkage() != LinkageSpec::Cforall ) {
     42                os << LinkageSpec::linkageName( get_linkage() ) << " ";
    4043        } // if
    4144        get_storageClasses().print( os );
  • src/Virtual/ExpandCasts.cc

    re195093 rcbce272  
    1010// Created On       : Mon Jul 24 13:59:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Wed Jul 26 14:16:00 2017
    13 // Update Count     : 0
     12// Last Modified On : Tus Aug  2 14:59:00 2017
     13// Update Count     : 1
    1414//
    1515
     
    7878
    7979        void VirtualCastCore::premutate( FunctionDecl * functionDecl ) {
    80                 if ( (! vcast_decl) && functionDecl->get_statements() &&
     80                if ( (! vcast_decl) &&
    8181                     functionDecl->get_name() == "__cfa__virtual_cast" ) {
    8282                        vcast_decl = functionDecl;
     
    101101                assertf( castExpr->get_result(), "Virtual Cast target not found before expansion." );
    102102
    103                 //assert( vcast_decl );
     103                assert( vcast_decl );
    104104                assert( pvt_decl );
    105105
    106106                // May only cast to a pointer or reference type.
    107107                // A earlier validation should give a syntax error, this is
    108                 // just to make sure errors don't creep in.
     108                // just to make sure errors don't creep during translation.
     109                // Move to helper with more detailed error messages.
    109110                PointerType * target_type =
    110111                        dynamic_cast<PointerType *>( castExpr->get_result() );
    111         assert( target_type );
     112                assert( target_type );
    112113
    113114                StructInstType * target_struct =
    114115                        dynamic_cast<StructInstType *>( target_type->get_base() );
     116                assert( target_struct );
     117
    115118                StructDecl * target_decl = target_struct->get_baseStruct();
    116119
     
    124127
    125128                Expression * result = new CastExpr(
    126                         //new ApplicationExpr( new VariableExpr( vcast_decl ), {
     129                        //new ApplicationExpr(
     130                                //new AddressExpr( new VariableExpr( vcast_decl ) ),
     131                                //new CastExpr( new VariableExpr( vcast_decl ),
     132                                //      new PointerType( noQualifiers,
     133                                //              vcast_decl->get_type()->clone()
     134                                //              )
     135                                //      ),
    127136                        new UntypedExpr( new NameExpr( "__cfa__virtual_cast" ), {
    128                                 new CastExpr(
    129                                         new AddressExpr( new VariableExpr( table ) ),
    130                                         pointer_to_pvt(1)
    131                                         ),
    132                                 new CastExpr(
    133                                         castExpr->get_arg(),
    134                                         pointer_to_pvt(2)
    135                                         ) }
    136                                 ),
    137                         castExpr->get_result()
     137                                        new CastExpr(
     138                                                new AddressExpr( new VariableExpr( table ) ),
     139                                                pointer_to_pvt(1)
     140                                                ),
     141                                        new CastExpr(
     142                                                castExpr->get_arg(),
     143                                                pointer_to_pvt(2)
     144                                                )
     145                                } ),
     146                        castExpr->get_result()->clone()
    138147                        );
    139148
  • src/libcfa/exception.c

    re195093 rcbce272  
    1010// Created On       : Mon Jun 26 15:13:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Mon Jul 31 13:51:00 2017
    13 // Update Count     : 4
     12// Last Modified On : Fri Aug  4 15:20:00 2017
     13// Update Count     : 6
    1414//
     15
     16#include <stddef.h> // for size_t
    1517
    1618#include "exception.h"
     
    3234#include "lsda.h"
    3335
     36
     37// Base exception vtable is abstract, you should not have base exceptions.
     38struct __cfaehm__base_exception_t_vtable
     39                ___cfaehm__base_exception_t_vtable_instance = {
     40        .parent = NULL,
     41        .size = 0,
     42        .copy = NULL,
     43        .free = NULL,
     44        .msg = NULL
     45};
     46
     47
    3448// Temperary global exception context. Does not work with concurency.
    3549struct exception_context_t {
     
    3953    exception * current_exception;
    4054    int current_handler_index;
    41 
    42         // Storage to avoid using the heap for exceptions.
    43         exception built_in_storage;
    44 } shared_stack = {NULL, NULL, 0, 0, 0};
     55} shared_stack = {NULL, NULL, 0, 0};
    4556
    4657// Get the current exception context.
     
    6980
    7081        // DEBUG
    71         printf("Throwing resumption exception %d\n", *except);
     82        printf("Throwing resumption exception\n");
    7283
    7384        struct __cfaehm__try_resume_node * original_head = shared_stack.current_resume;
     
    8394        }
    8495
    85         printf("Unhandled exception %d\n", *except);
     96        printf("Unhandled exception\n");
    8697        shared_stack.current_resume = original_head;
    8798
     
    124135        // Allocate memory for the exception.
    125136        struct __cfaehm__node * store = malloc(
    126                 sizeof( except ) + sizeof( struct __cfaehm__node ) );
     137                sizeof( struct __cfaehm__node ) + except->virtual_table->size );
    127138
    128139        if ( ! store ) {
     
    136147
    137148        // Copy the exception to storage.
    138         *context->current_exception = *except;
     149        except->virtual_table->copy( context->current_exception, except );
    139150}
    140151
     
    144155
    145156        // DEBUG
    146         printf( "Deleting Exception %d\n", *except);
     157        printf( "Deleting Exception\n");
    147158
    148159        // Remove the exception from the list.
     
    163174
    164175        // Free the old exception node.
     176        except->virtual_table->free( except );
    165177        free( to_free );
    166178}
    167179
    168180// If this isn't a rethrow (*except==0), delete the provided exception.
    169 void __cfaehm__cleanup_terminate( exception ** except ) {
    170         if ( *except ) __cfaehm__delete_exception( *except );
     181void __cfaehm__cleanup_terminate( void * except ) {
     182        if ( *(void**)except ) __cfaehm__delete_exception( *(exception**)except );
    171183}
    172184
  • src/libcfa/exception.h

    re195093 rcbce272  
    1010// Created On       : Mon Jun 26 15:11:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Jul 27 12:42:00 2017
    13 // Update Count     : 4
     12// Last Modified On : Fri Aug  4 15:20:00 2017
     13// Update Count     : 5
    1414//
    1515
     
    2121#endif
    2222
    23 #if 1
    24 typedef int exception;
    25 #else
    26 struct exception_t;
    27 struct exception_t_vtable {
    28         struct exception_t_vtable const * parent;
     23struct __cfaehm__base_exception_t;
     24typedef struct __cfaehm__base_exception_t exception;
     25struct __cfaehm__base_exception_t_vtable {
     26        const struct __cfaehm__base_exception_t_vtable * parent;
    2927        size_t size;
    30         void (*copy)(struct exception_t *this, struct exception_t * other);
    31         void (*free)(struct exception_t *this);
    32         const char (*msg)(struct exception_t *this);
     28        void (*copy)(struct __cfaehm__base_exception_t *this,
     29                     struct __cfaehm__base_exception_t * other);
     30        void (*free)(struct __cfaehm__base_exception_t *this);
     31        const char (*msg)(struct __cfaehm__base_exception_t *this);
    3332};
    34 struct exception_t {
    35         struct exception_vtable const * virtual_table;
     33struct __cfaehm__base_exception_t {
     34        struct __cfaehm__base_exception_t_vtable const * virtual_table;
    3635};
    37 typedef struct exception_t exception;
    38 #endif
     36extern struct __cfaehm__base_exception_t_vtable
     37        ___cfaehm__base_exception_t_vtable_instance;
    3938
    4039
     
    5150
    5251// Clean-up the exception in catch blocks.
    53 void __cfaehm__cleanup_terminate(exception ** except);
     52void __cfaehm__cleanup_terminate(void * except);
    5453
    5554// Data structure creates a list of resume handlers.
  • src/tests/except-0.c

    re195093 rcbce272  
    66#include <stdbool.h>
    77
     8// Local type to mark exits from scopes. (see ERROR)
    89struct signal_exit {
    910        const char * area;
     
    1920}
    2021
    21 void terminate(int except_value) {
     22
     23// Local Exception Types and manual vtable types.
     24//#define TRIVIAL_EXCEPTION(name) //TRIVAL_EXCEPTION(yin)
     25struct yin;
     26struct yin_vtable {
     27        struct exception_t_vtable const * parent;
     28        size_t size;
     29    void (*copy)(yin *this, yin * other);
     30    void (*free)(yin *this);
     31    const char (*msg)(yin *this);
     32};
     33struct yin {
     34        struct yin_vtable const * parent;
     35};
     36void yin_msg(yin) {
     37        return "in";
     38}
     39yin_vtable _yin_vtable_instance = {
     40        &_exception_t_vtable_instance, sizeof(yin), ?{}, ^?{}, yin_msg
     41}
     42
     43
     44void terminate(exception * except_value) {
    2245        signal_exit a = {"terminate function"};
    2346        throw except_value;
     
    2548}
    2649
    27 void resume(int except_value) {
     50void resume(exception * except_value) {
    2851        signal_exit a = {"resume function"};
    2952        throwResume except_value;
Note: See TracChangeset for help on using the changeset viewer.