mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-08 03:28:20 +02:00
Fixed split deferred call processor
This commit is contained in:
parent
e09b701e9f
commit
acb644830c
6 changed files with 97 additions and 8 deletions
|
@ -801,6 +801,8 @@ namespace IDE
|
|||
IDEUtils.FixFilePath(libPath);
|
||||
libPaths.Add(libPath);
|
||||
}
|
||||
else
|
||||
delete libPath;
|
||||
}
|
||||
|
||||
|
||||
|
@ -813,6 +815,8 @@ namespace IDE
|
|||
IDEUtils.FixFilePath(depPath);
|
||||
depPaths.Add(depPath);
|
||||
}
|
||||
else
|
||||
delete depPath;
|
||||
}
|
||||
|
||||
for (let libPath in options.mBuildOptions.mLibPaths)
|
||||
|
|
|
@ -8453,6 +8453,9 @@ void BeMCContext::DoFrameObjPass()
|
|||
// If we're doing UseBP, we have to allocate these at call time
|
||||
int homeSize = BF_ALIGN(BF_MAX(mMaxCallParamCount, 4) * 8, 16);
|
||||
|
||||
if (mMaxCallParamCount == -1)
|
||||
homeSize = 0;
|
||||
|
||||
mStackSize = 0;
|
||||
|
||||
if (mUseBP)
|
||||
|
|
|
@ -2006,9 +2006,12 @@ void BfModule::RestoreScopeState()
|
|||
}
|
||||
}
|
||||
|
||||
mCurMethodState->mCurScope->mDone = true;
|
||||
if (!mCurMethodState->mLeftBlockUncond)
|
||||
EmitDeferredScopeCalls(true, mCurMethodState->mCurScope);
|
||||
|
||||
EmitDeferredCallProcessorInstances(mCurMethodState->mCurScope);
|
||||
|
||||
RestoreScoreState_LocalVariables();
|
||||
|
||||
if (mCurMethodState->mCurScope->mValueScopeStart)
|
||||
|
@ -16017,7 +16020,7 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa
|
|||
}
|
||||
|
||||
auto prevHead = checkScope->mDeferredCallEntries.mHead;
|
||||
EmitDeferredCall(*deferredCallEntry, true);
|
||||
EmitDeferredCall(checkScope, *deferredCallEntry, true);
|
||||
if (prevHead != checkScope->mDeferredCallEntries.mHead)
|
||||
{
|
||||
// The list changed, start over and ignore anything we've already handled
|
||||
|
@ -16028,7 +16031,7 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa
|
|||
}
|
||||
else
|
||||
{
|
||||
EmitDeferredCall(*deferredCallEntry, true);
|
||||
EmitDeferredCall(checkScope, *deferredCallEntry, true);
|
||||
deferredCallEntry = deferredCallEntry->mNext;
|
||||
}
|
||||
}
|
||||
|
@ -21819,12 +21822,15 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup,
|
|||
AssertErrorState();
|
||||
}
|
||||
|
||||
mCurMethodState->mHeadScope.mDone = true;
|
||||
if (!mCurMethodState->mHadReturn)
|
||||
{
|
||||
// Clear off the stackallocs that have occurred after a scopeData break
|
||||
EmitDeferredScopeCalls(false, &mCurMethodState->mHeadScope, mCurMethodState->mIRExitBlock);
|
||||
}
|
||||
|
||||
EmitDeferredCallProcessorInstances(&mCurMethodState->mHeadScope);
|
||||
|
||||
if (mCurMethodState->mIRExitBlock)
|
||||
{
|
||||
for (auto preExitBlock : mCurMethodState->mHeadScope.mAtEndBlocks)
|
||||
|
|
|
@ -425,6 +425,14 @@ enum BfScopeKind
|
|||
BfScopeKind_StatementTarget_Conditional,
|
||||
};
|
||||
|
||||
class BfDeferredCallProcessorInstance
|
||||
{
|
||||
public:
|
||||
BfDeferredCallEntry* mDeferredCallEntry;
|
||||
BfIRBlock mProcessorBlock;
|
||||
BfIRBlock mContinueBlock;
|
||||
};
|
||||
|
||||
// "Looped" means this scope will execute zero to many times, "Conditional" means zero or one.
|
||||
// Looped and Conditional are mutually exclusive. "Dyn" means Looped OR Conditional.
|
||||
class BfScopeData
|
||||
|
@ -454,11 +462,13 @@ public:
|
|||
bool mSupressNextUnreachable;
|
||||
bool mInConstIgnore;
|
||||
bool mIsSharedTempBlock;
|
||||
bool mDone;
|
||||
BfMixinState* mMixinState;
|
||||
BfBlock* mAstBlock;
|
||||
BfAstNode* mCloseNode;
|
||||
BfExprEvaluator* mExprEvaluator;
|
||||
SLIList<BfDeferredCallEntry*> mDeferredCallEntries;
|
||||
Array<BfDeferredCallProcessorInstance> mDeferredCallProcessorInstances;
|
||||
BfIRValue mBlock;
|
||||
BfIRValue mValueScopeStart;
|
||||
BfIRValue mSavedStack;
|
||||
|
@ -495,6 +505,7 @@ public:
|
|||
mInInitBlock = false;
|
||||
mInConstIgnore = false;
|
||||
mIsSharedTempBlock = false;
|
||||
mDone = false;
|
||||
mMixinDepth = 0;
|
||||
mScopeDepth = 0;
|
||||
mScopeLocalId = -1;
|
||||
|
@ -1688,8 +1699,9 @@ public:
|
|||
bool AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfScopeData* scope);
|
||||
BfDeferredCallEntry* AddDeferredBlock(BfBlock* block, BfScopeData* scope, Array<BfDeferredCapture>* captures = NULL);
|
||||
BfDeferredCallEntry* AddDeferredCall(const BfModuleMethodInstance& moduleMethodInstance, SizedArrayImpl<BfIRValue>& llvmArgs, BfScopeData* scope, BfAstNode* srcNode = NULL, bool bypassVirtual = false, bool doNullCheck = false);
|
||||
void EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry, bool moveBlocks);
|
||||
void EmitDeferredCallProcessor(SLIList<BfDeferredCallEntry*>& callEntries, BfIRValue callTail);
|
||||
void EmitDeferredCall(BfScopeData* scopeData, BfDeferredCallEntry& deferredCallEntry, bool moveBlocks);
|
||||
void EmitDeferredCallProcessor(BfScopeData* scopeData, SLIList<BfDeferredCallEntry*>& callEntries, BfIRValue callTail);
|
||||
void EmitDeferredCallProcessorInstances(BfScopeData* scopeData);
|
||||
bool CanCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags = BfCastFlags_None);
|
||||
bool AreSplatsCompatible(BfType* fromType, BfType* toType, bool* outNeedsMemberCasting);
|
||||
BfType* GetClosestNumericCastType(const BfTypedValue& typedVal, BfType* wantType);
|
||||
|
|
|
@ -801,7 +801,28 @@ void BfModule::EmitDeferredCall(BfModuleMethodInstance moduleMethodInstance, Siz
|
|||
}
|
||||
}
|
||||
|
||||
void BfModule::EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry, bool moveBlocks)
|
||||
void BfModule::EmitDeferredCallProcessorInstances(BfScopeData* scopeData)
|
||||
{
|
||||
BF_ASSERT(scopeData->mDone);
|
||||
|
||||
for (auto& deferredProcessor : scopeData->mDeferredCallProcessorInstances)
|
||||
{
|
||||
SetAndRestoreValue<bool> prevHadReturn(mCurMethodState->mHadReturn, false);
|
||||
SetAndRestoreValue<bool> prevInPostReturn(mCurMethodState->mInPostReturn, false);
|
||||
SetAndRestoreValue<bool> prevLeftBlockUncond(mCurMethodState->mLeftBlockUncond, false);
|
||||
|
||||
auto prevBlock = mBfIRBuilder->GetInsertBlock();
|
||||
|
||||
mBfIRBuilder->AddBlock(deferredProcessor.mProcessorBlock);
|
||||
mBfIRBuilder->SetInsertPoint(deferredProcessor.mProcessorBlock);
|
||||
EmitDeferredCallProcessor(scopeData, deferredProcessor.mDeferredCallEntry->mDynList, deferredProcessor.mDeferredCallEntry->mDynCallTail);
|
||||
mBfIRBuilder->CreateBr(deferredProcessor.mContinueBlock);
|
||||
|
||||
mBfIRBuilder->SetInsertPoint(prevBlock);
|
||||
}
|
||||
}
|
||||
|
||||
void BfModule::EmitDeferredCall(BfScopeData* scopeData, BfDeferredCallEntry& deferredCallEntry, bool moveBlocks)
|
||||
{
|
||||
if ((mCompiler->mIsResolveOnly) && (!mIsComptimeModule) && (deferredCallEntry.mHandlerCount > 0))
|
||||
{
|
||||
|
@ -813,7 +834,23 @@ void BfModule::EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry, bool mov
|
|||
|
||||
if (deferredCallEntry.IsDynList())
|
||||
{
|
||||
EmitDeferredCallProcessor(deferredCallEntry.mDynList, deferredCallEntry.mDynCallTail);
|
||||
if (scopeData->mDone)
|
||||
{
|
||||
EmitDeferredCallProcessor(scopeData, deferredCallEntry.mDynList, deferredCallEntry.mDynCallTail);
|
||||
}
|
||||
else
|
||||
{
|
||||
BfDeferredCallProcessorInstance deferredProcessor;
|
||||
deferredProcessor.mProcessorBlock = mBfIRBuilder->CreateBlock("dyn.processor");
|
||||
deferredProcessor.mContinueBlock = mBfIRBuilder->CreateBlock("dyn.continue");
|
||||
deferredProcessor.mDeferredCallEntry = &deferredCallEntry;
|
||||
scopeData->mDeferredCallProcessorInstances.Add(deferredProcessor);
|
||||
mBfIRBuilder->CreateBr(deferredProcessor.mProcessorBlock);
|
||||
|
||||
mBfIRBuilder->AddBlock(deferredProcessor.mContinueBlock);
|
||||
mBfIRBuilder->SetInsertPoint(deferredProcessor.mContinueBlock);
|
||||
}
|
||||
|
||||
return;
|
||||
}
|
||||
|
||||
|
@ -877,7 +914,7 @@ void BfModule::EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry, bool mov
|
|||
EmitDeferredCall(deferredCallEntry.mModuleMethodInstance, args, flags);
|
||||
}
|
||||
|
||||
void BfModule::EmitDeferredCallProcessor(SLIList<BfDeferredCallEntry*>& callEntries, BfIRValue callTail)
|
||||
void BfModule::EmitDeferredCallProcessor(BfScopeData* scopeData, SLIList<BfDeferredCallEntry*>& callEntries, BfIRValue callTail)
|
||||
{
|
||||
int64 collisionId = 0;
|
||||
|
||||
|
@ -1036,7 +1073,7 @@ void BfModule::EmitDeferredCallProcessor(SLIList<BfDeferredCallEntry*>& callEntr
|
|||
}
|
||||
|
||||
auto prevHead = callEntries.mHead;
|
||||
EmitDeferredCall(*deferredCallEntry, moveBlocks);
|
||||
EmitDeferredCall(scopeData, *deferredCallEntry, moveBlocks);
|
||||
ValueScopeEnd(valueScopeStart);
|
||||
mBfIRBuilder->CreateBr(condBB);
|
||||
|
||||
|
|
|
@ -43,6 +43,33 @@ namespace Tests
|
|||
str.Contains('T');
|
||||
}*/
|
||||
|
||||
public static void Defer0(ref int val)
|
||||
{
|
||||
for (int i < 10)
|
||||
{
|
||||
defer::
|
||||
{
|
||||
val += 100;
|
||||
}
|
||||
|
||||
if (i == 2)
|
||||
return;
|
||||
|
||||
defer::
|
||||
{
|
||||
val++;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[Test]
|
||||
public static void TestBasics()
|
||||
{
|
||||
int a = 0;
|
||||
Defer0(ref a);
|
||||
Test.Assert(a == 302);
|
||||
}
|
||||
|
||||
public static mixin GetStr()
|
||||
{
|
||||
scope:mixin String("TestString")
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue