- Timestamp:
- Dec 19, 2023, 9:54:57 AM (9 months ago)
- Branches:
- master
- Children:
- 0a6d2045
- Parents:
- b7898ac
- File:
-
- 1 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ControlStruct/ExceptTranslate.cpp
rb7898ac r9fba8e6 145 145 ast::CompoundStmt * take_try_block( ast::TryStmt * tryStmt ); 146 146 ast::FunctionDecl * create_try_wrapper( const ast::CompoundStmt * body ); 147 ast::CaseClause * create_terminate_catch_case( 148 const ast::DeclWithType * except_obj, int index, ast::CatchClause * clause ); 147 149 ast::FunctionDecl * create_terminate_catch( CatchList &handlers ); 148 150 ast::CompoundStmt * create_single_matcher( … … 164 166 ast::ObjectDecl * make_voidptr_object( CodeLocation const & ) const; 165 167 ast::ObjectDecl * make_unused_index_object( CodeLocation const & ) const; 166 // void (*function)();167 ast::FunctionDecl * make_try_function( CodeLocation const & ) const;168 // void (*function)(int, exception);169 ast::FunctionDecl * make_catch_function( CodeLocation const & ) const;170 // int (*function)(exception);171 ast::FunctionDecl * make_match_function( CodeLocation const & ) const;172 // bool (*function)(exception);173 ast::FunctionDecl * make_handle_function( CodeLocation const & ) const;174 // void (*function)(__attribute__((unused)) void *);175 ast::FunctionDecl * make_finally_function( CodeLocation const & ) const;176 168 177 169 public: … … 248 240 } 249 241 250 ast::FunctionDecl * TryMutatorCore::make_try_function( 251 CodeLocation const & location ) const { 242 // TryStmt Mutation Helpers 243 244 ast::FunctionDecl * TryMutatorCore::create_try_wrapper( 245 const ast::CompoundStmt *body ) { 246 // void (*try)(void) `body` 252 247 return new ast::FunctionDecl( 253 location,248 body->location, 254 249 "try", 255 250 {}, //no param 256 251 {}, //no return 257 nullptr,252 ast::mutate( body ), 258 253 ast::Storage::Classes{}, 259 254 ast::Linkage::Cforall … … 261 256 } 262 257 263 ast::FunctionDecl * TryMutatorCore::make_catch_function( 264 CodeLocation const & location ) const { 265 return new ast::FunctionDecl( 266 location, 267 "catch", 268 { make_index_object( location ), make_exception_object( location ) }, 269 {}, //return void 270 nullptr, 271 ast::Storage::Classes{}, 272 ast::Linkage::Cforall 273 ); 274 } 275 276 ast::FunctionDecl * TryMutatorCore::make_match_function( 277 CodeLocation const & location ) const { 278 return new ast::FunctionDecl( 279 location, 280 "match", 281 { make_exception_object( location ) }, 282 { make_unused_index_object( location ) }, 283 nullptr, 284 ast::Storage::Classes{}, 285 ast::Linkage::Cforall 286 ); 287 } 288 289 ast::FunctionDecl * TryMutatorCore::make_handle_function( 290 CodeLocation const & location ) const { 291 return new ast::FunctionDecl( 292 location, 293 "handle", 294 { make_exception_object( location ) }, 295 { make_bool_object( location ) }, 296 nullptr, 297 ast::Storage::Classes{}, 298 ast::Linkage::Cforall 299 ); 300 } 301 302 ast::FunctionDecl * TryMutatorCore::make_finally_function( 303 CodeLocation const & location ) const { 304 return new ast::FunctionDecl( 305 location, 306 "finally", 307 { make_voidptr_object( location ) }, 308 {}, //return void 309 nullptr, 310 ast::Storage::Classes{}, 311 ast::Linkage::Cforall, 312 {}, 313 { ast::Function::Inline } 314 ); 315 } 316 317 // TryStmt Mutation Helpers 318 319 ast::FunctionDecl * TryMutatorCore::create_try_wrapper( 320 const ast::CompoundStmt *body ) { 321 322 ast::FunctionDecl * ret = make_try_function( body->location ); 323 ret->stmts = body; 324 return ret; 258 ast::CaseClause * TryMutatorCore::create_terminate_catch_case( 259 const ast::DeclWithType * except_obj, int index, ast::CatchClause * clause ) { 260 // case `index`: 261 // { 262 // __attribute__((cleanup(__cfaehm_cleanup_terminate))) 263 // `handler.decl` = { (virtual `decl.type`)`except` }; 264 // `handler.body`; 265 // } 266 // return; 267 const CodeLocation & location = clause->location; 268 269 auto clause_except = clause->decl.strict_as<ast::ObjectDecl>(); 270 auto local_except = ast::deepCopy( clause_except ); 271 local_except->attributes.push_back( new ast::Attribute( 272 "cleanup", 273 { new ast::NameExpr( location, "__cfaehm_cleanup_terminate" ) } 274 ) ); 275 276 local_except->init = new ast::ListInit( location, { 277 new ast::SingleInit( location, 278 new ast::VirtualCastExpr( location, 279 new ast::VariableExpr( location, except_obj ), 280 ast::deepCopy( local_except->get_type() ) 281 ) 282 ) 283 } ); 284 285 ast::DeclReplacer::DeclMap mapping; 286 mapping[clause_except] = local_except; 287 const ast::Stmt * body = strict_dynamic_cast<const ast::Stmt *>( 288 ast::DeclReplacer::replace(clause->body, mapping)); 289 290 return new ast::CaseClause( location, 291 ast::ConstantExpr::from_int( location, index ), 292 { 293 new ast::CompoundStmt( location, { 294 new ast::DeclStmt( location, local_except ), 295 body, 296 } ), 297 new ast::ReturnStmt( location, nullptr ), 298 } 299 ); 325 300 } 326 301 327 302 ast::FunctionDecl * TryMutatorCore::create_terminate_catch( 328 303 CatchList &handlers ) { 304 // void catch(int index, exception * except) { 305 // switch (index) { CATCH_CASE... } 306 // } 307 308 assert( !handlers.empty() ); 329 309 std::vector<ast::ptr<ast::CaseClause>> handler_wrappers; 330 331 assert (!handlers.empty()); 332 const CodeLocation loc = handlers.front()->location; 333 334 ast::FunctionDecl * func_t = make_catch_function( loc ); 335 const ast::DeclWithType * index_obj = func_t->params.front(); 336 const ast::DeclWithType * except_obj = func_t->params.back(); 310 const CodeLocation & location = handlers.front()->location; 311 312 const ast::DeclWithType * index_obj = make_index_object( location ); 313 const ast::DeclWithType * except_obj = make_exception_object( location ); 337 314 338 315 // Index 1..{number of handlers} 339 int index = 0; 340 CatchList::iterator it = handlers.begin(); 341 for ( ; it != handlers.end() ; ++it ) { 342 ++index; 343 ast::CatchClause * handler = *it; 344 const CodeLocation loc = handler->location; 345 346 // case `index`: 347 // { 348 // `handler.decl` = { (virtual `decl.type`)`except` }; 349 // `handler.body`; 350 // } 351 // return; 352 ast::CompoundStmt * block = new ast::CompoundStmt(loc); 353 354 // Just copy the exception value. (Post Validation) 355 const ast::ObjectDecl * handler_decl = 356 handler->decl.strict_as<ast::ObjectDecl>(); 357 ast::ObjectDecl * local_except = ast::deepCopy(handler_decl); 358 ast::VirtualCastExpr * vcex = new ast::VirtualCastExpr(loc, 359 new ast::VariableExpr( loc, except_obj ), 360 local_except->get_type() 361 ); 362 vcex->location = handler->location; 363 local_except->init = new ast::ListInit(loc, { new ast::SingleInit( loc, vcex ) }); 364 block->push_back( new ast::DeclStmt( loc, local_except ) ); 365 366 // Add the cleanup attribute. 367 local_except->attributes.push_back( new ast::Attribute( 368 "cleanup", 369 { new ast::NameExpr( loc, "__cfaehm_cleanup_terminate" ) } 370 ) ); 371 372 ast::DeclReplacer::DeclMap mapping; 373 mapping[handler_decl] = local_except; 374 const ast::Stmt * mutBody = strict_dynamic_cast<const ast::Stmt *>( 375 ast::DeclReplacer::replace(handler->body, mapping)); 376 377 378 block->push_back( mutBody ); 379 // handler->body = nullptr; 380 381 handler_wrappers.push_back( new ast::CaseClause(loc, 382 ast::ConstantExpr::from_int(loc, index) , 383 { block, new ast::ReturnStmt( loc, nullptr ) } 384 )); 316 for ( const auto & [index, handler] : enumerate( handlers ) ) { 317 handler_wrappers.push_back( 318 create_terminate_catch_case( except_obj, index + 1, handler ) ); 385 319 } 386 320 // TODO: Some sort of meaningful error on default perhaps? 387 321 388 ast::SwitchStmt * handler_lookup = new ast::SwitchStmt( loc ,389 new ast::VariableExpr( loc , index_obj ),322 ast::SwitchStmt * handler_lookup = new ast::SwitchStmt( location, 323 new ast::VariableExpr( location, index_obj ), 390 324 std::move(handler_wrappers) 391 325 ); 392 ast::CompoundStmt * body = new ast::CompoundStmt( loc, {handler_lookup} ); 393 394 func_t->stmts = body; 395 return func_t; 326 ast::CompoundStmt * body = new ast::CompoundStmt( location, {handler_lookup} ); 327 328 // void (*catch)(int, exception_t *) `body` 329 return new ast::FunctionDecl( 330 location, 331 "catch", 332 { index_obj, except_obj }, 333 {}, //return void 334 body, 335 ast::Storage::Classes{}, 336 ast::Linkage::Cforall 337 ); 396 338 } 397 339 … … 441 383 // } 442 384 443 assert (!handlers.empty()); 444 const CodeLocation loc = handlers.front()->location; 445 446 ast::CompoundStmt * body = new ast::CompoundStmt(loc); 447 448 ast::FunctionDecl * func_t = make_match_function( loc ); 449 const ast::DeclWithType * except_obj = func_t->params.back(); 385 assert( !handlers.empty() ); 386 const CodeLocation & location = handlers.front()->location; 387 388 ast::CompoundStmt * body = new ast::CompoundStmt( location ); 389 const ast::DeclWithType * except_obj = make_exception_object( location ); 450 390 451 391 // Index 1..{number of handlers} … … 469 409 } 470 410 471 body->push_back( new ast::ReturnStmt(loc, 472 ast::ConstantExpr::from_int( loc, 0 ) )); 473 474 func_t->stmts = body; 475 476 return func_t; 411 body->push_back( new ast::ReturnStmt( location, 412 ast::ConstantExpr::from_int( location, 0 ) )); 413 414 // void (*match)(exception_t *) `body` 415 return new ast::FunctionDecl( 416 location, 417 "match", 418 { except_obj }, 419 { make_unused_index_object( location ) }, 420 body, 421 ast::Storage::Classes{}, 422 ast::Linkage::Cforall 423 ); 477 424 } 478 425 … … 489 436 // } 490 437 491 ast::ObjectDecl * index = new ast::ObjectDecl( loc, "__handler_index", 492 new ast::BasicType( ast::BasicType::SignedInt ), 493 new ast::SingleInit( loc, 494 new ast::UntypedExpr( loc, 495 new ast::NameExpr( loc, "__cfaehm_try_terminate" ), 496 { 497 new ast::VariableExpr( loc, try_wrapper ), 498 new ast::VariableExpr( loc, terminate_match ), 499 } 500 ) 438 ast::ObjectDecl * index = make_index_object( loc ); 439 index->init = new ast::SingleInit( loc, 440 new ast::UntypedExpr( loc, 441 new ast::NameExpr( loc, "__cfaehm_try_terminate" ), 442 { 443 new ast::VariableExpr( loc, try_wrapper ), 444 new ast::VariableExpr( loc, terminate_match ), 445 } 501 446 ) 502 447 ); … … 526 471 // HANDLER WRAPPERS { `hander->body`; return true; } 527 472 // } 528 assert (!handlers.empty()); 529 const CodeLocation loc = handlers.front()->location;530 ast::CompoundStmt * body = new ast::CompoundStmt(loc);531 532 ast:: FunctionDecl * func_t = make_handle_function( loc);533 const ast::DeclWithType * except_obj = func_t->params.back();473 474 assert( !handlers.empty() ); 475 const CodeLocation & location = handlers.front()->location; 476 477 ast::CompoundStmt * body = new ast::CompoundStmt( location ); 478 const ast::DeclWithType * except_obj = make_exception_object( location ); 534 479 535 480 CatchList::iterator it; … … 555 500 } 556 501 557 body->push_back( new ast::ReturnStmt(loc, 558 ast::ConstantExpr::from_bool(loc, false ) ) ); 559 func_t->stmts = body; 560 561 return func_t; 502 body->push_back( new ast::ReturnStmt( location, 503 ast::ConstantExpr::from_bool( location, false ) ) ); 504 505 // bool (*handle)(exception_t *) `body` 506 return new ast::FunctionDecl( 507 location, 508 "handle", 509 { except_obj }, 510 { make_bool_object( location ) }, 511 body, 512 ast::Storage::Classes{}, 513 ast::Linkage::Cforall 514 ); 562 515 } 563 516 … … 601 554 ast::FunctionDecl * TryMutatorCore::create_finally_wrapper( 602 555 ast::TryStmt * tryStmt ) { 603 // void finally( ) { `finally->block` }556 // void finally(__attribute__((unused)) void *) `finally->body` 604 557 const ast::FinallyClause * finally = tryStmt->finally; 605 const ast::CompoundStmt * body = finally->body; 606 607 ast::FunctionDecl * func_t = make_finally_function( tryStmt->location ); 608 func_t->stmts = body; 609 610 tryStmt->finally = nullptr; 611 612 return func_t; 558 return new ast::FunctionDecl( 559 tryStmt->location, 560 "finally", 561 { make_voidptr_object( tryStmt->location ) }, 562 {}, //return void 563 ast::mutate( finally->body.get() ), 564 ast::Storage::Classes{}, 565 ast::Linkage::Cforall, 566 {}, 567 { ast::Function::Inline } 568 ); 613 569 } 614 570 … … 618 574 // __attribute__((cleanup( `finally_wrapper` ))); 619 575 620 const CodeLocation loc= finally_wrapper->location;576 const CodeLocation & location = finally_wrapper->location; 621 577 return new ast::ObjectDecl( 622 loc ,578 location, 623 579 "__finally_hook", 624 580 new ast::StructInstType( … … 629 585 ast::Linkage::Cforall, 630 586 nullptr, 631 {new ast::Attribute("cleanup", {new ast::VariableExpr {loc, finally_wrapper}})}587 {new ast::Attribute("cleanup", {new ast::VariableExpr(location, finally_wrapper)})} 632 588 ); 633 589 }
Note: See TracChangeset
for help on using the changeset viewer.