Ignore:
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/ControlStruct/ExceptTranslate.cc

    rcbce272 rac10576  
    1010// Created On       : Wed Jun 14 16:49:00 2017
    1111// Last Modified By : Andrew Beach
    12 // Last Modified On : Tus Aug  8 16:54:00 2017
    13 // Update Count     : 7
     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 {
     25
     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
     31        // void (*function)();
     32        static FunctionType try_func_t(Type::Qualifiers(), false);
     33        // void (*function)(int, exception);
     34        static FunctionType catch_func_t(Type::Qualifiers(), false);
     35        // int (*function)(exception);
     36        static FunctionType match_func_t(Type::Qualifiers(), false);
     37        // bool (*function)(exception);
     38        static FunctionType handle_func_t(Type::Qualifiers(), false);
     39        // void (*function)(__attribute__((unused)) void *);
     40        static FunctionType finally_func_t(Type::Qualifiers(), false);
     41
     42        static void init_func_types() {
     43                static bool init_complete = false;
     44                if (init_complete) {
     45                        return;
     46                }
     47                ObjectDecl index_obj(
     48                        "__handler_index",
     49                        Type::StorageClasses(),
     50                        LinkageSpec::Cforall,
     51                        /*bitfieldWidth*/ NULL,
     52                        new BasicType( noQualifiers, BasicType::SignedInt ),
     53                        /*init*/ NULL
     54                        );
     55                ObjectDecl exception_obj(
     56                        "__exception_inst",
     57                        Type::StorageClasses(),
     58                        LinkageSpec::Cforall,
     59                        /*bitfieldWidth*/ NULL,
     60                        new PointerType(
     61                                noQualifiers,
     62                                new BasicType( noQualifiers, BasicType::SignedInt )
     63                                ),
     64                        /*init*/ NULL
     65                        );
     66                ObjectDecl bool_obj(
     67                        "__ret_bool",
     68                        Type::StorageClasses(),
     69                        LinkageSpec::Cforall,
     70                        /*bitfieldWidth*/ NULL,
     71                        new BasicType(noQualifiers, BasicType::Bool),
     72                        /*init*/ NULL
     73                        );
     74                ObjectDecl voidptr_obj(
     75                        "__hook",
     76                        Type::StorageClasses(),
     77                        LinkageSpec::Cforall,
     78                        NULL,
     79                        new PointerType(
     80                                noQualifiers,
     81                                new VoidType(
     82                                        noQualifiers
     83                                        ),
     84                                std::list<Attribute *>{new Attribute("unused")}
     85                                ),
     86                        NULL
     87                        );
     88
     89                catch_func_t.get_parameters().push_back( index_obj.clone() );
     90                catch_func_t.get_parameters().push_back( exception_obj.clone() );
     91                match_func_t.get_returnVals().push_back( index_obj.clone() );
     92                match_func_t.get_parameters().push_back( exception_obj.clone() );
     93                handle_func_t.get_returnVals().push_back( bool_obj.clone() );
     94                handle_func_t.get_parameters().push_back( exception_obj.clone() );
     95                finally_func_t.get_parameters().push_back( voidptr_obj.clone() );
     96
     97                init_complete = true;
     98        }
    2699
    27100        // Buricratic Helpers (Not having to do with the paritular operation.)
     
    42115        }
    43116
     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
    44126        void appendDeclStmt( CompoundStmt * block, Declaration * item ) {
    45127                block->push_back(new DeclStmt(noLabels, item));
     
    50132        }
    51133
    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 
    120                 void premutate( CatchStmt *catchStmt );
    121                 void premutate( StructDecl *structDecl );
    122                 Statement * postmutate( ThrowStmt *throwStmt );
    123                 Statement * postmutate( TryStmt *tryStmt );
    124         };
    125 
    126         void ExceptionMutatorCore::init_func_types() {
    127                 assert( except_decl );
    128 
    129                 ObjectDecl index_obj(
    130                         "__handler_index",
    131                         Type::StorageClasses(),
    132                         LinkageSpec::Cforall,
    133                         /*bitfieldWidth*/ NULL,
     134        // ThrowStmt Mutation Helpers
     135
     136        Statement * create_given_throw(
     137                        const char * throwFunc, ThrowStmt * throwStmt ) {
     138                // { int NAME = EXPR; throwFunc( &NAME ); }
     139                CompoundStmt * result = new CompoundStmt( noLabels );
     140                ObjectDecl * local = new ObjectDecl(
     141                        "__local_exception_copy",
     142                        Type::StorageClasses(),
     143                        LinkageSpec::Cforall,
     144                        NULL,
    134145                        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                                 ),
    146                         /*init*/ NULL
    147                         );
    148                 ObjectDecl bool_obj(
    149                         "__ret_bool",
    150                         Type::StorageClasses(),
    151                         LinkageSpec::Cforall,
    152                         /*bitfieldWidth*/ NULL,
    153                         new BasicType( noQualifiers, BasicType::Bool ),
    154                         /*init*/ NULL
    155                         );
    156                 ObjectDecl voidptr_obj(
    157                         "__hook",
    158                         Type::StorageClasses(),
    159                         LinkageSpec::Cforall,
    160                         NULL,
    161                         new PointerType(
    162                                 noQualifiers,
    163                                 new VoidType(
    164                                         noQualifiers
    165                                         ),
    166                                 std::list<Attribute *>{ new Attribute( "unused" ) }
    167                                 ),
    168                         NULL
    169                         );
    170 
    171                 catch_func_t.get_parameters().push_back( index_obj.clone() );
    172                 catch_func_t.get_parameters().push_back( exception_obj.clone() );
    173                 match_func_t.get_returnVals().push_back( index_obj.clone() );
    174                 match_func_t.get_parameters().push_back( exception_obj.clone() );
    175                 handle_func_t.get_returnVals().push_back( bool_obj.clone() );
    176                 handle_func_t.get_parameters().push_back( exception_obj.clone() );
    177                 finally_func_t.get_parameters().push_back( voidptr_obj.clone() );
    178         }
    179 
    180         // ThrowStmt Mutation Helpers
    181 
    182         Statement * ExceptionMutatorCore::create_given_throw(
    183                         const char * throwFunc, ThrowStmt * throwStmt ) {
    184                 // `throwFunc`( `throwStmt->get_name` );
     146                        new SingleInit( throwStmt->get_expr() )
     147                        );
     148                appendDeclStmt( result, local );
    185149                UntypedExpr * call = new UntypedExpr( new NameExpr( throwFunc ) );
    186                 call->get_args().push_back( throwStmt->get_expr() );
     150                call->get_args().push_back( new AddressExpr( nameOf( local ) ) );
     151                result->push_back( new ExprStmt( throwStmt->get_labels(), call ) );
    187152                throwStmt->set_expr( nullptr );
    188153                delete throwStmt;
    189                 return new ExprStmt( noLabels, call );
    190         }
    191 
    192         Statement * ExceptionMutatorCore::create_terminate_throw(
    193                         ThrowStmt *throwStmt ) {
    194                 // __throw_terminate( `throwStmt->get_name()` ); }
     154                return result;
     155        }
     156
     157        Statement * create_terminate_throw( ThrowStmt *throwStmt ) {
     158                // { int NAME = EXPR; __throw_terminate( &NAME ); }
    195159                return create_given_throw( "__cfaehm__throw_terminate", throwStmt );
    196160        }
    197 
    198         Statement * ExceptionMutatorCore::create_terminate_rethrow(
    199                         ThrowStmt *throwStmt ) {
    200                 // { `handler_except_decl` = NULL; __rethrow_terminate(); }
     161        Statement * create_terminate_rethrow( ThrowStmt *throwStmt ) {
     162                // __rethrow_terminate();
    201163                assert( nullptr == throwStmt->get_expr() );
    202                 assert( handler_except_decl );
    203 
    204                 CompoundStmt * result = new CompoundStmt( throwStmt->get_labels() );
    205                 result->push_back( new ExprStmt( noLabels, UntypedExpr::createAssign(
    206                         nameOf( handler_except_decl ),
    207                         new ConstantExpr( Constant::null(
    208                                 new PointerType(
    209                                         noQualifiers,
    210                                         handler_except_decl->get_type()->clone()
    211                                         )
    212                                 ) )
    213                         ) ) );
    214                 result->push_back( new ExprStmt(
    215                         noLabels,
     164                Statement * result = new ExprStmt(
     165                        throwStmt->get_labels(),
    216166                        new UntypedExpr( new NameExpr( "__cfaehm__rethrow_terminate" ) )
    217                         ) );
     167                        );
    218168                delete throwStmt;
    219169                return result;
    220170        }
    221 
    222         Statement * ExceptionMutatorCore::create_resume_throw(
    223                         ThrowStmt *throwStmt ) {
    224                 // __throw_resume( `throwStmt->get_name` );
     171        Statement * create_resume_throw( ThrowStmt *throwStmt ) {
     172                // __throw_resume( EXPR );
    225173                return create_given_throw( "__cfaehm__throw_resume", throwStmt );
    226174        }
    227 
    228         Statement * ExceptionMutatorCore::create_resume_rethrow(
    229                         ThrowStmt *throwStmt ) {
     175        Statement * create_resume_rethrow( ThrowStmt *throwStmt ) {
    230176                // return false;
    231177                Statement * result = new ReturnStmt(
     
    239185        // TryStmt Mutation Helpers
    240186
    241         CompoundStmt * ExceptionMutatorCore::take_try_block( TryStmt *tryStmt ) {
     187        CompoundStmt * take_try_block( TryStmt *tryStmt ) {
    242188                CompoundStmt * block = tryStmt->get_block();
    243189                tryStmt->set_block( nullptr );
    244190                return block;
    245191        }
    246 
    247         FunctionDecl * ExceptionMutatorCore::create_try_wrapper(
    248                         CompoundStmt *body ) {
     192        FunctionDecl * create_try_wrapper( CompoundStmt *body ) {
    249193
    250194                return new FunctionDecl( "try", Type::StorageClasses(),
     
    252196        }
    253197
    254         FunctionDecl * ExceptionMutatorCore::create_terminate_catch(
    255                         CatchList &handlers ) {
     198        FunctionDecl * create_terminate_catch( CatchList &handlers ) {
    256199                std::list<CaseStmt *> handler_wrappers;
    257200
    258201                FunctionType *func_type = catch_func_t.clone();
    259202                DeclarationWithType * index_obj = func_type->get_parameters().front();
    260                 DeclarationWithType * except_obj = func_type->get_parameters().back();
     203        //      DeclarationWithType * except_obj = func_type->get_parameters().back();
    261204
    262205                // Index 1..{number of handlers}
     
    267210                        CatchStmt * handler = *it;
    268211
     212                        // INTEGERconstant Version
    269213                        // case `index`:
    270214                        // {
    271                         //     `handler.decl` = { (virtual `decl.type`)`except` };
    272                         //     `handler.body`;
     215                        //     `handler.body`
    273216                        // }
    274217                        // return;
    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();
    281                         local_except->set_init(
    282                                 new ListInit({ new SingleInit(
    283                                         new VirtualCastExpr( nameOf( except_obj ),
    284                                                 local_except->get_type()
    285                                                 )
    286                                         ) })
    287                                 );
    288                         block->push_back( new DeclStmt( noLabels, local_except ) );
    289 
    290                         // Add the cleanup attribute.
    291                         local_except->get_attributes().push_back( new Attribute(
    292                                 "cleanup",
    293                                 { new NameExpr( "__cfaehm__cleanup_terminate" ) }
    294                                 ) );
    295 
    296                         // Update variables in the body to point to this local copy.
    297                         {
    298                                 VarExprReplacer::DeclMap mapping;
    299                                 mapping[ handler_decl ] = local_except;
    300                                 VarExprReplacer mapper( mapping );
    301                                 handler->get_body()->accept( mapper );
    302                         }
    303 
    304                         block->push_back( handler->get_body() );
     218                        std::list<Statement *> caseBody;
     219                        caseBody.push_back( handler->get_body() );
    305220                        handler->set_body( nullptr );
    306 
    307                         std::list<Statement *> caseBody
    308                                         { block, new ReturnStmt( noLabels, nullptr ) };
     221                        caseBody.push_back( new ReturnStmt( noLabels, nullptr ) );
     222
    309223                        handler_wrappers.push_back( new CaseStmt(
    310224                                noLabels,
     
    335249        // Create a single check from a moddified handler.
    336250        // except_obj is referenced, modded_handler will be freed.
    337         CompoundStmt * ExceptionMutatorCore::create_single_matcher(
     251        CompoundStmt *create_single_matcher(
    338252                        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 
    347253                CompoundStmt * block = new CompoundStmt( noLabels );
    348254
    349                 // Local Declaration
    350                 ObjectDecl * local_except =
    351                         dynamic_cast<ObjectDecl *>( modded_handler->get_decl() );
    352                 assert( local_except );
    353                 block->push_back( new DeclStmt( noLabels, local_except ) );
    354 
    355                 // Check for type match.
    356                 Expression * cond = UntypedExpr::createAssign( nameOf( local_except ),
    357                         new VirtualCastExpr( nameOf( except_obj ),
    358                                 local_except->get_type()->clone() ) );
    359 
    360                 // Add the check on the conditional if it is provided.
     255                // INTEGERconstant Version
     256                assert( nullptr == modded_handler->get_decl() );
     257                ConstantExpr * number =
     258                        dynamic_cast<ConstantExpr*>( modded_handler->get_cond() );
     259                assert( number );
     260                modded_handler->set_cond( nullptr );
     261
     262                Expression * cond;
     263                {
     264                        std::list<Expression *> args;
     265                        args.push_back( number );
     266
     267                        std::list<Expression *> rhs_args;
     268                        rhs_args.push_back( nameOf( except_obj ) );
     269                        Expression * rhs = new UntypedExpr(
     270                                new NameExpr( "*?" ), rhs_args );
     271                        args.push_back( rhs );
     272
     273                        cond = new UntypedExpr( new NameExpr( "?==?" /*???*/), args );
     274                }
     275
    361276                if ( modded_handler->get_cond() ) {
    362277                        cond = new LogicalExpr( cond, modded_handler->get_cond() );
    363278                }
    364                 // Construct the match condition.
    365279                block->push_back( new IfStmt( noLabels,
    366280                        cond, modded_handler->get_body(), nullptr ) );
     
    373287        }
    374288
    375         FunctionDecl * ExceptionMutatorCore::create_terminate_match(
    376                         CatchList &handlers ) {
    377                 // int match(exception * except) {
    378                 //     HANDLER WRAPPERS { return `index`; }
    379                 // }
    380 
     289        FunctionDecl * create_terminate_match( CatchList &handlers ) {
    381290                CompoundStmt * body = new CompoundStmt( noLabels );
    382291
     
    410319        }
    411320
    412         CompoundStmt * ExceptionMutatorCore::create_terminate_caller(
     321        CompoundStmt * create_terminate_caller(
    413322                        FunctionDecl * try_wrapper,
    414323                        FunctionDecl * terminate_catch,
    415                         FunctionDecl * terminate_match ) {
    416                 // { __cfaehm__try_terminate(`try`, `catch`, `match`); }
     324                        FunctionDecl * terminate_match) {
    417325
    418326                UntypedExpr * caller = new UntypedExpr( new NameExpr(
     
    428336        }
    429337
    430         FunctionDecl * ExceptionMutatorCore::create_resume_handler(
    431                         CatchList &handlers ) {
    432                 // bool handle(exception * except) {
    433                 //     HANDLER WRAPPERS { `hander->body`; return true; }
    434                 // }
     338        FunctionDecl * create_resume_handler( CatchList &handlers ) {
    435339                CompoundStmt * body = new CompoundStmt( noLabels );
    436340
     
    465369        }
    466370
    467         CompoundStmt * ExceptionMutatorCore::create_resume_wrapper(
     371        CompoundStmt * create_resume_wrapper(
     372                        StructDecl * node_decl,
    468373                        Statement * wraps,
    469374                        FunctionDecl * resume_handler ) {
     
    509414        }
    510415
    511         FunctionDecl * ExceptionMutatorCore::create_finally_wrapper(
    512                         TryStmt * tryStmt ) {
    513                 // void finally() { <finally code> }
     416        FunctionDecl * create_finally_wrapper( TryStmt * tryStmt ) {
    514417                FinallyStmt * finally = tryStmt->get_finally();
    515418                CompoundStmt * body = finally->get_block();
     
    522425        }
    523426
    524         ObjectDecl * ExceptionMutatorCore::create_finally_hook(
    525                         FunctionDecl * finally_wrapper ) {
     427        ObjectDecl * create_finally_hook(
     428                        StructDecl * hook_decl, FunctionDecl * finally_wrapper ) {
    526429                // struct __cfaehm__cleanup_hook __finally_hook
    527430                //      __attribute__((cleanup( finally_wrapper )));
     
    549452        }
    550453
    551         // Visiting/Mutating Functions
    552         void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) {
    553                 // Validate the Statement's form.
    554                 ObjectDecl * decl =
    555                         dynamic_cast<ObjectDecl *>( catchStmt->get_decl() );
    556                 if ( decl && true /* check decl->get_type() */ ) {
    557                         // Pass.
    558                 } else if ( CatchStmt::Terminate == catchStmt->get_kind() ) {
    559                         throw SemanticError("catch must have exception type");
    560                 } else {
    561                         throw SemanticError("catchResume must have exception type");
    562                 }
    563 
    564                 // Track the handler context.
    565                 GuardValue( cur_context );
    566                 if ( CatchStmt::Terminate == catchStmt->get_kind() ) {
    567                         cur_context = TerHandler;
    568 
    569                         GuardValue( handler_except_decl );
    570                         handler_except_decl = decl;
    571                 } else {
    572                         cur_context = ResHandler;
    573                 }
    574         }
    575 
    576         void ExceptionMutatorCore::premutate( StructDecl *structDecl ) {
    577                 if ( !structDecl->has_body() ) {
    578                         // Skip children?
    579                         return;
    580                 } else if ( structDecl->get_name() == "__cfaehm__base_exception_t" ) {
    581                         assert( nullptr == except_decl );
    582                         except_decl = structDecl;
    583                         init_func_types();
    584                 } else if ( structDecl->get_name() == "__cfaehm__try_resume_node" ) {
    585                         assert( nullptr == node_decl );
    586                         node_decl = structDecl;
    587                 } else if ( structDecl->get_name() == "__cfaehm__cleanup_hook" ) {
    588                         assert( nullptr == hook_decl );
    589                         hook_decl = structDecl;
    590                 }
    591                 // Later we might get the exception type as well.
    592         }
     454
     455        class ExceptionMutatorCore : public WithGuards {
     456                enum Context { NoHandler, TerHandler, ResHandler };
     457
     458                // Also need to handle goto, break & continue.
     459                // They need to be cut off in a ResHandler, until we enter another
     460                // loop, switch or the goto stays within the function.
     461
     462                Context cur_context;
     463
     464                // We might not need this, but a unique base for each try block's
     465                // generated functions might be nice.
     466                //std::string curFunctionName;
     467                //unsigned int try_count = 0;
     468
     469                StructDecl *node_decl;
     470                StructDecl *hook_decl;
     471
     472        public:
     473                ExceptionMutatorCore() :
     474                        cur_context(NoHandler),
     475                        node_decl(nullptr), hook_decl(nullptr)
     476                {}
     477
     478                void premutate( CatchStmt *catchStmt );
     479                void premutate( StructDecl *structDecl );
     480                Statement * postmutate( ThrowStmt *throwStmt );
     481                Statement * postmutate( TryStmt *tryStmt );
     482        };
    593483
    594484        Statement * ExceptionMutatorCore::postmutate( ThrowStmt *throwStmt ) {
    595                 assert( except_decl );
    596 
    597485                // Ignoring throwStmt->get_target() for now.
    598486                if ( ThrowStmt::Terminate == throwStmt->get_kind() ) {
     
    622510
    623511        Statement * ExceptionMutatorCore::postmutate( TryStmt *tryStmt ) {
    624                 assert( except_decl );
    625512                assert( node_decl );
    626513                assert( hook_decl );
     
    637524                        appendDeclStmt( block, finally_block );
    638525                        // Create and add the finally cleanup hook.
    639                         appendDeclStmt( block, create_finally_hook( finally_block ) );
     526                        appendDeclStmt( block,
     527                                create_finally_hook( hook_decl, finally_block ) );
    640528                }
    641529
     
    651539                        appendDeclStmt( block, resume_handler );
    652540                        // Prepare hooks
    653                         inner = create_resume_wrapper( inner, resume_handler );
     541                        inner = create_resume_wrapper( node_decl, inner, resume_handler );
    654542                }
    655543
     
    672560                block->push_back( inner );
    673561
     562                //free_all( termination_handlers );
     563                //free_all( resumption_handlers );
     564
    674565                return block;
    675566        }
    676567
     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.
     589        }
     590
    677591        void translateEHM( std::list< Declaration *> & translationUnit ) {
     592                init_func_types();
     593
    678594                PassVisitor<ExceptionMutatorCore> translator;
    679595                mutateAll( translationUnit, translator );
Note: See TracChangeset for help on using the changeset viewer.