Skip to content
This repository has been archived by the owner on Jan 22, 2022. It is now read-only.

Commit

Permalink
Add scope around switch sections and make array value copies less agg…
Browse files Browse the repository at this point in the history
…ressive

- Also add some places that could potentially be marked as scoped to save heap variables
  • Loading branch information
MerlinVR committed Apr 18, 2020
1 parent 3d2f301 commit 2d6d989
Show file tree
Hide file tree
Showing 2 changed files with 60 additions and 25 deletions.
72 changes: 48 additions & 24 deletions Assets/UdonSharp/Editor/UdonSharpASTVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -972,11 +972,15 @@ public override void VisitAssignmentExpression(AssignmentExpressionSyntax node)
{
UpdateSyntaxNode(node);

//visitorContext.PushTable(new SymbolTable(visitorContext.resolverContext, visitorContext.topTable));

SymbolDefinition rhsValue = null;

using (ExpressionCaptureScope rhsCapture = new ExpressionCaptureScope(visitorContext, null))
{
//visitorContext.PushTable(new SymbolTable(visitorContext.resolverContext, visitorContext.topTable));
Visit(node.Right);
//visitorContext.PopTable();

rhsValue = rhsCapture.ExecuteGet();
}
Expand All @@ -986,6 +990,9 @@ public override void VisitAssignmentExpression(AssignmentExpressionSyntax node)
{
Visit(node.Left);

// Done before anything modifies the state of the lhsCapture which will make this turn false
bool needsCopy = lhsCapture.NeedsArrayCopySet();

if (node.OperatorToken.Kind() == SyntaxKind.SimpleAssignmentExpression || node.OperatorToken.Kind() == SyntaxKind.EqualsToken)
{
lhsCapture.ExecuteSet(rhsValue);
Expand Down Expand Up @@ -1028,22 +1035,30 @@ public override void VisitAssignmentExpression(AssignmentExpressionSyntax node)
using (ExpressionCaptureScope operatorMethodCapture = new ExpressionCaptureScope(visitorContext, null))
{
operatorMethodCapture.SetToMethods(operatorMethods.ToArray());

SymbolDefinition resultSymbol = operatorMethodCapture.Invoke(new SymbolDefinition[] { lhsCapture.ExecuteGet(), rhsValue });

BuiltinOperatorType operatorType = SyntaxKindToBuiltinOperator(node.Kind());

// Create a new set scope to maintain array setter handling for structs
using (ExpressionCaptureScope lhsSetScope = new ExpressionCaptureScope(visitorContext, null))
if (needsCopy)
{
Visit(node.Left);
// Create a new set scope to maintain array setter handling for structs
using (ExpressionCaptureScope lhsSetScope = new ExpressionCaptureScope(visitorContext, null))
{
Visit(node.Left);

// In place arithmetic operators for lower precision types will return int, but C# will normaally cast the result back to the target type
lhsSetScope.ExecuteSet(resultSymbol, true);
// In place arithmetic operators for lower precision types will return int, but C# will normally cast the result back to the target type, so do a force cast here
lhsSetScope.ExecuteSet(resultSymbol, true);
}
}
else
{
// In place arithmetic operators for lower precision types will return int, but C# will normally cast the result back to the target type, so do a force cast here
lhsCapture.ExecuteSet(resultSymbol, true);
}
}
}
}

//visitorContext.PopTable();
}

public override void VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node)
Expand Down Expand Up @@ -1651,14 +1666,18 @@ public override void VisitBinaryExpression(BinaryExpressionSyntax node)

lhsValue = lhsCopy;
}


using (ExpressionCaptureScope rhsCapture = new ExpressionCaptureScope(visitorContext, null))
{
//visitorContext.PushTable(new SymbolTable(visitorContext.resolverContext, visitorContext.topTable));
Visit(node.Right);
//visitorContext.PopTable();

rhsValue = rhsCapture.ExecuteGet();
}


