| 596 | } |
| 597 | |
| 598 | FunctionPtr generateLambdaFinalizer ( const string & lambdaName, ExprBlock * block, |
| 599 | const StructurePtr & ls, Program * thisProgram ) { |
| 600 | auto lfn = lambdaName + "`finalizer"; |
| 601 | auto pFunc = new Function(); |
| 602 | pFunc->privateFunction = true; |
| 603 | pFunc->generated = true; |
| 604 | pFunc->at = pFunc->atDecl = block->at; |
| 605 | pFunc->name = lfn; |
| 606 | auto fb = new ExprBlock(); |
| 607 | fb->at = block->at; |
| 608 | // fb->list.push_back(genComment("delete this lambda\n")); |
| 609 | if ( block->finalList.size() ) { |
| 610 | auto with = new ExprWith(block->at); |
| 611 | auto THISVAR = new ExprVar(block->at, "__this"); |
| 612 | with->with = new ExprPtr2Ref(block->at, THISVAR); |
| 613 | with->with->generated = true; |
| 614 | auto bbl = new ExprBlock(); |
| 615 | bbl->at = block->at; |
| 616 | with->body = bbl; |
| 617 | with->body->at = block->at; |
| 618 | bbl->list.reserve(block->finalList.size()); // copy finally section of the block body |
| 619 | for ( auto & subexpr : block->finalList ) { |
| 620 | bbl->list.push_back(subexpr->clone()); |
| 621 | } |
| 622 | fb->list.push_back(with); |
| 623 | } |
| 624 | // now, lets generate all release functions (after the original finally section is generated, but before deleting the lambda itself) |
| 625 | pFunc->body = fb; |
| 626 | thisProgram->library.foreach([&](Module * mod){ |
| 627 | for ( auto & cm : mod->captureMacros ) { |
| 628 | cm->releaseFunction(thisProgram, thisProgram->thisModule.get(), ls, pFunc); |
| 629 | } |
| 630 | return true; |
| 631 | },"*"); |
| 632 | |
| 633 | // delete * this |
| 634 | auto THISA = new ExprVar(block->at, "__this"); |
| 635 | auto THISAP = new ExprPtr2Ref(block->at, THISA); |
| 636 | auto delit = new ExprDelete(block->at, THISAP); |
| 637 | delit->alwaysSafe = true; |
| 638 | fb->list.push_back(delit); |
| 639 | // delete this |
| 640 | auto THISA1 = new ExprVar(block->at, "__this"); |
| 641 | auto delit1 = new ExprDelete(block->at, THISA1); |
| 642 | delit1->native = true; |
| 643 | delit1->alwaysSafe = true; |
| 644 | fb->list.push_back(delit1); |
| 645 | // function goo |
| 646 | pFunc->result = new TypeDecl(Type::tVoid); |
| 647 | auto cTHIS = new Variable(); |
| 648 | cTHIS->at = ls->at; |
| 649 | cTHIS->name = "__this"; |
| 650 | cTHIS->type = new TypeDecl(Type::tPointer); |
| 651 | cTHIS->type->firstType = new TypeDecl(ls); |
| 652 | cTHIS->type->isExplicit = true; |
| 653 | pFunc->arguments.push_back(cTHIS); |
| 654 | // wrapInUnsafe(pFunc); |
| 655 | verifyGenerated(pFunc->body); |
no test coverage detected