1
0
Fork 0
mirror of https://github.com/beefytech/Beef.git synced 2025-06-08 11:38:21 +02:00

Fixed split deferred call processor

This commit is contained in:
Brian Fiete 2022-08-24 14:49:05 -07:00
parent e09b701e9f
commit acb644830c
6 changed files with 97 additions and 8 deletions

View file

@ -801,6 +801,8 @@ namespace IDE
IDEUtils.FixFilePath(libPath); IDEUtils.FixFilePath(libPath);
libPaths.Add(libPath); libPaths.Add(libPath);
} }
else
delete libPath;
} }
@ -813,6 +815,8 @@ namespace IDE
IDEUtils.FixFilePath(depPath); IDEUtils.FixFilePath(depPath);
depPaths.Add(depPath); depPaths.Add(depPath);
} }
else
delete depPath;
} }
for (let libPath in options.mBuildOptions.mLibPaths) for (let libPath in options.mBuildOptions.mLibPaths)

View file

@ -8453,6 +8453,9 @@ void BeMCContext::DoFrameObjPass()
// If we're doing UseBP, we have to allocate these at call time // If we're doing UseBP, we have to allocate these at call time
int homeSize = BF_ALIGN(BF_MAX(mMaxCallParamCount, 4) * 8, 16); int homeSize = BF_ALIGN(BF_MAX(mMaxCallParamCount, 4) * 8, 16);
if (mMaxCallParamCount == -1)
homeSize = 0;
mStackSize = 0; mStackSize = 0;
if (mUseBP) if (mUseBP)

View file

