Changeset 86d5ba7c for src/ControlStruct/ExceptTranslate.cc
- Timestamp:
- Jul 28, 2017, 2:06:10 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:
- 03eedd5, 79dbb79
- Parents:
- a2e0687
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/ExceptTranslate.cc
ra2e0687 r86d5ba7c 10 10 // Created On : Wed Jun 14 16:49:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tus Jul 18 10:09:00 201713 // Update Count : 412 // Last Modified On : Fri Jul 28 14:03:00 2017 13 // Update Count : 5 14 14 // 15 15 … … 21 21 #include "SynTree/Type.h" 22 22 #include "SynTree/Attribute.h" 23 #include "SynTree/VarExprReplacer.h" 23 24 24 25 namespace ControlStruct { 25 26 26 // This (large) section could probably be moved out of the class27 // and be static helpers instead.28 29 // Type(Qualifiers &, false, std::list<Attribute *> &)30 31 27 // void (*function)(); 32 static FunctionType try_func_t( Type::Qualifiers(), false);28 static FunctionType try_func_t(noQualifiers, false); 33 29 // void (*function)(int, exception); 34 static FunctionType catch_func_t( Type::Qualifiers(), false);30 static FunctionType catch_func_t(noQualifiers, false); 35 31 // int (*function)(exception); 36 static FunctionType match_func_t( Type::Qualifiers(), false);32 static FunctionType match_func_t(noQualifiers, false); 37 33 // bool (*function)(exception); 38 static FunctionType handle_func_t( Type::Qualifiers(), false);34 static FunctionType handle_func_t(noQualifiers, false); 39 35 // void (*function)(__attribute__((unused)) void *); 40 static FunctionType finally_func_t( Type::Qualifiers(), false);36 static FunctionType finally_func_t(noQualifiers, false); 41 37 42 38 static void init_func_types() { … … 115 111 } 116 112 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 126 113 void appendDeclStmt( CompoundStmt * block, Declaration * item ) { 127 114 block->push_back(new DeclStmt(noLabels, item)); … … 136 123 Statement * create_given_throw( 137 124 const char * throwFunc, ThrowStmt * throwStmt ) { 125 // There is an extra copy here we might be able to remove with 126 // references. 138 127 // { int NAME = EXPR; throwFunc( &NAME ); } 139 128 CompoundStmt * result = new CompoundStmt( noLabels ); … … 159 148 return create_given_throw( "__cfaehm__throw_terminate", throwStmt ); 160 149 } 161 Statement * create_terminate_rethrow( ThrowStmt *throwStmt ) { 162 // __rethrow_terminate(); 150 151 Statement * create_terminate_rethrow( ThrowStmt *throwStmt, 152 ObjectDecl *handler_except_decl ) { 153 // { `handler_except_decl` = NULL; __rethrow_terminate(); } 163 154 assert( nullptr == throwStmt->get_expr() ); 164 Statement * result = new ExprStmt( 165 throwStmt->get_labels(), 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, 166 169 new UntypedExpr( new NameExpr( "__cfaehm__rethrow_terminate" ) ) 167 ) ;170 ) ); 168 171 delete throwStmt; 169 172 return result; 170 173 } 174 171 175 Statement * create_resume_throw( ThrowStmt *throwStmt ) { 172 176 // __throw_resume( EXPR ); 173 177 return create_given_throw( "__cfaehm__throw_resume", throwStmt ); 174 178 } 179 175 180 Statement * create_resume_rethrow( ThrowStmt *throwStmt ) { 176 181 // return false; … … 201 206 FunctionType *func_type = catch_func_t.clone(); 202 207 DeclarationWithType * index_obj = func_type->get_parameters().front(); 203 //DeclarationWithType * except_obj = func_type->get_parameters().back();208 DeclarationWithType * except_obj = func_type->get_parameters().back(); 204 209 205 210 // Index 1..{number of handlers} … … 213 218 // case `index`: 214 219 // { 220 // `handler.decl` {inserted} = { except_obj }; 215 221 // `handler.body` 216 222 // } 217 223 // return; 218 std::list<Statement *> caseBody; 219 caseBody.push_back( handler->get_body() ); 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() ); 220 269 handler->set_body( nullptr ); 221 caseBody.push_back( new ReturnStmt( noLabels, nullptr ) ); 222 270 271 std::list<Statement *> caseBody 272 { block, new ReturnStmt( noLabels, nullptr ) }; 223 273 handler_wrappers.push_back( new CaseStmt( 224 274 noLabels, … … 253 303 CompoundStmt * block = new CompoundStmt( noLabels ); 254 304 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 255 325 // INTEGERconstant Version 256 assert( nullptr == modded_handler->get_decl() ); 326 // { 327 // `modded_handler.decl` = *`except` 328 // if ( `decl.name` == `modded_handler.cond` ) { 329 // `modded_handler.body` 330 // } 331 // } 257 332 ConstantExpr * number = 258 333 dynamic_cast<ConstantExpr*>( modded_handler->get_cond() ); … … 274 349 } 275 350 351 // Add the check on the conditional if it is provided. 276 352 if ( modded_handler->get_cond() ) { 277 353 cond = new LogicalExpr( cond, modded_handler->get_cond() ); 278 354 } 355 // Construct the match condition. 279 356 block->push_back( new IfStmt( noLabels, 280 357 cond, modded_handler->get_body(), nullptr ) ); … … 288 365 289 366 FunctionDecl * create_terminate_match( CatchList &handlers ) { 367 // int match(exception * except) { 368 // HANDLER WRAPPERS { return `index`; } 369 // } 370 290 371 CompoundStmt * body = new CompoundStmt( noLabels ); 291 372 … … 323 404 FunctionDecl * terminate_catch, 324 405 FunctionDecl * terminate_match) { 406 // { __cfaehm__try_terminate(`try`, `catch`, `match`); } 325 407 326 408 UntypedExpr * caller = new UntypedExpr( new NameExpr( … … 337 419 338 420 FunctionDecl * create_resume_handler( CatchList &handlers ) { 421 // bool handle(exception * except) { 422 // HANDLER WRAPPERS { `hander->body`; return true; } 423 // } 339 424 CompoundStmt * body = new CompoundStmt( noLabels ); 340 425 … … 415 500 416 501 FunctionDecl * create_finally_wrapper( TryStmt * tryStmt ) { 502 // void finally() { <finally code> } 417 503 FinallyStmt * finally = tryStmt->get_finally(); 418 504 CompoundStmt * body = finally->get_block(); … … 462 548 Context cur_context; 463 549 550 // The current (innermost) termination handler exception declaration. 551 ObjectDecl * handler_except_decl; 552 464 553 // We might not need this, but a unique base for each try block's 465 554 // generated functions might be nice. … … 473 562 ExceptionMutatorCore() : 474 563 cur_context(NoHandler), 475 node_decl(nullptr), hook_decl(nullptr) 564 handler_except_decl( nullptr ), 565 node_decl( nullptr ), hook_decl( nullptr ) 476 566 {} 477 567 … … 481 571 Statement * postmutate( TryStmt *tryStmt ); 482 572 }; 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 } 483 615 484 616 Statement * ExceptionMutatorCore::postmutate( ThrowStmt *throwStmt ) { … … 488 620 return create_terminate_throw( throwStmt ); 489 621 } else if ( TerHandler == cur_context ) { 490 return create_terminate_rethrow( throwStmt ); 622 return create_terminate_rethrow( 623 throwStmt, handler_except_decl ); 491 624 } else { 492 625 assertf(false, "Invalid throw in %s at %i\n", … … 560 693 block->push_back( inner ); 561 694 562 //free_all( termination_handlers );563 //free_all( resumption_handlers );564 565 695 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.589 696 } 590 697
Note: See TracChangeset
for help on using the changeset viewer.