Changeset 288eede for src/ControlStruct
- Timestamp:
- Jun 29, 2017, 3:27:57 PM (7 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:
- a49a11b
- Parents:
- c9383ee
- Location:
- src/ControlStruct
- Files:
-
- 3 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/ExceptTranslate.cc
rc9383ee r288eede 10 10 // Created On : Wed Jun 14 16:49:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Jun 2 2 15:57:00 201713 // Update Count : 012 // Last Modified On : Thr Jun 29 15:18:00 2017 13 // Update Count : 1 14 14 // 15 15 16 16 #include "ExceptTranslate.h" 17 17 #include "Common/PassVisitor.h" 18 #include "SynTree/Statement.h" 19 #include "SynTree/Declaration.h" 20 #include "SynTree/Expression.h" 21 #include "SynTree/Type.h" 22 #include "SynTree/Attribute.h" 18 23 19 24 namespace ControlFlow { … … 34 39 35 40 static void init_func_types() { 36 static init_complete = false;41 static bool init_complete = false; 37 42 if (init_complete) { 38 43 return; 39 44 } 40 45 ObjectDecl index_obj( 41 " index_t",46 "__handler_index", 42 47 Type::StorageClasses(), 43 48 LinkageSpec::Cforall, … … 47 52 ); 48 53 ObjectDecl exception_obj( 49 " exception_t",54 "__exception_inst", 50 55 Type::StorageClasses(), 51 56 LinkageSpec::Cforall, … … 55 60 ); 56 61 ObjectDecl bool_obj( 57 " bool_t",62 "__ret_bool", 58 63 Type::StorageClasses(), 59 64 LinkageSpec::Cforall, … … 80 85 CatchList& resHandlers ) { 81 86 while ( !allHandlers.empty() ) { 82 Statement * stmt = allHandlers.front();87 CatchStmt * stmt = allHandlers.front(); 83 88 allHandlers.pop_front(); 84 if (Ca seStmt::Terminate == stmt->get_kind()) {89 if (CatchStmt::Terminate == stmt->get_kind()) { 85 90 terHandlers.push_back(stmt); 86 91 } else { … … 92 97 template<typename T> 93 98 void free_all( std::list<T *> &list ) { 94 std::list<T *>::iterator it;99 typename std::list<T *>::iterator it; 95 100 for ( it = list.begin() ; it != list.end() ; ++it ) { 96 101 delete *it; … … 100 105 101 106 void appendDeclStmt( CompoundStmt * block, Declaration * item ) { 102 block->push_back(new DeclStmt(no _labels, item));103 } 104 105 Expression * nameOf( FunctionDecl * function) {106 return new VariableExpr( function);107 block->push_back(new DeclStmt(noLabels, item)); 108 } 109 110 Expression * nameOf( DeclarationWithType * decl ) { 111 return new VariableExpr( decl ); 107 112 } 108 113 … … 111 116 Statement * create_terminate_throw( ThrowStmt *throwStmt ) { 112 117 // __throw_terminate( EXPR ); 113 ApplicationExpr * call = new ApplicationExpr( /* ... */ ); 114 call->get_args.push_back( throwStmt->get_expr() ); 118 UntypedExpr * call = new UntypedExpr( new NameExpr( 119 "__cfaehm__throw_termination" ) ); 120 call->get_args().push_back( throwStmt->get_expr() ); 115 121 Statement * result = new ExprStmt( throwStmt->get_labels(), call ); 116 122 throwStmt->set_expr( nullptr ); … … 120 126 Statement * create_terminate_rethrow( ThrowStmt *throwStmt ) { 121 127 // __rethrow_terminate(); 128 assert( nullptr == throwStmt->get_expr() ); 122 129 Statement * result = new ExprStmt( 123 130 throwStmt->get_labels(), 124 new ApplicationExpr( /* ... */ );131 new UntypedExpr( new NameExpr( "__cfaehm__rethrow_termination" ) ) 125 132 ); 126 133 delete throwStmt; … … 129 136 Statement * create_resume_throw( ThrowStmt *throwStmt ) { 130 137 // __throw_resume( EXPR ); 131 ApplicationExpr * call = new ApplicationExpr( /* ... */ ); 132 call->get_args.push_back( throwStmt->get_expr() ); 138 UntypedExpr * call = new UntypedExpr( new NameExpr( 139 "__cfaehm__throw_resumption" ) ); 140 call->get_args().push_back( throwStmt->get_expr() ); 133 141 Statement * result = new ExprStmt( throwStmt->get_labels(), call ); 134 142 throwStmt->set_expr( nullptr ); … … 140 148 Statement * result = new ReturnStmt( 141 149 throwStmt->get_labels(), 142 new ConstantExpr( 143 Constant( 144 new BasicType( 145 Type::Qualifiers(), 146 BasicType::Bool 147 ), 148 "0") 149 ) 150 new ConstantExpr( Constant::from_bool( false ) ) 150 151 ); 151 152 delete throwStmt; … … 160 161 return block; 161 162 } 162 FunctionDecl * create_try_wrapper( TryStmt *tryStmt ) { 163 CompoundStmt * body = base_try->get_block(); 164 base_try->set_block(nullptr); 165 166 return new FunctionDecl("try", Type::StorageClasses(), 167 LinkageSpec::Cforall, void_func_t, body); 163 FunctionDecl * create_try_wrapper( CompoundStmt *body ) { 164 165 return new FunctionDecl( "try", Type::StorageClasses(), 166 LinkageSpec::Cforall, void_func_t.clone(), body ); 168 167 } 169 168 170 169 FunctionDecl * create_terminate_catch( CatchList &handlers ) { 171 170 std::list<CaseStmt *> handler_wrappers; 171 172 FunctionType *func_type = catch_func_t.clone(); 173 DeclarationWithType * index_obj = func_type->get_parameters().front(); 174 // DeclarationWithType * except_obj = func_type->get_parameters().back(); 172 175 173 176 // Index 1..{number of handlers} … … 178 181 CatchStmt * handler = *it; 179 182 180 std::list<Statement *> core; 181 if ( /*the exception is named*/ ) { 182 ObjectDecl * local_except = /* Dynamic case, same */; 183 core->push_back( new DeclStmt( noLabel, local_except ) ); 184 } 185 // Append the provided statement to the handler. 186 core->push_back( cur_handler->get_body() ); 187 // Append return onto the inner block? case stmt list? 188 CaseStmt * wrapper = new CaseStmt( 183 // INTEGERconstant Version 184 // case `index`: 185 // { 186 // `handler.body` 187 // } 188 // return; 189 std::list<Statement *> caseBody; 190 caseBody.push_back( handler->get_body() ); 191 handler->set_body( nullptr ); 192 caseBody.push_back( new ReturnStmt( noLabels, nullptr ) ); 193 194 handler_wrappers.push_back( new CaseStmt( 189 195 noLabels, 190 196 new ConstantExpr( Constant::from_int( index ) ), 191 core 192 ); 193 handler_wrappers.push_back(wrapper); 197 caseBody 198 ) ); 194 199 } 195 200 // TODO: Some sort of meaningful error on default perhaps? 201 202 std::list<Statement*> stmt_handlers; 203 while ( !handler_wrappers.empty() ) { 204 stmt_handlers.push_back( handler_wrappers.front() ); 205 handler_wrappers.pop_front(); 206 } 196 207 197 208 SwitchStmt * handler_lookup = new SwitchStmt( 198 209 noLabels, 199 /*parameter 0: index*/, 200 handler_wrappers, 201 false 210 nameOf( index_obj ), 211 stmt_handlers 202 212 ); 203 213 CompoundStmt * body = new CompoundStmt( noLabels ); … … 205 215 206 216 return new FunctionDecl("catch", Type::StorageClasses(), 207 LinkageSpec::Cforall, catch_func_t, body);217 LinkageSpec::Cforall, func_type, body); 208 218 } 209 219 210 220 // Create a single check from a moddified handler. 211 CompoundStmt *create_single_matcher( CatchStmt * modded_handler ) { 212 CompoundStmt * block = new CompoundStmt( noLables ); 213 214 appendDeclStmt( block, modded_handler->get_decl() ); 215 216 // TODO: This is not the actual check. 217 LogicalExpr * cond = new ConstantExpr( Constant::from_bool( false ) ); 221 // except_obj is referenced, modded_handler will be freed. 222 CompoundStmt *create_single_matcher( 223 DeclarationWithType * except_obj, CatchStmt * modded_handler ) { 224 CompoundStmt * block = new CompoundStmt( noLabels ); 225 226 // INTEGERconstant Version 227 assert( nullptr == modded_handler->get_decl() ); 228 ConstantExpr * number = 229 dynamic_cast<ConstantExpr*>( modded_handler->get_cond() ); 230 assert( number ); 231 modded_handler->set_cond( nullptr ); 232 233 Expression * cond; 234 { 235 std::list<Expression *> args; 236 args.push_back( number ); 237 args.push_back( nameOf( except_obj ) ); 238 cond = new UntypedExpr( new NameExpr( "?==?" /*???*/), args ); 239 } 218 240 219 241 if ( modded_handler->get_cond() ) { 220 cond = new LogicalExpr( cond, modded_handler->get_cond() ) q242 cond = new LogicalExpr( cond, modded_handler->get_cond() ); 221 243 } 222 244 block->push_back( new IfStmt( noLabels, 223 cond, modded_handler->get_body() );245 cond, modded_handler->get_body(), nullptr ) ); 224 246 225 247 modded_handler->set_decl( nullptr ); … … 232 254 FunctionDecl * create_terminate_match( CatchList &handlers ) { 233 255 CompoundStmt * body = new CompoundStmt( noLabels ); 256 257 FunctionType * func_type = match_func_t.clone(); 258 DeclarationWithType * except_obj = func_type->get_parameters().back(); 234 259 235 260 // Index 1..{number of handlers} … … 240 265 CatchStmt * handler = *it; 241 266 242 // body should have been taken by create_terminate_catch. 243 // assert( nullptr == handler->get_body() ); 267 // Body should have been taken by create_terminate_catch. 268 assert( nullptr == handler->get_body() ); 269 270 // Create new body. 244 271 handler->set_body( new ReturnStmt( noLabels, 245 272 new ConstantExpr( Constant::from_int( index ) ) ) ); 246 273 247 body->push_back( create_single_matcher( handler ) ); 274 // Create the handler. 275 body->push_back( create_single_matcher( except_obj, handler ) ); 276 *it = nullptr; 248 277 } 249 278 250 279 return new FunctionDecl("match", Type::StorageClasses(), 251 LinkageSpec::Cforall, match_func_t, body);252 } 253 254 Statement * create_terminate_caller(280 LinkageSpec::Cforall, func_type, body); 281 } 282 283 CompoundStmt * create_terminate_caller( 255 284 FunctionDecl * try_wrapper, 256 285 FunctionDecl * terminate_catch, 257 286 FunctionDecl * terminate_match) { 258 287 259 ApplicationExpr * caller = new ApplicationExpr( /* ... */ ); 260 std::list<Expression *>& args = caller.get_args(); 288 UntypedExpr * caller = new UntypedExpr( new NameExpr( 289 "__cfaehm__try_terminate" ) ); 290 std::list<Expression *>& args = caller->get_args(); 261 291 args.push_back( nameOf( try_wrapper ) ); 262 292 args.push_back( nameOf( terminate_catch ) ); 263 293 args.push_back( nameOf( terminate_match ) ); 264 294 265 return new ExprStmt( noLabels, caller ); 295 CompoundStmt * callStmt = new CompoundStmt( noLabels ); 296 callStmt->push_back( new ExprStmt( noLabels, caller ) ); 297 return callStmt; 266 298 } 267 299 268 300 FunctionDecl * create_resume_handler( CatchList &handlers ) { 269 CompoundStmt * body = new CompountStmt( noLabels ); 301 CompoundStmt * body = new CompoundStmt( noLabels ); 302 303 FunctionType * func_type = match_func_t.clone(); 304 DeclarationWithType * except_obj = func_type->get_parameters().back(); 270 305 271 306 CatchList::iterator it; … … 280 315 handling_code->push_back( handler->get_body() ); 281 316 } 282 handling_code->push_back( new ReturnStmt( noLabel ,317 handling_code->push_back( new ReturnStmt( noLabels, 283 318 new ConstantExpr( Constant::from_bool( false ) ) ) ); 284 319 handler->set_body( handling_code ); 285 320 286 321 // Create the handler. 287 body->push_back( create_single_matcher( handler ) ); 322 body->push_back( create_single_matcher( except_obj, handler ) ); 323 *it = nullptr; 288 324 } 289 325 290 326 return new FunctionDecl("handle", Type::StorageClasses(), 291 LinkageSpec::Cforall, handle_func_t, body); 292 } 293 294 Statement * create_resume_wrapper( 327 LinkageSpec::Cforall, func_type, body); 328 } 329 330 CompoundStmt * create_resume_wrapper( 331 StructDecl * node_decl, 295 332 Statement * wraps, 296 333 FunctionDecl * resume_handler ) { 297 334 CompoundStmt * body = new CompoundStmt( noLabels ); 298 335 299 // struct node = {current top resume handler, call to resume_handler}; 300 // __attribute__((cleanup( ... ))); 301 // set top resume handler to node. 302 // The wrapped statement. 303 304 ListInit * node_init; 305 { 306 std::list<Initializer*> field_inits; 307 field_inits.push_back( new SingleInit( /* ... */ ) ); 308 field_inits.push_back( new SingleInit( nameOf( resume_handler ) ) ); 309 node_init = new ListInit( field_inits ); 310 } 336 // struct __try_resume_node __resume_node 337 // __attribute__((cleanup( __cfaehm__try_resume_cleanup ))); 338 // ** unwinding of the stack here could cause problems ** 339 // ** however I don't think that can happen currently ** 340 // __cfaehm__try_resume_setup( &__resume_node, resume_handler ); 311 341 312 342 std::list< Attribute * > attributes; 313 343 { 314 344 std::list< Expression * > attr_params; 315 attr_params.push_back( n ameOf( /* ... deconstructor ... */ ) );316 attrributes.push_back( new Attribute( "cleanup", attr_params) );317 }318 319 appendDeclStmt( body, 320 /**/ObjectDecl(321 " resume_node",345 attr_params.push_back( new NameExpr( 346 "__cfaehm__try_resume_cleanup" ) ); 347 attributes.push_back( new Attribute( "cleanup", attr_params ) ); 348 } 349 350 ObjectDecl * obj = new ObjectDecl( 351 "__resume_node", 322 352 Type::StorageClasses(), 323 353 LinkageSpec::Cforall, 324 354 nullptr, 325 /* Type* = resume_node */, 326 node_init, 355 new StructInstType( 356 Type::Qualifiers(), 357 node_decl 358 ), 359 nullptr, 327 360 attributes 328 ) 329 ); 361 ); 362 appendDeclStmt( body, obj ); 363 364 UntypedExpr *setup = new UntypedExpr( new NameExpr( 365 "__cfaehm__try_resume_setup" ) ); 366 setup->get_args().push_back( nameOf( obj ) ); 367 setup->get_args().push_back( nameOf( resume_handler ) ); 368 369 body->push_back( new ExprStmt( noLabels, setup ) ); 370 330 371 body->push_back( wraps ); 331 372 return body; … … 333 374 334 375 FunctionDecl * create_finally_wrapper( TryStmt * tryStmt ) { 335 CompoundStmt * body = tryStmt->get_finally(); 376 FinallyStmt * finally = tryStmt->get_finally(); 377 CompoundStmt * body = finally->get_block(); 378 finally->set_block( nullptr ); 379 delete finally; 336 380 tryStmt->set_finally( nullptr ); 337 381 338 382 return new FunctionDecl("finally", Type::StorageClasses(), 339 LinkageSpec::Cforall, void_func_t, body); 340 } 341 342 ObjectDecl * create_finally_hook( FunctionDecl * finally_wrapper ) { 343 // struct _cleanup_hook NAME __attribute__((cleanup( ... ))); 383 LinkageSpec::Cforall, void_func_t.clone(), body); 384 } 385 386 ObjectDecl * create_finally_hook( 387 StructDecl * hook_decl, FunctionDecl * finally_wrapper ) { 388 // struct __cfaehm__cleanup_hook __finally_hook 389 // __attribute__((cleanup( finally_wrapper ))); 344 390 345 391 // Make Cleanup Attribute. … … 348 394 std::list< Expression * > attr_params; 349 395 attr_params.push_back( nameOf( finally_wrapper ) ); 350 attr ributes.push_back( new Attribute( "cleanup", attr_params ) );351 } 352 353 return ObjectDecl( /* ... */354 const std::string &name "finally_hook",396 attributes.push_back( new Attribute( "cleanup", attr_params ) ); 397 } 398 399 return new ObjectDecl( 400 "__finally_hook", 355 401 Type::StorageClasses(), 356 402 LinkageSpec::Cforall, 357 403 nullptr, 358 /* ... Type * ... */, 404 new StructInstType( 405 emptyQualifiers, 406 hook_decl 407 ), 359 408 nullptr, 360 409 attributes … … 363 412 364 413 365 class ExceptionMutatorCore : public WithScop ing{414 class ExceptionMutatorCore : public WithScopes { 366 415 enum Context { NoHandler, TerHandler, ResHandler }; 367 416 … … 370 419 // loop, switch or the goto stays within the function. 371 420 372 Context cur Context;421 Context cur_context; 373 422 374 423 // We might not need this, but a unique base for each try block's … … 377 426 //unsigned int try_count = 0; 378 427 428 StructDecl *node_decl; 429 StructDecl *hook_decl; 379 430 380 431 public: 381 432 ExceptionMutatorCore() : 382 curContext(NoHandler) 433 cur_context(NoHandler), 434 node_decl(nullptr), hook_decl(nullptr) 383 435 {} 384 436 385 void premutate( CatchStmt *tryStmt ); 437 void premutate( CatchStmt *catchStmt ); 438 void premutate( StructDecl *structDecl ); 386 439 Statement * postmutate( ThrowStmt *throwStmt ); 387 440 Statement * postmutate( TryStmt *tryStmt ); … … 393 446 if ( throwStmt->get_expr() ) { 394 447 return create_terminate_throw( throwStmt ); 395 } else if ( TerHandler == cur Context ) {448 } else if ( TerHandler == cur_context ) { 396 449 return create_terminate_rethrow( throwStmt ); 397 450 } else { 398 451 assertf(false, "Invalid throw in %s at %i\n", 399 throwStmt->location.filename ,452 throwStmt->location.filename.c_str(), 400 453 throwStmt->location.linenumber); 401 454 return nullptr; … … 404 457 if ( throwStmt->get_expr() ) { 405 458 return create_resume_throw( throwStmt ); 406 } else if ( ResHandler == cur Context ) {459 } else if ( ResHandler == cur_context ) { 407 460 return create_resume_rethrow( throwStmt ); 408 461 } else { 409 462 assertf(false, "Invalid throwResume in %s at %i\n", 410 throwStmt->location.filename ,463 throwStmt->location.filename.c_str(), 411 464 throwStmt->location.linenumber); 412 465 return nullptr; … … 416 469 417 470 Statement * ExceptionMutatorCore::postmutate( TryStmt *tryStmt ) { 471 assert( node_decl ); 472 assert( hook_decl ); 473 418 474 // Generate a prefix for the function names? 419 475 420 CompoundStmt * block = new CompoundStmt( );421 Statement * inner = take_try_block( tryStmt );476 CompoundStmt * block = new CompoundStmt( noLabels ); 477 CompoundStmt * inner = take_try_block( tryStmt ); 422 478 423 479 if ( tryStmt->get_finally() ) { … … 427 483 appendDeclStmt( block, finally_block ); 428 484 // Create and add the finally cleanup hook. 429 appendDeclStmt( block, create_finally_hook( finally_block ) ); 430 } 431 432 StatementList termination_handlers; 433 StatementList resumption_handlers; 434 split( tryStmt->get_handlers(), 485 appendDeclStmt( block, 486 create_finally_hook( hook_decl, finally_block ) ); 487 } 488 489 CatchList termination_handlers; 490 CatchList resumption_handlers; 491 split( tryStmt->get_catchers(), 435 492 termination_handlers, resumption_handlers ); 436 493 437 if ( resum eption_handlers.size() ) {494 if ( resumption_handlers.size() ) { 438 495 // Define the helper function. 439 496 FunctionDecl * resume_handler = … … 441 498 appendDeclStmt( block, resume_handler ); 442 499 // Prepare hooks 443 inner = create_resume_wrapper( inner, resume_handler );500 inner = create_resume_wrapper( node_decl, inner, resume_handler ); 444 501 } 445 502 … … 462 519 block->push_back( inner ); 463 520 464 free_all( termination_handlers );465 free_all( resumption_handlers );521 //free_all( termination_handlers ); 522 //free_all( resumption_handlers ); 466 523 467 524 return block; … … 469 526 470 527 void ExceptionMutatorCore::premutate( CatchStmt *catchStmt ) { 471 GuardValue( cur Context );472 if ( CatchStmt::Terminat ion== catchStmt->get_kind() ) {473 cur Context = TerHandler;528 GuardValue( cur_context ); 529 if ( CatchStmt::Terminate == catchStmt->get_kind() ) { 530 cur_context = TerHandler; 474 531 } else { 475 curContext = ResHandler; 476 } 532 cur_context = ResHandler; 533 } 534 } 535 536 void ExceptionMutatorCore::premutate( StructDecl *structDecl ) { 537 if ( !structDecl->has_body() ) { 538 // Skip children? 539 return; 540 } else if ( structDecl->get_name() == "__cfaehm__try_resume_node" ) { 541 assert( nullptr == node_decl ); 542 node_decl = structDecl; 543 } else if ( structDecl->get_name() == "__cfaehm__cleanup_hook" ) { 544 assert( nullptr == hook_decl ); 545 hook_decl = structDecl; 546 } 547 // Later we might get the exception type as well. 477 548 } 478 549 479 550 void translateEHM( std::list< Declaration *> & translationUnit ) { 551 init_func_types(); 552 480 553 PassVisitor<ExceptionMutatorCore> translator; 481 554 for ( Declaration * decl : translationUnit ) { 482 decl-> mutate( translator );555 decl->acceptMutator( translator ); 483 556 } 484 557 } -
src/ControlStruct/ExceptTranslate.h
rc9383ee r288eede 10 10 // Created On : Tus Jun 06 10:13:00 2017 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Jun 2 2 15:57:00 201713 // Update Count : 012 // Last Modified On : Thr Jun 29 15:18:00 2017 13 // Update Count : 1 14 14 // 15 15 16 16 #ifndef EXCEPT_TRANSLATE_H 17 17 #define EXCEPT_TRANSLATE_H 18 19 #include <list> 20 #include "SynTree/SynTree.h" 18 21 19 22 namespace ControlFlow { -
src/ControlStruct/module.mk
rc9383ee r288eede 10 10 ## Author : Richard C. Bilson 11 11 ## Created On : Mon Jun 1 17:49:17 2015 12 ## Last Modified By : Peter A. Buhr13 ## Last Modified On : Thu Aug 4 11:38:06 201614 ## Update Count : 312 ## Last Modified By : Andrew Beach 13 ## Last Modified On : Wed Jun 28 16:15:00 2017 14 ## Update Count : 4 15 15 ############################################################################### 16 16 17 17 SRC += ControlStruct/LabelGenerator.cc \ 18 18 ControlStruct/LabelFixer.cc \ 19 19 ControlStruct/MLEMutator.cc \ 20 20 ControlStruct/Mutate.cc \ 21 ControlStruct/ForExprMutator.cc 22 21 ControlStruct/ForExprMutator.cc \ 22 ControlStruct/ExceptTranslate.cc
Note: See TracChangeset
for help on using the changeset viewer.