Changeset 948b0c8
- Timestamp:
- Aug 2, 2017, 12:11:57 PM (6 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- f1a4ccb
- Parents:
- ff56efdf
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/ExceptTranslate.cc
rff56efdf r948b0c8 10 10 // Created On : Wed Jun 14 16:49:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Jul 28 15:34:00 201713 // Update Count : 612 // Last Modified On : Wed Aug 02 12:09:00 2017 13 // Update Count : 7 14 14 // 15 15 … … 25 25 namespace ControlStruct { 26 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 } 27 // Buricratic Helpers (Not having to do with the paritular operation.) 28 29 typedef std::list<CatchStmt*> CatchList; 30 31 void split( CatchList& allHandlers, CatchList& terHandlers, 32 CatchList& resHandlers ) { 33 while ( !allHandlers.empty() ) { 34 CatchStmt * stmt = allHandlers.front(); 35 allHandlers.pop_front(); 36 if (CatchStmt::Terminate == stmt->get_kind()) { 37 terHandlers.push_back(stmt); 38 } else { 39 resHandlers.push_back(stmt); 40 } 41 } 42 } 43 44 void appendDeclStmt( CompoundStmt * block, Declaration * item ) { 45 block->push_back(new DeclStmt(noLabels, item)); 46 } 47 48 Expression * nameOf( DeclarationWithType * decl ) { 49 return new VariableExpr( decl ); 50 } 51 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() { 43 129 ObjectDecl index_obj( 44 130 "__handler_index", … … 56 142 new PointerType( 57 143 noQualifiers, 144 //new StructInstType( noQualifiers, except_decl ) 58 145 new BasicType( noQualifiers, BasicType::SignedInt ) 59 146 ), … … 65 152 LinkageSpec::Cforall, 66 153 /*bitfieldWidth*/ NULL, 67 new BasicType( noQualifiers, BasicType::Bool),154 new BasicType( noQualifiers, BasicType::Bool ), 68 155 /*init*/ NULL 69 156 ); … … 78 165 noQualifiers 79 166 ), 80 std::list<Attribute *>{ new Attribute("unused")}167 std::list<Attribute *>{ new Attribute( "unused" ) } 81 168 ), 82 169 NULL … … 90 177 handle_func_t.get_parameters().push_back( exception_obj.clone() ); 91 178 finally_func_t.get_parameters().push_back( voidptr_obj.clone() ); 92 93 init_complete = true;94 }95 96 // Buricratic Helpers (Not having to do with the paritular operation.)97 98 typedef std::list<CatchStmt*> CatchList;99 100 void split( CatchList& allHandlers, CatchList& terHandlers,101 CatchList& resHandlers ) {102 while ( !allHandlers.empty() ) {103 CatchStmt * stmt = allHandlers.front();104 allHandlers.pop_front();105 if (CatchStmt::Terminate == stmt->get_kind()) {106 terHandlers.push_back(stmt);107 } else {108 resHandlers.push_back(stmt);109 }110 }111 }112 113 void appendDeclStmt( CompoundStmt * block, Declaration * item ) {114 block->push_back(new DeclStmt(noLabels, item));115 }116 117 Expression * nameOf( DeclarationWithType * decl ) {118 return new VariableExpr( decl );119 179 } 120 180 121 181 // ThrowStmt Mutation Helpers 122 182 123 Statement * create_given_throw(183 Statement * ExceptionMutatorCore::create_given_throw( 124 184 const char * throwFunc, ThrowStmt * throwStmt ) { 125 185 // There is an extra copy here we might be able to remove with … … 144 204 } 145 205 146 Statement * create_terminate_throw( ThrowStmt *throwStmt ) { 206 Statement * ExceptionMutatorCore::create_terminate_throw( 207 ThrowStmt *throwStmt ) { 147 208 // { int NAME = EXPR; __throw_terminate( &NAME ); } 148 209 return create_given_throw( "__cfaehm__throw_terminate", throwStmt ); 149 210 } 150 211 151 Statement * create_terminate_rethrow( ThrowStmt *throwStmt,152 ObjectDecl *handler_except_decl) {212 Statement * ExceptionMutatorCore::create_terminate_rethrow( 213 ThrowStmt *throwStmt ) { 153 214 // { `handler_except_decl` = NULL; __rethrow_terminate(); } 154 215 assert( nullptr == throwStmt->get_expr() ); … … 173 234 } 174 235 175 Statement * create_resume_throw( ThrowStmt *throwStmt ) { 236 Statement * ExceptionMutatorCore::create_resume_throw( 237 ThrowStmt *throwStmt ) { 176 238 // __throw_resume( EXPR ); 177 239 return create_given_throw( "__cfaehm__throw_resume", throwStmt ); 178 240 } 179 241 180 Statement * create_resume_rethrow( ThrowStmt *throwStmt ) { 242 Statement * ExceptionMutatorCore::create_resume_rethrow( 243 ThrowStmt *throwStmt ) { 181 244 // return false; 182 245 Statement * result = new ReturnStmt( … … 190 253 // TryStmt Mutation Helpers 191 254 192 CompoundStmt * take_try_block( TryStmt *tryStmt ) { 255 // XXX: Leave out? 256 CompoundStmt * ExceptionMutatorCore::take_try_block( TryStmt *tryStmt ) { 193 257 CompoundStmt * block = tryStmt->get_block(); 194 258 tryStmt->set_block( nullptr ); 195 259 return block; 196 260 } 197 FunctionDecl * create_try_wrapper( CompoundStmt *body ) { 261 262 FunctionDecl * ExceptionMutatorCore::create_try_wrapper( 263 CompoundStmt *body ) { 198 264 199 265 return new FunctionDecl( "try", Type::StorageClasses(), … … 201 267 } 202 268 203 FunctionDecl * create_terminate_catch( CatchList &handlers ) { 269 FunctionDecl * ExceptionMutatorCore::create_terminate_catch( 270 CatchList &handlers ) { 204 271 std::list<CaseStmt *> handler_wrappers; 205 272 … … 297 364 // Create a single check from a moddified handler. 298 365 // except_obj is referenced, modded_handler will be freed. 299 CompoundStmt * create_single_matcher(366 CompoundStmt * ExceptionMutatorCore::create_single_matcher( 300 367 DeclarationWithType * except_obj, CatchStmt * modded_handler ) { 301 368 CompoundStmt * block = new CompoundStmt( noLabels ); … … 362 429 } 363 430 364 FunctionDecl * create_terminate_match( CatchList &handlers ) { 431 FunctionDecl * ExceptionMutatorCore::create_terminate_match( 432 CatchList &handlers ) { 365 433 // int match(exception * except) { 366 434 // HANDLER WRAPPERS { return `index`; } … … 398 466 } 399 467 400 CompoundStmt * create_terminate_caller(468 CompoundStmt * ExceptionMutatorCore::create_terminate_caller( 401 469 FunctionDecl * try_wrapper, 402 470 FunctionDecl * terminate_catch, 403 FunctionDecl * terminate_match ) {471 FunctionDecl * terminate_match ) { 404 472 // { __cfaehm__try_terminate(`try`, `catch`, `match`); } 405 473 … … 416 484 } 417 485 418 FunctionDecl * create_resume_handler( CatchList &handlers ) { 486 FunctionDecl * ExceptionMutatorCore::create_resume_handler( 487 CatchList &handlers ) { 419 488 // bool handle(exception * except) { 420 489 // HANDLER WRAPPERS { `hander->body`; return true; } … … 452 521 } 453 522 454 CompoundStmt * create_resume_wrapper( 455 StructDecl * node_decl, 523 CompoundStmt * ExceptionMutatorCore::create_resume_wrapper( 456 524 Statement * wraps, 457 525 FunctionDecl * resume_handler ) { … … 497 565 } 498 566 499 FunctionDecl * create_finally_wrapper( TryStmt * tryStmt ) { 567 FunctionDecl * ExceptionMutatorCore::create_finally_wrapper( 568 TryStmt * tryStmt ) { 500 569 // void finally() { <finally code> } 501 570 FinallyStmt * finally = tryStmt->get_finally(); … … 509 578 } 510 579 511 ObjectDecl * create_finally_hook(512 StructDecl * hook_decl,FunctionDecl * finally_wrapper ) {580 ObjectDecl * ExceptionMutatorCore::create_finally_hook( 581 FunctionDecl * finally_wrapper ) { 513 582 // struct __cfaehm__cleanup_hook __finally_hook 514 583 // __attribute__((cleanup( finally_wrapper ))); … … 536 605 } 537 606 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 607 // Visiting/Mutating Functions 572 608 void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) { 573 609 // Currently, we make up the declaration, as there isn't one for 574 610 // integers. 611 assert( ! catchStmt->get_decl() ); 575 612 ObjectDecl * tmp = new ObjectDecl( 576 613 "_hidden_local", … … 629 666 return create_terminate_throw( throwStmt ); 630 667 } else if ( TerHandler == cur_context ) { 631 return create_terminate_rethrow( 632 throwStmt, handler_except_decl ); 668 return create_terminate_rethrow( throwStmt ); 633 669 } else { 634 670 assertf(false, "Invalid throw in %s at %i\n", … … 666 702 appendDeclStmt( block, finally_block ); 667 703 // Create and add the finally cleanup hook. 668 appendDeclStmt( block, 669 create_finally_hook( hook_decl, finally_block ) ); 704 appendDeclStmt( block, create_finally_hook( finally_block ) ); 670 705 } 671 706 … … 681 716 appendDeclStmt( block, resume_handler ); 682 717 // Prepare hooks 683 inner = create_resume_wrapper( node_decl,inner, resume_handler );718 inner = create_resume_wrapper( inner, resume_handler ); 684 719 } 685 720 … … 706 741 707 742 void translateEHM( std::list< Declaration *> & translationUnit ) { 708 init_func_types();709 710 743 PassVisitor<ExceptionMutatorCore> translator; 711 744 mutateAll( translationUnit, translator );
Note: See TracChangeset
for help on using the changeset viewer.