Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/ExceptTranslate.cc

    r948b0c8 r03eedd5  
    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
    13 // Update Count     : 7
     12// Last Modified On : Fri Jul 28 15:34:00 2017
     13// Update Count     : 6
    1414//
    1515
     
    2424
    2525namespace ControlStruct {
     26
     27        // void (*function)();
     28        static FunctionType try_func_t(noQualifiers, false);
     29        // void (*function)(int, exception);
     30        static FunctionType catch_func_t(noQualifiers, false);
     31        // int (*function)(exception);
     32        static FunctionType match_func_t(noQualifiers, false);
     33        // bool (*function)(exception);
     34        static FunctionType handle_func_t(noQualifiers, false);
     35        // void (*function)(__attribute__((unused)) void *);
     36        static FunctionType finally_func_t(noQualifiers, false);
     37
     38        static void init_func_types() {
     39                static bool init_complete = false;
     40                if (init_complete) {
     41                        return;
     42                }
     43                ObjectDecl index_obj(
     44                        "__handler_index",
     45                        Type::StorageClasses(),
     46                        LinkageSpec::Cforall,
     47                        /*bitfieldWidth*/ NULL,
     48                        new BasicType( noQualifiers, BasicType::SignedInt ),
     49                        /*init*/ NULL
     50                        );
     51                ObjectDecl exception_obj(
     52                        "__exception_inst",
     53                        Type::StorageClasses(),
     54                        LinkageSpec::Cforall,
     55                        /*bitfieldWidth*/ NULL,
     56                        new PointerType(
     57                                noQualifiers,
     58                                new BasicType( noQualifiers, BasicType::SignedInt )
     59                                ),
     60                        /*init*/ NULL
     61                        );
     62                ObjectDecl bool_obj(
     63                        "__ret_bool",
     64                        Type::StorageClasses(),
     65                        LinkageSpec::Cforall,
     66                        /*bitfieldWidth*/ NULL,
     67                        new BasicType(noQualifiers, BasicType::Bool),
     68                        /*init*/ NULL
     69                        );
     70                ObjectDecl voidptr_obj(
     71                        "__hook",
     72                        Type::StorageClasses(),
     73                        LinkageSpec::Cforall,
     74                        NULL,
     75                        new PointerType(
     76                                noQualifiers,
     77                                new VoidType(
     78                                        noQualifiers
     79                                        ),
     80                                std::list<Attribute *>{new Attribute("unused")}
     81                                ),
     82                        NULL
     83                        );
     84
     85                catch_func_t.get_parameters().push_back( index_obj.clone() );
     86                catch_func_t.get_parameters().push_back( exception_obj.clone() );
     87                match_func_t.get_returnVals().push_back( index_obj.clone() );
     88                match_func_t.get_parameters().push_back( exception_obj.clone() );
     89                handle_func_t.get_returnVals().push_back( bool_obj.clone() );
     90                handle_func_t.get_parameters().push_back( exception_obj.clone() );
     91                finally_func_t.get_parameters().push_back( voidptr_obj.clone() );
     92
     93                init_complete = true;
     94        }
    2695
    2796        // Buricratic Helpers (Not having to do with the paritular operation.)
     
    50119        }
    51120
    52         class ExceptionMutatorCore : public WithGuards {
    53                 enum Context { NoHandler, TerHandler, ResHandler };
    54 
    55                 // Also need to handle goto, break & continue.
    56                 // They need to be cut off in a ResHandler, until we enter another
    57                 // loop, switch or the goto stays within the function.
    58 
    59                 Context cur_context;
    60 
    61                 // The current (innermost) termination handler exception declaration.
    62                 ObjectDecl * handler_except_decl;
    63 
    64                 // The built in types used in translation.
    65                 StructDecl * except_decl;
    66                 StructDecl * node_decl;
    67                 StructDecl * hook_decl;
    68 
    69                 // The many helper functions for code/syntree generation.
    70                 Statement * create_given_throw(
    71                         const char * throwFunc, ThrowStmt * throwStmt );
    72                 Statement * create_terminate_throw( ThrowStmt * throwStmt );
    73                 Statement * create_terminate_rethrow( ThrowStmt * throwStmt );
    74                 Statement * create_resume_throw( ThrowStmt * throwStmt );
    75                 Statement * create_resume_rethrow( ThrowStmt * throwStmt );
    76                 CompoundStmt * take_try_block( TryStmt * tryStmt );
    77                 FunctionDecl * create_try_wrapper( CompoundStmt * body );
    78                 FunctionDecl * create_terminate_catch( CatchList &handlers );
    79                 CompoundStmt * create_single_matcher(
    80                         DeclarationWithType * except_obj, CatchStmt * modded_handler );
    81                 FunctionDecl * create_terminate_match( CatchList &handlers );
    82                 CompoundStmt * create_terminate_caller( FunctionDecl * try_wrapper,
    83                         FunctionDecl * terminate_catch, FunctionDecl * terminate_match );
    84                 FunctionDecl * create_resume_handler( CatchList &handlers );
    85                 CompoundStmt * create_resume_wrapper(
    86                         Statement * wraps, FunctionDecl * resume_handler );
    87                 FunctionDecl * create_finally_wrapper( TryStmt * tryStmt );
    88                 ObjectDecl * create_finally_hook( FunctionDecl * finally_wrapper );
    89 
    90                 // Types used in translation, make sure to use clone.
    91                 // void (*function)();
    92                 FunctionType try_func_t;
    93                 // void (*function)(int, exception);
    94                 FunctionType catch_func_t;
    95                 // int (*function)(exception);
    96                 FunctionType match_func_t;
    97                 // bool (*function)(exception);
    98                 FunctionType handle_func_t;
    99                 // void (*function)(__attribute__((unused)) void *);
    100                 FunctionType finally_func_t;
    101 
    102                 StructInstType * create_except_type() {
    103                         assert( except_decl );
    104                         return new StructInstType( noQualifiers, except_decl );
    105                 }
    106                 void init_func_types();
    107 
    108         public:
    109                 ExceptionMutatorCore() :
    110                         cur_context( NoHandler ),
    111                         handler_except_decl( nullptr ),
    112                         except_decl( nullptr ), node_decl( nullptr ), hook_decl( nullptr ),
    113                         try_func_t( noQualifiers, false ),
    114                         catch_func_t( noQualifiers, false ),
    115                         match_func_t( noQualifiers, false ),
    116                         handle_func_t( noQualifiers, false ),
    117                         finally_func_t( noQualifiers, false )
    118                 {
    119                         init_func_types();
    120                 }
    121 
    122                 void premutate( CatchStmt *catchStmt );
    123                 void premutate( StructDecl *structDecl );
    124                 Statement * postmutate( ThrowStmt *throwStmt );
    125                 Statement * postmutate( TryStmt *tryStmt );
    126         };
    127 
    128         void ExceptionMutatorCore::init_func_types() {
    129                 ObjectDecl index_obj(
    130                         "__handler_index",
    131                         Type::StorageClasses(),
    132                         LinkageSpec::Cforall,
    133                         /*bitfieldWidth*/ NULL,
    134                         new BasicType( noQualifiers, BasicType::SignedInt ),
    135                         /*init*/ NULL
    136                         );
    137                 ObjectDecl exception_obj(
    138                         "__exception_inst",
    139                         Type::StorageClasses(),
    140                         LinkageSpec::Cforall,
    141                         /*bitfieldWidth*/ NULL,
    142                         new PointerType(
    143                                 noQualifiers,
    144                                 //new StructInstType( noQualifiers, except_decl )
    145                                 new BasicType( noQualifiers, BasicType::SignedInt )
    146                                 ),
    147                         /*init*/ NULL
    148                         );
    149                 ObjectDecl bool_obj(
    150                         "__ret_bool",
    151                         Type::StorageClasses(),
    152                         LinkageSpec::Cforall,
    153                         /*bitfieldWidth*/ NULL,
    154                         new BasicType( noQualifiers, BasicType::Bool ),
    155                         /*init*/ NULL
    156                         );
    157                 ObjectDecl voidptr_obj(
    158                         "__hook",
    159                         Type::StorageClasses(),
    160                         LinkageSpec::Cforall,
    161                         NULL,
    162                         new PointerType(
    163                                 noQualifiers,
    164                                 new VoidType(
    165                                         noQualifiers
    166                                         ),
    167                                 std::list<Attribute *>{ new Attribute( "unused" ) }
    168                                 ),
    169                         NULL
    170                         );
    171 
    172                 catch_func_t.get_parameters().push_back( index_obj.clone() );
    173                 catch_func_t.get_parameters().push_back( exception_obj.clone() );
    174                 match_func_t.get_returnVals().push_back( index_obj.clone() );
    175                 match_func_t.get_parameters().push_back( exception_obj.clone() );
    176                 handle_func_t.get_returnVals().push_back( bool_obj.clone() );
    177                 handle_func_t.get_parameters().push_back( exception_obj.clone() );
    178                 finally_func_t.get_parameters().push_back( voidptr_obj.clone() );
    179         }
    180 
    181121        // ThrowStmt Mutation Helpers
    182122
    183         Statement * ExceptionMutatorCore::create_given_throw(
     123        Statement * create_given_throw(
    184124                        const char * throwFunc, ThrowStmt * throwStmt ) {
    185125                // There is an extra copy here we might be able to remove with
     
    204144        }
    205145
    206         Statement * ExceptionMutatorCore::create_terminate_throw(
    207                         ThrowStmt *throwStmt ) {
     146        Statement * create_terminate_throw( ThrowStmt *throwStmt ) {
    208147                // { int NAME = EXPR; __throw_terminate( &NAME ); }
    209148                return create_given_throw( "__cfaehm__throw_terminate", throwStmt );
    210149        }
    211150
    212         Statement * ExceptionMutatorCore::create_terminate_rethrow(
    213                         ThrowStmt *throwStmt ) {
     151        Statement * create_terminate_rethrow( ThrowStmt *throwStmt,
     152                        ObjectDecl *handler_except_decl ) {
    214153                // { `handler_except_decl` = NULL; __rethrow_terminate(); }
    215154                assert( nullptr == throwStmt->get_expr() );
     
    234173        }
    235174
    236         Statement * ExceptionMutatorCore::create_resume_throw(
    237                         ThrowStmt *throwStmt ) {
     175        Statement * create_resume_throw( ThrowStmt *throwStmt ) {
    238176                // __throw_resume( EXPR );
    239177                return create_given_throw( "__cfaehm__throw_resume", throwStmt );
    240178        }
    241179
    242         Statement * ExceptionMutatorCore::create_resume_rethrow(
    243                         ThrowStmt *throwStmt ) {
     180        Statement * create_resume_rethrow( ThrowStmt *throwStmt ) {
    244181                // return false;
    245182                Statement * result = new ReturnStmt(
     
    253190        // TryStmt Mutation Helpers
    254191
    255         // XXX: Leave out?
    256         CompoundStmt * ExceptionMutatorCore::take_try_block( TryStmt *tryStmt ) {
     192        CompoundStmt * take_try_block( TryStmt *tryStmt ) {
    257193                CompoundStmt * block = tryStmt->get_block();
    258194                tryStmt->set_block( nullptr );
    259195                return block;
    260196        }
    261 
    262         FunctionDecl * ExceptionMutatorCore::create_try_wrapper(
    263                         CompoundStmt *body ) {
     197        FunctionDecl * create_try_wrapper( CompoundStmt *body ) {
    264198
    265199                return new FunctionDecl( "try", Type::StorageClasses(),
     
    267201        }
    268202
    269         FunctionDecl * ExceptionMutatorCore::create_terminate_catch(
    270                         CatchList &handlers ) {
     203        FunctionDecl * create_terminate_catch( CatchList &handlers ) {
    271204                std::list<CaseStmt *> handler_wrappers;
    272205
     
    364297        // Create a single check from a moddified handler.
    365298        // except_obj is referenced, modded_handler will be freed.
    366         CompoundStmt * ExceptionMutatorCore::create_single_matcher(
     299        CompoundStmt *create_single_matcher(
    367300                        DeclarationWithType * except_obj, CatchStmt * modded_handler ) {
    368301                CompoundStmt * block = new CompoundStmt( noLabels );
     
    429362        }
    430363
    431         FunctionDecl * ExceptionMutatorCore::create_terminate_match(
    432                         CatchList &handlers ) {
     364        FunctionDecl * create_terminate_match( CatchList &handlers ) {
    433365                // int match(exception * except) {
    434366                //     HANDLER WRAPPERS { return `index`; }
     
    466398        }
    467399
    468         CompoundStmt * ExceptionMutatorCore::create_terminate_caller(
     400        CompoundStmt * create_terminate_caller(
    469401                        FunctionDecl * try_wrapper,
    470402                        FunctionDecl * terminate_catch,
    471                         FunctionDecl * terminate_match ) {
     403                        FunctionDecl * terminate_match) {
    472404                // { __cfaehm__try_terminate(`try`, `catch`, `match`); }
    473405
     
    484416        }
    485417
    486         FunctionDecl * ExceptionMutatorCore::create_resume_handler(
    487                         CatchList &handlers ) {
     418        FunctionDecl * create_resume_handler( CatchList &handlers ) {
    488419                // bool handle(exception * except) {
    489420                //     HANDLER WRAPPERS { `hander->body`; return true; }
     
    521452        }
    522453
    523         CompoundStmt * ExceptionMutatorCore::create_resume_wrapper(
     454        CompoundStmt * create_resume_wrapper(
     455                        StructDecl * node_decl,
    524456                        Statement * wraps,
    525457                        FunctionDecl * resume_handler ) {
     
    565497        }
    566498
    567         FunctionDecl * ExceptionMutatorCore::create_finally_wrapper(
    568                         TryStmt * tryStmt ) {
     499        FunctionDecl * create_finally_wrapper( TryStmt * tryStmt ) {
    569500                // void finally() { <finally code> }
    570501                FinallyStmt * finally = tryStmt->get_finally();
     
    578509        }
    579510
    580         ObjectDecl * ExceptionMutatorCore::create_finally_hook(
    581                         FunctionDecl * finally_wrapper ) {
     511        ObjectDecl * create_finally_hook(
     512                        StructDecl * hook_decl, FunctionDecl * finally_wrapper ) {
    582513                // struct __cfaehm__cleanup_hook __finally_hook
    583514                //      __attribute__((cleanup( finally_wrapper )));
     
    605536        }
    606537
    607         // Visiting/Mutating Functions
     538
     539        class ExceptionMutatorCore : public WithGuards {
     540                enum Context { NoHandler, TerHandler, ResHandler };
     541
     542                // Also need to handle goto, break & continue.
     543                // They need to be cut off in a ResHandler, until we enter another
     544                // loop, switch or the goto stays within the function.
     545
     546                Context cur_context;
     547
     548                // The current (innermost) termination handler exception declaration.
     549                ObjectDecl * handler_except_decl;
     550
     551                // We might not need this, but a unique base for each try block's
     552                // generated functions might be nice.
     553                //std::string curFunctionName;
     554                //unsigned int try_count = 0;
     555
     556                StructDecl *node_decl;
     557                StructDecl *hook_decl;
     558
     559        public:
     560                ExceptionMutatorCore() :
     561                        cur_context(NoHandler),
     562                        handler_except_decl( nullptr ),
     563                        node_decl( nullptr ), hook_decl( nullptr )
     564                {}
     565
     566                void premutate( CatchStmt *catchStmt );
     567                void premutate( StructDecl *structDecl );
     568                Statement * postmutate( ThrowStmt *throwStmt );
     569                Statement * postmutate( TryStmt *tryStmt );
     570        };
     571
    608572        void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) {
    609573                // Currently, we make up the declaration, as there isn't one for
    610574                // integers.
    611                 assert( ! catchStmt->get_decl() );
    612575                ObjectDecl * tmp = new ObjectDecl(
    613576                        "_hidden_local",
     
    666629                                return create_terminate_throw( throwStmt );
    667630                        } else if ( TerHandler == cur_context ) {
    668                                 return create_terminate_rethrow( throwStmt );
     631                                return create_terminate_rethrow(
     632                                        throwStmt, handler_except_decl );
    669633                        } else {
    670634                                assertf(false, "Invalid throw in %s at %i\n",
     
    702666                        appendDeclStmt( block, finally_block );
    703667                        // Create and add the finally cleanup hook.
    704                         appendDeclStmt( block, create_finally_hook( finally_block ) );
     668                        appendDeclStmt( block,
     669                                create_finally_hook( hook_decl, finally_block ) );
    705670                }
    706671
     
    716681                        appendDeclStmt( block, resume_handler );
    717682                        // Prepare hooks
    718                         inner = create_resume_wrapper( inner, resume_handler );
     683                        inner = create_resume_wrapper( node_decl, inner, resume_handler );
    719684                }
    720685
     
    741706
    742707        void translateEHM( std::list< Declaration *> & translationUnit ) {
     708                init_func_types();
     709
    743710                PassVisitor<ExceptionMutatorCore> translator;
    744711                mutateAll( translationUnit, translator );
Note: See TracChangeset for help on using the changeset viewer.