@ -2006,9 +2006,12 @@ void BfModule::RestoreScopeState()
} }
} }
mCurMethodState->mCurScope->mDone = true;
if (!mCurMethodState->mLeftBlockUncond) if (!mCurMethodState->mLeftBlockUncond)
EmitDeferredScopeCalls(true, mCurMethodState->mCurScope); EmitDeferredScopeCalls(true, mCurMethodState->mCurScope);
EmitDeferredCallProcessorInstances(mCurMethodState->mCurScope);
RestoreScoreState_LocalVariables(); RestoreScoreState_LocalVariables();
if (mCurMethodState->mCurScope->mValueScopeStart) if (mCurMethodState->mCurScope->mValueScopeStart)
@ -16017,7 +16020,7 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa
} }
auto prevHead = checkScope->mDeferredCallEntries.mHead; auto prevHead = checkScope->mDeferredCallEntries.mHead;
EmitDeferredCall(*deferredCallEntry, true); EmitDeferredCall(checkScope, *deferredCallEntry, true);
if (prevHead != checkScope->mDeferredCallEntries.mHead) if (prevHead != checkScope->mDeferredCallEntries.mHead)
{ {
// The list changed, start over and ignore anything we've already handled // The list changed, start over and ignore anything we've already handled
@ -16028,7 +16031,7 @@ void BfModule::EmitDeferredScopeCalls(bool useSrcPositions, BfScopeData* scopeDa
} }
else else
{ {
EmitDeferredCall(*deferredCallEntry, true); EmitDeferredCall(checkScope, *deferredCallEntry, true);
deferredCallEntry = deferredCallEntry->mNext; deferredCallEntry = deferredCallEntry->mNext;
} }
} }
@ -21819,12 +21822,15 @@ void BfModule::ProcessMethod(BfMethodInstance* methodInstance, bool isInlineDup,
AssertErrorState(); AssertErrorState();
} }
mCurMethodState->mHeadScope.mDone = true;
if (!mCurMethodState->mHadReturn) if (!mCurMethodState->mHadReturn)
{ {
// Clear off the stackallocs that have occurred after a scopeData break // Clear off the stackallocs that have occurred after a scopeData break
EmitDeferredScopeCalls(false, &mCurMethodState->mHeadScope, mCurMethodState->mIRExitBlock); EmitDeferredScopeCalls(false, &mCurMethodState->mHeadScope, mCurMethodState->mIRExitBlock);
} }
EmitDeferredCallProcessorInstances(&mCurMethodState->mHeadScope);
if (mCurMethodState->mIRExitBlock) if (mCurMethodState->mIRExitBlock)
{ {
for (auto preExitBlock : mCurMethodState->mHeadScope.mAtEndBlocks) for (auto preExitBlock : mCurMethodState->mHeadScope.mAtEndBlocks)

View file

@ -425,6 +425,14 @@ enum BfScopeKind
BfScopeKind_StatementTarget_Conditional, 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" 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. // Looped and Conditional are mutually exclusive. "Dyn" means Looped OR Conditional.
class BfScopeData class BfScopeData
@ -454,11 +462,13 @@ public:
bool mSupressNextUnreachable; bool mSupressNextUnreachable;
bool mInConstIgnore; bool mInConstIgnore;
bool mIsSharedTempBlock; bool mIsSharedTempBlock;
bool mDone;
BfMixinState* mMixinState; BfMixinState* mMixinState;
BfBlock* mAstBlock; BfBlock* mAstBlock;
BfAstNode* mCloseNode; BfAstNode* mCloseNode;
BfExprEvaluator* mExprEvaluator; BfExprEvaluator* mExprEvaluator;
SLIList<BfDeferredCallEntry*> mDeferredCallEntries; SLIList<BfDeferredCallEntry*> mDeferredCallEntries;
Array<BfDeferredCallProcessorInstance> mDeferredCallProcessorInstances;
BfIRValue mBlock; BfIRValue mBlock;
BfIRValue mValueScopeStart; BfIRValue mValueScopeStart;
BfIRValue mSavedStack; BfIRValue mSavedStack;
@ -495,6 +505,7 @@ public:
mInInitBlock = false; mInInitBlock = false;
mInConstIgnore = false; mInConstIgnore = false;
mIsSharedTempBlock = false; mIsSharedTempBlock = false;
mDone = false;
mMixinDepth = 0; mMixinDepth = 0;
mScopeDepth = 0; mScopeDepth = 0;
mScopeLocalId = -1; mScopeLocalId = -1;
@ -1688,8 +1699,9 @@ public:
bool AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfScopeData* scope); bool AddDeferredCallEntry(BfDeferredCallEntry* deferredCallEntry, BfScopeData* scope);
BfDeferredCallEntry* AddDeferredBlock(BfBlock* block, BfScopeData* scope, Array<BfDeferredCapture>* captures = NULL); 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); 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 EmitDeferredCall(BfScopeData* scopeData, BfDeferredCallEntry& deferredCallEntry, bool moveBlocks);
void EmitDeferredCallProcessor(SLIList<BfDeferredCallEntry*>& callEntries, BfIRValue callTail); void EmitDeferredCallProcessor(BfScopeData* scopeData, SLIList<BfDeferredCallEntry*>& callEntries, BfIRValue callTail);
void EmitDeferredCallProcessorInstances(BfScopeData* scopeData);
bool CanCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags = BfCastFlags_None); bool CanCast(BfTypedValue typedVal, BfType* toType, BfCastFlags castFlags = BfCastFlags_None);
bool AreSplatsCompatible(BfType* fromType, BfType* toType, bool* outNeedsMemberCasting); bool AreSplatsCompatible(BfType* fromType, BfType* toType, bool* outNeedsMemberCasting);
BfType* GetClosestNumericCastType(const BfTypedValue& typedVal, BfType* wantType); BfType* GetClosestNumericCastType(const BfTypedValue& typedVal, BfType* wantType);

View file

@ -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)) if ((mCompiler->mIsResolveOnly) && (!mIsComptimeModule) && (deferredCallEntry.mHandlerCount > 0))
{ {
@ -813,7 +834,23 @@ void BfModule::EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry, bool mov
if (deferredCallEntry.IsDynList()) 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; return;
} }
@ -877,7 +914,7 @@ void BfModule::EmitDeferredCall(BfDeferredCallEntry& deferredCallEntry, bool mov
EmitDeferredCall(deferredCallEntry.mModuleMethodInstance, args, flags); 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; int64 collisionId = 0;
@ -1036,7 +1073,7 @@ void BfModule::EmitDeferredCallProcessor(SLIList<BfDeferredCallEntry*>& callEntr
} }
auto prevHead = callEntries.mHead; auto prevHead = callEntries.mHead;
EmitDeferredCall(*deferredCallEntry, moveBlocks); EmitDeferredCall(scopeData, *deferredCallEntry, moveBlocks);
ValueScopeEnd(valueScopeStart); ValueScopeEnd(valueScopeStart);
mBfIRBuilder->CreateBr(condBB); mBfIRBuilder->CreateBr(condBB);

View file

@ -43,6 +43,33 @@ namespace Tests
str.Contains('T'); 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() public static mixin GetStr()
{ {
scope:mixin String("TestString") scope:mixin String("TestString")