System.Type lhsType = lhsValue.symbolCsType;
System.Type rhsType = rhsValue.symbolCsType;

Expand Down Expand Up @@ -2308,10 +2327,15 @@ public override void VisitSwitchStatement(SwitchStatementSyntax node)
for (int i = 0; i < node.Sections.Count; ++i)
{
visitorContext.uasmBuilder.AddJumpLabel(sectionJumps[i]);

visitorContext.PushTable(new SymbolTable(visitorContext.resolverContext, visitorContext.topTable));

foreach (StatementSyntax statment in node.Sections[i].Statements)
{
Visit(statment);
}

visitorContext.PopTable();
}

visitorContext.uasmBuilder.AddJumpLabel(switchExitLabel);
Expand Down Expand Up @@ -2375,22 +2399,6 @@ public override void VisitGenericName(GenericNameSyntax node)
public override void VisitInvocationExpression(InvocationExpressionSyntax node)
{
UpdateSyntaxNode(node);

List<SymbolDefinition> invocationArgs = new List<SymbolDefinition>();

//visitorContext.PushTable(new SymbolTable(visitorContext.resolverContext, visitorContext.topTable));

foreach (ArgumentSyntax argument in node.ArgumentList.Arguments)
{
using (ExpressionCaptureScope captureScope = new ExpressionCaptureScope(visitorContext, null))
{
Visit(argument.Expression);

invocationArgs.Add(captureScope.ExecuteGet());
}
}

//visitorContext.PopTable();

// Grab the external scope so that the method call can propagate its output upwards
ExpressionCaptureScope externalScope = visitorContext.PopCaptureScope();
Expand All @@ -2404,6 +2412,22 @@ public override void VisitInvocationExpression(InvocationExpressionSyntax node)

if (!methodCaptureScope.IsMethod())
throw new System.Exception("Invocation requires method expression!");

List<SymbolDefinition> invocationArgs = new List<SymbolDefinition>();

//visitorContext.PushTable(new SymbolTable(visitorContext.resolverContext, visitorContext.topTable));

foreach (ArgumentSyntax argument in node.ArgumentList.Arguments)
{
using (ExpressionCaptureScope captureScope = new ExpressionCaptureScope(visitorContext, null))
{
Visit(argument.Expression);

invocationArgs.Add(captureScope.ExecuteGet());
}
}

//visitorContext.PopTable();

SymbolDefinition functionReturnValue = methodCaptureScope.Invoke(invocationArgs.ToArray());

Expand Down
13 changes: 12 additions & 1 deletion Assets/UdonSharp/Editor/UdonSharpExpressionCapture.cs
Original file line number Diff line number Diff line change
Expand Up @@ -465,7 +465,7 @@ public void ExecuteSet(SymbolDefinition value, bool explicitCast = false)
}

// Copy the result back into the array if it's a value type
if (captureArchetype != ExpressionCaptureArchetype.ArrayIndexer && arrayBacktraceSymbol != null && accessSymbol.symbolCsType.IsValueType)
if (NeedsArrayCopySet())
{
using (ExpressionCaptureScope arraySetScope = new ExpressionCaptureScope(visitorContext, null))
{
Expand Down Expand Up @@ -1441,6 +1441,17 @@ public bool IsConstExpression()
return false;
}

/// <summary>
/// Value types need to be copied back to the array if you change a field on them.
/// For instance if you have an array of Vector3, and do vecArray[0].x += 4f;, the vector result needs to be copied back to that index in the array since you're modifying an intermediate copy of it.
/// This function tells you if that copy is necessary.
/// </summary>
/// <returns></returns>
public bool NeedsArrayCopySet()
{
return !IsArrayIndexer() && arrayBacktraceSymbol != null && accessSymbol.symbolCsType.IsValueType;
}

public bool ResolveAccessToken(string accessToken)
{
bool resolvedToken = false;
Expand Down

0 comments on commit 2d6d989

Please sign in to comment.