Skip to content

Commit

Permalink
Fix foreach loops breaking in recursive methods when used with an exp…
Browse files Browse the repository at this point in the history
…ression iterator

- When using a foreach loop in a method marked with [RecursiveMethod] while iterating on an expression result, the expression result was not being pushed to the recursive stack. This could cause unexpected behavior/errors in some cases. Reported by GlitchyDev
  • Loading branch information
MerlinVR committed Jul 12, 2021
1 parent d61ba6d commit 603ae98
Show file tree
Hide file tree
Showing 4 changed files with 44 additions and 1 deletion.
6 changes: 6 additions & 0 deletions Assets/UdonSharp/Editor/UdonSharpASTVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2206,6 +2206,12 @@ public override void VisitForEachStatement(ForEachStatementSyntax node)
throw new System.Exception("foreach loop must iterate an array type");
}

if (visitorContext.isRecursiveMethod &&
((arraySymbol.declarationType & SymbolDeclTypeFlags.Internal) != 0))
{
arraySymbol.declarationType |= SymbolDeclTypeFlags.NeedsRecursivePush;
}

if (node.Type.IsVar)
{
if (!isTransformIterator)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -17,6 +17,7 @@ MonoBehaviour:
udonAssembly:
assemblyError:
sourceCsScript: {fileID: 11500000, guid: 41aa655b07e37a84292568dd0dc1aac5, type: 3}
behaviourSyncMode: 0
behaviourIDHeapVarName: __refl_const_intnl_udonTypeID
compileErrors: []
hasInteractEvent: 0
Expand Down
36 changes: 36 additions & 0 deletions Assets/UdonSharp/Tests/TestScripts/FlowControl/RecursionTest.cs
Original file line number Diff line number Diff line change
Expand Up @@ -176,6 +176,18 @@ public string CombineStringsNested(int count, string a, string b)
return string.Concat(a, CombineStringsNested(count - 1, CombineStringsNested(count - 1, b, a), CombineStringsNested(count - 1, a, b)), CombineStringsNested(count - 1, CombineStringsNested(count - 1, a, b), CombineStringsNested(count - 1, b, a)), "c");
}

Transform[] GetChildrenTransforms(Transform parent)
{
Transform[] children = new Transform[parent.childCount];

for (int i = 0; i < children.Length; ++i)
{
children[i] = parent.GetChild(i);
}

return children;
}

[RecursiveMethod]
int CountChildren(Transform transformToCount)
{
Expand All @@ -187,6 +199,28 @@ int CountChildren(Transform transformToCount)
return childCount;
}

[RecursiveMethod]
int CountChildrenForeachExpression(Transform transformToCount)
{
int childCount = transformToCount.childCount;

foreach (Transform child in GetChildrenTransforms(transformToCount))
childCount += CountChildrenForeachExpression(child);

return childCount;
}

[RecursiveMethod]
int CountChildrenForeachAccessExpression(Transform transformToCount)
{
int childCount = transformToCount.childCount;

foreach (Transform child in transformToCount.gameObject.transform)
childCount += CountChildrenForeachAccessExpression(child);

return childCount;
}

int externChildCount;

[RecursiveMethod]
Expand Down Expand Up @@ -280,6 +314,8 @@ public void ExecuteTests()
tester.TestAssertion("Nested call recursion", CombineStringsNested(3, "a", "b") == "abaccbcccabccacccccbaccbccccccabccacccbaccbcccccabccaccccccc");

tester.TestAssertion("Count children recursively foreach", CountChildren(transform) == 20);
tester.TestAssertion("Count children recursively foreach expression", CountChildrenForeachExpression(transform) == 20);
tester.TestAssertion("Count children recursively foreach access", CountChildrenForeachAccessExpression(transform) == 20);

externChildCount = 0;
CountChildrenExternalCount(transform);
Expand Down
2 changes: 1 addition & 1 deletion Assets/UdonSharp/version.txt
Original file line number Diff line number Diff line change
@@ -1 +1 @@
v0.19.11
v0.20.0

0 comments on commit 603ae98

Please sign in to comment.