- File:
-
- 1 edited
-
src/ControlStruct/ExceptTranslate.cc (modified) (19 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/ExceptTranslate.cc
r948b0c8 r03eedd5 10 10 // Created On : Wed Jun 14 16:49:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Wed Aug 02 12:09:00 201713 // Update Count : 712 // Last Modified On : Fri Jul 28 15:34:00 2017 13 // Update Count : 6 14 14 // 15 15 … … 24 24 25 25 namespace 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 } 26 95 27 96 // Buricratic Helpers (Not having to do with the paritular operation.) … … 50 119 } 51 120 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 another57 // 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*/ NULL136 );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*/ NULL148 );149 ObjectDecl bool_obj(150 "__ret_bool",151 Type::StorageClasses(),152 LinkageSpec::Cforall,153 /*bitfieldWidth*/ NULL,154 new BasicType( noQualifiers, BasicType::Bool ),155 /*init*/ NULL156 );157 ObjectDecl voidptr_obj(158 "__hook",159 Type::StorageClasses(),160 LinkageSpec::Cforall,161 NULL,162 new PointerType(163 noQualifiers,164 new VoidType(165 noQualifiers166 ),167 std::list<Attribute *>{ new Attribute( "unused" ) }168 ),169 NULL170 );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 181 121 // ThrowStmt Mutation Helpers 182 122 183 Statement * ExceptionMutatorCore::create_given_throw(123 Statement * create_given_throw( 184 124 const char * throwFunc, ThrowStmt * throwStmt ) { 185 125 // There is an extra copy here we might be able to remove with … … 204 144 } 205 145 206 Statement * ExceptionMutatorCore::create_terminate_throw( 207 ThrowStmt *throwStmt ) { 146 Statement * create_terminate_throw( ThrowStmt *throwStmt ) { 208 147 // { int NAME = EXPR; __throw_terminate( &NAME ); } 209 148 return create_given_throw( "__cfaehm__throw_terminate", throwStmt ); 210 149 } 211 150 212 Statement * ExceptionMutatorCore::create_terminate_rethrow(213 ThrowStmt *throwStmt) {151 Statement * create_terminate_rethrow( ThrowStmt *throwStmt, 152 ObjectDecl *handler_except_decl ) { 214 153 // { `handler_except_decl` = NULL; __rethrow_terminate(); } 215 154 assert( nullptr == throwStmt->get_expr() ); … … 234 173 } 235 174 236 Statement * ExceptionMutatorCore::create_resume_throw( 237 ThrowStmt *throwStmt ) { 175 Statement * create_resume_throw( ThrowStmt *throwStmt ) { 238 176 // __throw_resume( EXPR ); 239 177 return create_given_throw( "__cfaehm__throw_resume", throwStmt ); 240 178 } 241 179 242 Statement * ExceptionMutatorCore::create_resume_rethrow( 243 ThrowStmt *throwStmt ) { 180 Statement * create_resume_rethrow( ThrowStmt *throwStmt ) { 244 181 // return false; 245 182 Statement * result = new ReturnStmt( … … 253 190 // TryStmt Mutation Helpers 254 191 255 // XXX: Leave out? 256 CompoundStmt * ExceptionMutatorCore::take_try_block( TryStmt *tryStmt ) { 192 CompoundStmt * take_try_block( TryStmt *tryStmt ) { 257 193 CompoundStmt * block = tryStmt->get_block(); 258 194 tryStmt->set_block( nullptr ); 259 195 return block; 260 196 } 261 262 FunctionDecl * ExceptionMutatorCore::create_try_wrapper( 263 CompoundStmt *body ) { 197 FunctionDecl * create_try_wrapper( CompoundStmt *body ) { 264 198 265 199 return new FunctionDecl( "try", Type::StorageClasses(), … … 267 201 } 268 202 269 FunctionDecl * ExceptionMutatorCore::create_terminate_catch( 270 CatchList &handlers ) { 203 FunctionDecl * create_terminate_catch( CatchList &handlers ) { 271 204 std::list<CaseStmt *> handler_wrappers; 272 205 … … 364 297 // Create a single check from a moddified handler. 365 298 // except_obj is referenced, modded_handler will be freed. 366 CompoundStmt * ExceptionMutatorCore::create_single_matcher(299 CompoundStmt *create_single_matcher( 367 300 DeclarationWithType * except_obj, CatchStmt * modded_handler ) { 368 301 CompoundStmt * block = new CompoundStmt( noLabels ); … … 429 362 } 430 363 431 FunctionDecl * ExceptionMutatorCore::create_terminate_match( 432 CatchList &handlers ) { 364 FunctionDecl * create_terminate_match( CatchList &handlers ) { 433 365 // int match(exception * except) { 434 366 // HANDLER WRAPPERS { return `index`; } … … 466 398 } 467 399 468 CompoundStmt * ExceptionMutatorCore::create_terminate_caller(400 CompoundStmt * create_terminate_caller( 469 401 FunctionDecl * try_wrapper, 470 402 FunctionDecl * terminate_catch, 471 FunctionDecl * terminate_match ) {403 FunctionDecl * terminate_match) { 472 404 // { __cfaehm__try_terminate(`try`, `catch`, `match`); } 473 405 … … 484 416 } 485 417 486 FunctionDecl * ExceptionMutatorCore::create_resume_handler( 487 CatchList &handlers ) { 418 FunctionDecl * create_resume_handler( CatchList &handlers ) { 488 419 // bool handle(exception * except) { 489 420 // HANDLER WRAPPERS { `hander->body`; return true; } … … 521 452 } 522 453 523 CompoundStmt * ExceptionMutatorCore::create_resume_wrapper( 454 CompoundStmt * create_resume_wrapper( 455 StructDecl * node_decl, 524 456 Statement * wraps, 525 457 FunctionDecl * resume_handler ) { … … 565 497 } 566 498 567 FunctionDecl * ExceptionMutatorCore::create_finally_wrapper( 568 TryStmt * tryStmt ) { 499 FunctionDecl * create_finally_wrapper( TryStmt * tryStmt ) { 569 500 // void finally() { <finally code> } 570 501 FinallyStmt * finally = tryStmt->get_finally(); … … 578 509 } 579 510 580 ObjectDecl * ExceptionMutatorCore::create_finally_hook(581 FunctionDecl * finally_wrapper ) {511 ObjectDecl * create_finally_hook( 512 StructDecl * hook_decl, FunctionDecl * finally_wrapper ) { 582 513 // struct __cfaehm__cleanup_hook __finally_hook 583 514 // __attribute__((cleanup( finally_wrapper ))); … … 605 536 } 606 537 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 608 572 void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) { 609 573 // Currently, we make up the declaration, as there isn't one for 610 574 // integers. 611 assert( ! catchStmt->get_decl() );612 575 ObjectDecl * tmp = new ObjectDecl( 613 576 "_hidden_local", … … 666 629 return create_terminate_throw( throwStmt ); 667 630 } else if ( TerHandler == cur_context ) { 668 return create_terminate_rethrow( throwStmt ); 631 return create_terminate_rethrow( 632 throwStmt, handler_except_decl ); 669 633 } else { 670 634 assertf(false, "Invalid throw in %s at %i\n", … … 702 666 appendDeclStmt( block, finally_block ); 703 667 // 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 ) ); 705 670 } 706 671 … … 716 681 appendDeclStmt( block, resume_handler ); 717 682 // Prepare hooks 718 inner = create_resume_wrapper( inner, resume_handler );683 inner = create_resume_wrapper( node_decl, inner, resume_handler ); 719 684 } 720 685 … … 741 706 742 707 void translateEHM( std::list< Declaration *> & translationUnit ) { 708 init_func_types(); 709 743 710 PassVisitor<ExceptionMutatorCore> translator; 744 711 mutateAll( translationUnit, translator );
Note:
See TracChangeset
for help on using the changeset viewer.