Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/ExceptTranslate.cc

    r86d5ba7c rac10576  
    1010// Created On       : Wed Jun 14 16:49:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Fri Jul 28 14:03:00 2017
    13 // Update Count     : 5
     12// Last Modified On : Tus Jul 18 10:09:00 2017
     13// Update Count     : 4
    1414//
    1515
     
    2121#include "SynTree/Type.h"
    2222#include "SynTree/Attribute.h"
    23 #include "SynTree/VarExprReplacer.h"
    2423
    2524namespace ControlStruct {
    2625
     26        // This (large) section could probably be moved out of the class
     27        // and be static helpers instead.
     28
     29        // Type(Qualifiers &, false, std::list<Attribute *> &)
     30
    2731        // void (*function)();
    28         static FunctionType try_func_t(noQualifiers, false);
     32        static FunctionType try_func_t(Type::Qualifiers(), false);
    2933        // void (*function)(int, exception);
    30         static FunctionType catch_func_t(noQualifiers, false);
     34        static FunctionType catch_func_t(Type::Qualifiers(), false);
    3135        // int (*function)(exception);
    32         static FunctionType match_func_t(noQualifiers, false);
     36        static FunctionType match_func_t(Type::Qualifiers(), false);
    3337        // bool (*function)(exception);
    34         static FunctionType handle_func_t(noQualifiers, false);
     38        static FunctionType handle_func_t(Type::Qualifiers(), false);
    3539        // void (*function)(__attribute__((unused)) void *);
    36         static FunctionType finally_func_t(noQualifiers, false);
     40        static FunctionType finally_func_t(Type::Qualifiers(), false);
    3741
    3842        static void init_func_types() {
     
    111115        }
    112116
     117        template<typename T>
     118        void free_all( std::list<T *> &list ) {
     119                typename std::list<T *>::iterator it;
     120                for ( it = list.begin() ; it != list.end() ; ++it ) {
     121                        delete *it;
     122                }
     123                list.clear();
     124        }
     125
    113126        void appendDeclStmt( CompoundStmt * block, Declaration * item ) {
    114127                block->push_back(new DeclStmt(noLabels, item));
     
    123136        Statement * create_given_throw(
    124137                        const char * throwFunc, ThrowStmt * throwStmt ) {
    125                 // There is an extra copy here we might be able to remove with
    126                 // references.
    127138                // { int NAME = EXPR; throwFunc( &NAME ); }
    128139                CompoundStmt * result = new CompoundStmt( noLabels );
     
    148159                return create_given_throw( "__cfaehm__throw_terminate", throwStmt );
    149160        }
    150 
    151         Statement * create_terminate_rethrow( ThrowStmt *throwStmt,
    152                         ObjectDecl *handler_except_decl ) {
    153                 // { `handler_except_decl` = NULL; __rethrow_terminate(); }
     161        Statement * create_terminate_rethrow( ThrowStmt *throwStmt ) {
     162                // __rethrow_terminate();
    154163                assert( nullptr == throwStmt->get_expr() );
    155                 assert( handler_except_decl );
    156 
    157                 CompoundStmt * result = new CompoundStmt( throwStmt->get_labels() );
    158                 result->push_back( new ExprStmt( noLabels, UntypedExpr::createAssign(
    159                         nameOf( handler_except_decl ),
    160                         new ConstantExpr( Constant::null(
    161                                 new PointerType(
    162                                         noQualifiers,
    163                                         handler_except_decl->get_type()->clone()
    164                                         )
    165                                 ) )
    166                         ) ) );
    167                 result->push_back( new ExprStmt(
    168                         noLabels,
     164                Statement * result = new ExprStmt(
     165                        throwStmt->get_labels(),
    169166                        new UntypedExpr( new NameExpr( "__cfaehm__rethrow_terminate" ) )
    170                         ) );
     167                        );
    171168                delete throwStmt;
    172169                return result;
    173170        }
    174 
    175171        Statement * create_resume_throw( ThrowStmt *throwStmt ) {
    176172                // __throw_resume( EXPR );
    177173                return create_given_throw( "__cfaehm__throw_resume", throwStmt );
    178174        }
    179 
    180175        Statement * create_resume_rethrow( ThrowStmt *throwStmt ) {
    181176                // return false;
     
    206201                FunctionType *func_type = catch_func_t.clone();
    207202                DeclarationWithType * index_obj = func_type->get_parameters().front();
    208                 DeclarationWithType * except_obj = func_type->get_parameters().back();
     203        //      DeclarationWithType * except_obj = func_type->get_parameters().back();
    209204
    210205                // Index 1..{number of handlers}
     
    218213                        // case `index`:
    219214                        // {
    220                         //     `handler.decl` {inserted} = { except_obj };
    221215                        //     `handler.body`
    222216                        // }
    223217                        // return;
    224                         CompoundStmt * block = new CompoundStmt( noLabels );
    225 
    226                         // Just copy the exception value.
    227                         // TODO: Or just store an ObjectDecl?
    228                         ObjectDecl * handler_decl =
    229                                 dynamic_cast<ObjectDecl*>( handler->get_decl() );
    230                         assert( handler_decl );
    231                         ObjectDecl * local_except = handler_decl->clone();
    232                         local_except->set_init(
    233                                 new ListInit({ new SingleInit( nameOf( except_obj ) ) }) );
    234 #if 0
    235                         // Virtual Exception Vision
    236                         // case `index`:
    237                         // {
    238                         //     `handler.decl` = { (virtual `decl.type`)`except` };
    239                         //     `handler.body`;
    240                         // }
    241                         // return;
    242 
    243                         // Save a cast copy of the exception (should always succeed).
    244                         ObjectDecl * local_except = handler->get_decl()->clone();
    245                         local_except.set_init(
    246                                 new ListInit({ new SingleInit(
    247                                         new VirtualCastExpr( nameOf( except_obj ),
    248                                                 local_except->get_type()
    249                                                 )
    250                                         ) }) );
    251 #endif
    252                         block->push_back( new DeclStmt( noLabels, local_except ) );
    253 
    254                         // Add the cleanup attribute.
    255                         local_except->get_attributes().push_back( new Attribute(
    256                                 "cleanup",
    257                                 { new NameExpr( "__cfaehm__cleanup_terminate" ) }
    258                                 ) );
    259 
    260                         // Update variables in the body to point to this local copy.
    261                         {
    262                                 VarExprReplacer::DeclMap mapping;
    263                                 mapping[ handler_decl ] = local_except;
    264                                 VarExprReplacer mapper( mapping );
    265                                 handler->get_body()->accept( mapper );
    266                         }
    267 
    268                         block->push_back( handler->get_body() );
     218                        std::list<Statement *> caseBody;
     219                        caseBody.push_back( handler->get_body() );
    269220                        handler->set_body( nullptr );
    270 
    271                         std::list<Statement *> caseBody
    272                                         { block, new ReturnStmt( noLabels, nullptr ) };
     221                        caseBody.push_back( new ReturnStmt( noLabels, nullptr ) );
     222
    273223                        handler_wrappers.push_back( new CaseStmt(
    274224                                noLabels,
     
    303253                CompoundStmt * block = new CompoundStmt( noLabels );
    304254
    305                 ObjectDecl * local_except =
    306                         dynamic_cast<ObjectDecl *>( modded_handler->get_decl() );
    307                 assert( local_except );
    308                 block->push_back( new DeclStmt( noLabels, local_except ) );
    309 #if 0
    310                 // Virtual Exception Version
    311                 // {
    312                 //     `modded_handler.decl`
    313                 //     if ( `decl.name = (virtual)`except`
    314                 //             [&& `modded_handler.cond`] ) {
    315                 //         `modded_handler.body`
    316                 //     }
    317                 // }
    318 
    319                 // Check for type match.
    320                 Expression * cond = UntypedExpr::createAssign( nameOf( local_except ),
    321                         new VirtualCastExpr( nameOf( except_obj ),
    322                                 local_except->get_type()->clone() ) );
    323 #endif
    324 
    325255                // INTEGERconstant Version
    326                 // {
    327                 //     `modded_handler.decl` = *`except`
    328                 //     if ( `decl.name` == `modded_handler.cond` ) {
    329                 //         `modded_handler.body`
    330                 //     }
    331                 // }
     256                assert( nullptr == modded_handler->get_decl() );
    332257                ConstantExpr * number =
    333258                        dynamic_cast<ConstantExpr*>( modded_handler->get_cond() );
     
    349274                }
    350275
    351                 // Add the check on the conditional if it is provided.
    352276                if ( modded_handler->get_cond() ) {
    353277                        cond = new LogicalExpr( cond, modded_handler->get_cond() );
    354278                }
    355                 // Construct the match condition.
    356279                block->push_back( new IfStmt( noLabels,
    357280                        cond, modded_handler->get_body(), nullptr ) );
     
    365288
    366289        FunctionDecl * create_terminate_match( CatchList &handlers ) {
    367                 // int match(exception * except) {
    368                 //     HANDLER WRAPPERS { return `index`; }
    369                 // }
    370 
    371290                CompoundStmt * body = new CompoundStmt( noLabels );
    372291
     
    404323                        FunctionDecl * terminate_catch,
    405324                        FunctionDecl * terminate_match) {
    406                 // { __cfaehm__try_terminate(`try`, `catch`, `match`); }
    407325
    408326                UntypedExpr * caller = new UntypedExpr( new NameExpr(
     
    419337
    420338        FunctionDecl * create_resume_handler( CatchList &handlers ) {
    421                 // bool handle(exception * except) {
    422                 //     HANDLER WRAPPERS { `hander->body`; return true; }
    423                 // }
    424339                CompoundStmt * body = new CompoundStmt( noLabels );
    425340
     
    500415
    501416        FunctionDecl * create_finally_wrapper( TryStmt * tryStmt ) {
    502                 // void finally() { <finally code> }
    503417                FinallyStmt * finally = tryStmt->get_finally();
    504418                CompoundStmt * body = finally->get_block();
     
    548462                Context cur_context;
    549463
    550                 // The current (innermost) termination handler exception declaration.
    551                 ObjectDecl * handler_except_decl;
    552 
    553464                // We might not need this, but a unique base for each try block's
    554465                // generated functions might be nice.
     
    562473                ExceptionMutatorCore() :
    563474                        cur_context(NoHandler),
    564                         handler_except_decl( nullptr ),
    565                         node_decl( nullptr ), hook_decl( nullptr )
     475                        node_decl(nullptr), hook_decl(nullptr)
    566476                {}
    567477
     
    571481                Statement * postmutate( TryStmt *tryStmt );
    572482        };
    573 
    574         void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) {
    575                 // Currently, we make up the declaration, as there isn't one for
    576                 // integers.
    577                 ObjectDecl * tmp = new ObjectDecl(
    578                         "_hidden_local",
    579                         Type::StorageClasses(),
    580                         LinkageSpec::Cforall,
    581                         nullptr,
    582                         new PointerType(
    583                                 noQualifiers,
    584                                 new BasicType( noQualifiers, BasicType::SignedInt )
    585                                 ),
    586                         nullptr
    587                         );
    588                 catchStmt->set_decl( tmp );
    589 
    590                 GuardValue( cur_context );
    591                 if ( CatchStmt::Terminate == catchStmt->get_kind() ) {
    592                         cur_context = TerHandler;
    593 
    594                         GuardValue( handler_except_decl );
    595                         handler_except_decl = tmp;
    596                         //handler_except_decl = catchStmt->get_decl();
    597                 } else {
    598                         cur_context = ResHandler;
    599                 }
    600         }
    601 
    602         void ExceptionMutatorCore::premutate( StructDecl *structDecl ) {
    603                 if ( !structDecl->has_body() ) {
    604                         // Skip children?
    605                         return;
    606                 } else if ( structDecl->get_name() == "__cfaehm__try_resume_node" ) {
    607                         assert( nullptr == node_decl );
    608                         node_decl = structDecl;
    609                 } else if ( structDecl->get_name() == "__cfaehm__cleanup_hook" ) {
    610                         assert( nullptr == hook_decl );
    611                         hook_decl = structDecl;
    612                 }
    613                 // Later we might get the exception type as well.
    614         }
    615483
    616484        Statement * ExceptionMutatorCore::postmutate( ThrowStmt *throwStmt ) {
     
    620488                                return create_terminate_throw( throwStmt );
    621489                        } else if ( TerHandler == cur_context ) {
    622                                 return create_terminate_rethrow(
    623                                         throwStmt, handler_except_decl );
     490                                return create_terminate_rethrow( throwStmt );
    624491                        } else {
    625492                                assertf(false, "Invalid throw in %s at %i\n",
     
    693560                block->push_back( inner );
    694561
     562                //free_all( termination_handlers );
     563                //free_all( resumption_handlers );
     564
    695565                return block;
     566        }
     567
     568        void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) {
     569                GuardValue( cur_context );
     570                if ( CatchStmt::Terminate == catchStmt->get_kind() ) {
     571                        cur_context = TerHandler;
     572                } else {
     573                        cur_context = ResHandler;
     574                }
     575        }
     576
     577        void ExceptionMutatorCore::premutate( StructDecl *structDecl ) {
     578                if ( !structDecl->has_body() ) {
     579                        // Skip children?
     580                        return;
     581                } else if ( structDecl->get_name() == "__cfaehm__try_resume_node" ) {
     582                        assert( nullptr == node_decl );
     583                        node_decl = structDecl;
     584                } else if ( structDecl->get_name() == "__cfaehm__cleanup_hook" ) {
     585                        assert( nullptr == hook_decl );
     586                        hook_decl = structDecl;
     587                }
     588                // Later we might get the exception type as well.
    696589        }
    697590
Note: See TracChangeset for help on using the changeset viewer.