| 2546 | } |
| 2547 | |
| 2548 | void BfModule::SaveStackState(BfScopeData* scopeData) |
| 2549 | { |
| 2550 | // If we push a value on the stack that needs to survive until the end of scopeData, we need to make sure that no |
| 2551 | // scopes within scopeData restore the stack |
| 2552 | auto checkScope = mCurMethodState->mCurScope; |
| 2553 | while (true) |
| 2554 | { |
| 2555 | if (checkScope == scopeData) |
| 2556 | { |
| 2557 | if ((!checkScope->mSavedStack) && (checkScope->mBlock) && (!checkScope->mIsScopeHead) && (!checkScope->mHadOuterDynStack)) |
| 2558 | { |
| 2559 | if (mBfIRBuilder->mHasDebugInfo) |
| 2560 | mBfIRBuilder->SaveDebugLocation(); |
| 2561 | auto prevPos = mBfIRBuilder->GetInsertBlock(); |
| 2562 | mBfIRBuilder->SetInsertPointAtStart(checkScope->mBlock); |
| 2563 | checkScope->mSavedStack = mBfIRBuilder->CreateStackSave(); |
| 2564 | mBfIRBuilder->ClearDebugLocation(checkScope->mSavedStack); |
| 2565 | mBfIRBuilder->SetInsertPoint(prevPos); |
| 2566 | if (mBfIRBuilder->mHasDebugInfo) |
| 2567 | mBfIRBuilder->RestoreDebugLocation(); |
| 2568 | } |
| 2569 | break; |
| 2570 | } |
| 2571 | if (checkScope->mSavedStack) |
| 2572 | { |
| 2573 | for (auto usage : checkScope->mSavedStackUses) |
| 2574 | mBfIRBuilder->EraseInstFromParent(usage); |
| 2575 | checkScope->mSavedStackUses.Clear(); |
| 2576 | |
| 2577 | mBfIRBuilder->EraseInstFromParent(checkScope->mSavedStack); |
| 2578 | checkScope->mSavedStack = BfIRValue(); |
| 2579 | } |
| 2580 | checkScope = checkScope->mPrevScope; |
| 2581 | } |
| 2582 | } |
| 2583 | |
| 2584 | BfIRValue BfModule::ValueScopeStart() |
| 2585 | { |
nothing calls this directly
no test coverage detected