Skip to content

Commit

Permalink
Fix issues with implicit casts on increment/decrement and switch cond…
Browse files Browse the repository at this point in the history
…itions

- Fix issues with not correctly implicitly casting numeric types correctly in pre and post increment/decrement operators. This meant that low precision types like byte could not be incremented in place.
- Fix switch conditions not performing implicit numeric casts for the correct comparision type. This will later be improved when constant folding is implemented.
  • Loading branch information
MerlinVR committed Apr 19, 2020
1 parent a679eed commit f46d5a0
Show file tree
Hide file tree
Showing 2 changed files with 39 additions and 13 deletions.
47 changes: 34 additions & 13 deletions Assets/UdonSharp/Editor/UdonSharpASTVisitor.cs
Original file line number Diff line number Diff line change
Expand Up @@ -1147,7 +1147,7 @@ public override void VisitPrefixUnaryExpression(PrefixUnaryExpressionSyntax node
{
resultSymbol = operatorMethodCapture.Invoke(new SymbolDefinition[] { operandCapture.ExecuteGet(), valueConstant });

operandCapture.ExecuteSet(resultSymbol);
operandCapture.ExecuteSet(resultSymbol, true);
}
catch (System.Exception)
{
Expand Down Expand Up @@ -1205,7 +1205,7 @@ public override void VisitPostfixUnaryExpression(PostfixUnaryExpressionSyntax no

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

operandCapture.ExecuteSet(resultSymbol);
operandCapture.ExecuteSet(resultSymbol, true);
}
}
catch (System.Exception)
Expand Down Expand Up @@ -2292,22 +2292,43 @@ public override void VisitSwitchStatement(SwitchStatementSyntax node)
visitorContext.uasmBuilder.AddJumpLabel(nextLabelJump);
nextLabelJump = visitorContext.labelTable.GetNewJumpLabel("nextSwitchLabelJump");

SymbolDefinition conditionEqualitySymbol = null;

using (ExpressionCaptureScope conditionValueCapture = new ExpressionCaptureScope(visitorContext, null))
{
Visit(switchLabel);

if (!conditionValueCapture.IsUnknownArchetype())
switchLabelValue = conditionValueCapture.ExecuteGet();
}
using (ExpressionCaptureScope equalityCheckScope = new ExpressionCaptureScope(visitorContext, null))
{
List<MethodInfo> operatorMethods = new List<MethodInfo>();
operatorMethods.AddRange(UdonSharpUtils.GetOperators(switchExpressionSymbol.symbolCsType, BuiltinOperatorType.Equality));
operatorMethods.AddRange(GetImplicitHigherPrecisionOperator(switchExpressionSymbol.symbolCsType, conditionValueCapture.GetReturnType(), BuiltinOperatorType.Equality));

// The condition has a numeric value that needs to be converted for the condition
// This is done on the condition symbol because once constant folding is implemented, this will turn into a nop at runtime
if (visitorContext.resolverContext.FindBestOverloadFunction(operatorMethods.ToArray(), new List<System.Type> { switchExpressionSymbol.symbolCsType, conditionValueCapture.GetReturnType() }) == null &&
UdonSharpUtils.IsNumericExplicitCastValid(conditionValueCapture.GetReturnType(), switchExpressionSymbol.symbolCsType))
{
SymbolDefinition convertedNumericType = visitorContext.topTable.CreateUnnamedSymbol(conditionValueCapture.GetReturnType(), SymbolDeclTypeFlags.Internal);

SymbolDefinition conditionEqualitySymbol = null;
using (ExpressionCaptureScope equalityCheckScope = new ExpressionCaptureScope(visitorContext, null))
{
List<MethodInfo> operatorMethods = new List<MethodInfo>();
operatorMethods.AddRange(UdonSharpUtils.GetOperators(switchExpressionSymbol.symbolCsType, BuiltinOperatorType.Equality));
operatorMethods.AddRange(GetImplicitHigherPrecisionOperator(switchExpressionSymbol.symbolCsType, switchLabelValue.symbolCsType, BuiltinOperatorType.Equality));
equalityCheckScope.SetToMethods(operatorMethods.ToArray());
conditionEqualitySymbol = equalityCheckScope.Invoke(new SymbolDefinition[] { switchExpressionSymbol, switchLabelValue });
using (ExpressionCaptureScope numericConversionScope = new ExpressionCaptureScope(visitorContext, null))
{
numericConversionScope.SetToLocalSymbol(convertedNumericType);
numericConversionScope.ExecuteSetDirect(conditionValueCapture, true);
}

switchLabelValue = convertedNumericType;
operatorMethods.AddRange(UdonSharpUtils.GetOperators(switchLabelValue.symbolCsType, BuiltinOperatorType.Equality));
operatorMethods.AddRange(GetImplicitHigherPrecisionOperator(switchExpressionSymbol.symbolCsType, switchLabelValue.symbolCsType, BuiltinOperatorType.Equality));
}
else
{
switchLabelValue = conditionValueCapture.ExecuteGet();
}

equalityCheckScope.SetToMethods(operatorMethods.ToArray());
conditionEqualitySymbol = equalityCheckScope.Invoke(new SymbolDefinition[] { switchExpressionSymbol, switchLabelValue });
}
}

// Jump past the jump to the section if false
Expand Down
5 changes: 5 additions & 0 deletions Assets/UdonSharp/Editor/UdonSharpUtils.cs
Original file line number Diff line number Diff line change
Expand Up @@ -154,6 +154,11 @@ public static MethodInfo GetNumericConversionMethod(System.Type targetType, Syst
return foundMethods.FirstOrDefault();
}

public static bool IsNumericExplicitCastValid(System.Type targetType, System.Type sourceType)
{
return IsNumericType(sourceType) && GetNumericConversionMethod(targetType, sourceType) != null;
}

public static bool IsImplicitlyAssignableFrom(this System.Type targetType, System.Type assignee)
{
// Normal explicit assign
Expand Down

0 comments on commit f46d5a0

Please sign in to comment.