mirror of
https://github.com/beefytech/Beef.git
synced 2025-06-13 22:04:09 +02:00
Fixed issue with multiple Dispose calls on foreach enumerator
This commit is contained in:
parent
9236b3e0d2
commit
85462e6d62
2 changed files with 60 additions and 8 deletions
|
@ -6424,7 +6424,11 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
scopeData.mIsLoop = true;
|
BfScopeData innerScopeData;
|
||||||
|
innerScopeData.mValueScopeStart = ValueScopeStart();
|
||||||
|
mCurMethodState->AddScope(&innerScopeData);
|
||||||
|
NewScopeState(true, false);
|
||||||
|
innerScopeData.mIsLoop = true;
|
||||||
|
|
||||||
if ((autoComplete != NULL) && (forEachStmt->mVariableTypeRef != NULL))
|
if ((autoComplete != NULL) && (forEachStmt->mVariableTypeRef != NULL))
|
||||||
autoComplete->CheckVarResolution(forEachStmt->mVariableTypeRef, varType);
|
autoComplete->CheckVarResolution(forEachStmt->mVariableTypeRef, varType);
|
||||||
|
@ -6445,7 +6449,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
||||||
BfBreakData breakData;
|
BfBreakData breakData;
|
||||||
breakData.mIRContinueBlock = incBB;
|
breakData.mIRContinueBlock = incBB;
|
||||||
breakData.mIRBreakBlock = endBB;
|
breakData.mIRBreakBlock = endBB;
|
||||||
breakData.mScope = &scopeData;
|
breakData.mScope = &innerScopeData;
|
||||||
breakData.mInnerValueScopeStart = valueScopeStartInner;
|
breakData.mInnerValueScopeStart = valueScopeStartInner;
|
||||||
breakData.mPrevBreakData = mCurMethodState->mBreakData;
|
breakData.mPrevBreakData = mCurMethodState->mBreakData;
|
||||||
SetAndRestoreValue<BfBreakData*> prevBreakData(mCurMethodState->mBreakData, &breakData);
|
SetAndRestoreValue<BfBreakData*> prevBreakData(mCurMethodState->mBreakData, &breakData);
|
||||||
|
@ -6679,6 +6683,7 @@ void BfModule::Visit(BfForEachStatement* forEachStmt)
|
||||||
mCurMethodState->mLeftBlockCond = false;
|
mCurMethodState->mLeftBlockCond = false;
|
||||||
|
|
||||||
RestoreScopeState();
|
RestoreScopeState();
|
||||||
|
RestoreScopeState();
|
||||||
}
|
}
|
||||||
|
|
||||||
void BfModule::Visit(BfDeferStatement* deferStmt)
|
void BfModule::Visit(BfDeferStatement* deferStmt)
|
||||||
|
|
|
@ -1,6 +1,7 @@
|
||||||
#pragma warning disable 168
|
#pragma warning disable 168
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Collections;
|
||||||
|
|
||||||
namespace Tests
|
namespace Tests
|
||||||
{
|
{
|
||||||
|
@ -12,6 +13,21 @@ namespace Tests
|
||||||
public int32 mB;
|
public int32 mB;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
class EnumeratorTest : IEnumerator<int32>, IDisposable
|
||||||
|
{
|
||||||
|
public int mDispCount;
|
||||||
|
|
||||||
|
public void Dispose()
|
||||||
|
{
|
||||||
|
mDispCount++;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Result<int32> GetNext()
|
||||||
|
{
|
||||||
|
return .Err;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public static void TestBasics()
|
public static void TestBasics()
|
||||||
{
|
{
|
||||||
|
@ -26,6 +42,37 @@ namespace Tests
|
||||||
StructA sa = val;
|
StructA sa = val;
|
||||||
int idx = @val;
|
int idx = @val;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
var e = scope EnumeratorTest();
|
||||||
|
for (var val in e)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
Test.Assert(e.mDispCount == 1);
|
||||||
|
for (var val in e)
|
||||||
|
{
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
Test.Assert(e.mDispCount == 2);
|
||||||
|
TestEnumerator1(e);
|
||||||
|
Test.Assert(e.mDispCount == 3);
|
||||||
|
TestEnumerator2(e);
|
||||||
|
Test.Assert(e.mDispCount == 4);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void TestEnumerator1(EnumeratorTest e)
|
||||||
|
{
|
||||||
|
for (var val in e)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public static void TestEnumerator2(EnumeratorTest e)
|
||||||
|
{
|
||||||
|
for (var val in e)
|
||||||
|
{
|
||||||
|
return;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Add table
Add a link
Reference in a new issue