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