Skip to content

Commit

Permalink
number operations fixes
Browse files Browse the repository at this point in the history
  • Loading branch information
Xytabich committed Nov 16, 2021
1 parent 2027b3c commit 6169f26
Show file tree
Hide file tree
Showing 5 changed files with 77 additions and 15 deletions.
2 changes: 1 addition & 1 deletion Assets/Katsudon/Builder/Extensions/Udon/CallExtern.cs
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ public bool TryCallMethod(IMethodDescriptor method, MethodInfo methodInfo)
}
else
{
arguments.Add(iterator.Current.Mode(VariableMeta.UsageMode.In | VariableMeta.UsageMode.Out));
arguments.Add(iterator.Current.UseType(methodInfo.DeclaringType).Mode(VariableMeta.UsageMode.In | VariableMeta.UsageMode.Out));
}
index++;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -99,7 +99,7 @@ bool IOperationBuider.Process(IMethodDescriptor method)
}
else
{
arguments.Add(iterator.Current.Mode(VariableMeta.UsageMode.In | VariableMeta.UsageMode.Out));
arguments.Add(iterator.Current.UseType(methodInfo.DeclaringType).Mode(VariableMeta.UsageMode.In | VariableMeta.UsageMode.Out));
}
index++;
}
Expand Down
36 changes: 28 additions & 8 deletions Assets/Katsudon/Builder/Numeric/BitwiseNumberConverter.cs
Original file line number Diff line number Diff line change
Expand Up @@ -54,10 +54,10 @@ public IVariable TryConvert(IUdonProgramBlock block, in IVariable variable, Type
{
IVariable outVariable = null;
var fromType = fromVariable.type;
block.machine.BinaryOperatorExtern(
BinaryOperator.LogicalAnd, fromVariable,
BinaryOperatorExtension.ArithmeticBinaryOperation(
block.machine, BinaryOperator.LogicalAnd, fromVariable,
block.machine.GetConstVariable(Convert.ChangeType(NumberCodeUtils.GetMaxValue(toPrimitive), fromType)),
fromType, () => (outVariable = block.GetTmpVariable(fromType))
(type) => (outVariable = block.GetTmpVariable(type))
);
var converted = block.GetTmpVariable(toType);
block.machine.ConvertExtern(outVariable, converted);
Expand Down Expand Up @@ -89,24 +89,44 @@ public IVariable TryConvert(IUdonProgramBlock block, in IVariable variable, Type
// converted = Convert.To{toType}(value & unsignedBitsConst);
// if((value & fromSignBit) != 0) converted |= toSignBit;

IVariable tmp = block.GetTmpVariable(value.type);
IVariable tmp = block.GetTmpVariable(BinaryOperatorExtension.GetOutputType(value.type));
tmp.Allocate();
value.Allocate();
block.machine.BinaryOperatorExtern(BinaryOperator.LogicalAnd, value, unsignedBitsConst, tmp);
var converted = block.GetTmpVariable(toType);

IVariable converted = block.GetTmpVariable(toType);
converted.Allocate();
block.machine.ConvertExtern(tmp, converted);
if(tmp.type == toType)
{
converted.Allocate();
block.machine.AddCopy(tmp, converted);
}
else
{
block.machine.ConvertExtern(tmp, converted);
}

block.machine.BinaryOperatorExtern(BinaryOperator.LogicalAnd, value, fromSignBit, tmp);
var condition = block.GetTmpVariable(typeof(bool));
block.machine.BinaryOperatorExtern(
BinaryOperator.Inequality, tmp,
block.machine.GetConstVariable(Convert.ChangeType(0, value.type)),
block.machine.GetConstVariable(Convert.ChangeType(0, tmp.type)),
condition
);

var exitLabel = new EmbedAddressLabel();
block.machine.AddBranch(condition, exitLabel);
block.machine.BinaryOperatorExtern(BinaryOperator.LogicalOr, converted, toSignBit, converted);
var outType = BinaryOperatorExtension.GetOutputType(toType);
if(outType != toType)
{
tmp = block.GetTmpVariable(outType);
block.machine.BinaryOperatorExtern(BinaryOperator.LogicalOr, converted, toSignBit, tmp);
block.machine.ConvertExtern(tmp, converted);
}
else
{
block.machine.BinaryOperatorExtern(BinaryOperator.LogicalOr, converted, toSignBit, converted);
}
block.machine.ApplyLabel(exitLabel);

return converted;
Expand Down
50 changes: 46 additions & 4 deletions Assets/Katsudon/Builder/UdonMachine/Extern/BinaryOperatorExtern.cs
Original file line number Diff line number Diff line change
Expand Up @@ -7,6 +7,12 @@ public static class BinaryOperatorExtension
public static void BinaryOperatorExtern(this IUdonMachine machine, BinaryOperator type,
IVariable leftVariable, IVariable rightVariable, IVariable outVariable)
{
#if KATSUDON_DEBUG
if(outVariable.type != typeof(bool) && NumberCodeUtils.GetSize(NumberCodeUtils.GetCode(outVariable.type)) < sizeof(int))
{
throw new Exception("Invalid output type: " + outVariable.type);
}
#endif
machine.AddExtern(
GetExternName(type, leftVariable.type, rightVariable.type, outVariable.type),
outVariable,
Expand All @@ -18,6 +24,12 @@ public static class BinaryOperatorExtension
public static void BinaryOperatorExtern(this IUdonMachine machine, BinaryOperator type,
IVariable leftVariable, IVariable rightVariable, Type outType, Func<IVariable> outVariableCtor)
{
#if KATSUDON_DEBUG
if(outType != typeof(bool) && NumberCodeUtils.GetSize(NumberCodeUtils.GetCode(outType)) < sizeof(int))
{
throw new Exception("Invalid output type: " + outType);
}
#endif
machine.AddExtern(
GetExternName(type, leftVariable.type, rightVariable.type, outType),
outVariableCtor,
Expand All @@ -29,6 +41,12 @@ public static class BinaryOperatorExtension
public static void BinaryOperatorExtern(this IUdonMachine machine, BinaryOperator type,
VariableMeta leftVariable, VariableMeta rightVariable, Type outType, Func<IVariable> outVariableCtor)
{
#if KATSUDON_DEBUG
if(outType != typeof(bool) && NumberCodeUtils.GetSize(NumberCodeUtils.GetCode(outType)) < sizeof(int))
{
throw new Exception("Invalid output type: " + outType);
}
#endif
machine.AddExtern(
GetExternName(type, leftVariable.preferredType, rightVariable.preferredType, outType),
outVariableCtor,
Expand Down Expand Up @@ -74,6 +92,16 @@ public static class BinaryOperatorExtension
}
}

public static void ArithmeticBinaryOperation(IUdonMachine machine, BinaryOperator operationType, IVariable a, IVariable b, Func<Type, IVariable> outVariableCtor)
{
var code = Type.GetTypeCode(a.type);
if(code != Type.GetTypeCode(b.type)) throw new Exception("The input data types do not match");

Type type, outputType = type = NumberCodeUtils.ToType(code);
if(NumberCodeUtils.GetSize(code) < sizeof(int)) outputType = typeof(int);
machine.BinaryOperatorExtern(operationType, a.UseType(type), b.UseType(type), outputType, () => outVariableCtor(outputType));
}

public static void ShiftBinaryOperation(IMethodDescriptor method, Func<object, int, TypeCode, object> constCtor,
BinaryOperator operationType, bool? unsigned, IVariable a, IVariable b)
{
Expand All @@ -91,13 +119,21 @@ public static class BinaryOperatorExtension
}
else
{
var code = Type.GetTypeCode(a.type);
var type = NumberCodeUtils.ToType(code);
if(NumberCodeUtils.GetSize(code) < sizeof(int)) type = typeof(int);
method.machine.BinaryOperatorExtern(operationType, a.UseType(type), b.UseType(typeof(int)), type, () => method.GetOrPushOutVariable(type));
ShiftBinaryOperation(method.machine, operationType, a, b, (type) => method.GetOrPushOutVariable(type));
}
}

public static void ShiftBinaryOperation(IUdonMachine machine, BinaryOperator operationType, IVariable a, IVariable b, Func<Type, IVariable> outVariableCtor)
{
var code = Type.GetTypeCode(a.type);
Type type = NumberCodeUtils.ToType(code);
Type outputType = type;
Type offsetType = type;
if(NumberCodeUtils.GetSize(code) < sizeof(int)) outputType = typeof(int);
if(NumberCodeUtils.GetSize(code) >= sizeof(int)) offsetType = typeof(int);// why..?
machine.BinaryOperatorExtern(operationType, a.UseType(type), b.UseType(offsetType), outputType, () => outVariableCtor(outputType));
}

public static void LogicBinaryOperation(IMethodDescriptor method, Func<object, object, TypeCode, bool> constCtor,
BinaryOperator operationType, bool? unsigned, IVariable a, IVariable b, Func<IVariable> retVariableCtor, out IVariable constVariable)
{
Expand Down Expand Up @@ -144,6 +180,12 @@ public static string GetExternName(BinaryOperator type, Type leftType, Type righ
return Utils.GetExternName(leftType, "__op_" + type + "__{0}_{1}__{2}", leftType, rightType, outType);
}

public static Type GetOutputType(Type reference)
{
var code = Type.GetTypeCode(reference);
return NumberCodeUtils.ToType(NumberCodeUtils.GetSize(code) < sizeof(int) ? TypeCode.Int32 : code);
}

private static object GetTypedNumberValue(object value, TypeCode valueCode, bool real, bool unsigned)
{
if(real) return Convert.ToDouble(value);
Expand Down
2 changes: 1 addition & 1 deletion Assets/Katsudon/Builder/UdonMachine/UdonProgramBlock.cs
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ public void AddCopy(IVariable fromVariable, IVariable toVariable)
{
fromVariable.Allocate();
toVariable.Allocate();
AddPush(fromVariable.Mode(VariableMeta.UsageMode.In));
AddPush(fromVariable.UseType(toVariable.type).Mode(VariableMeta.UsageMode.In));
AddPush(toVariable.Mode(VariableMeta.UsageMode.Out));
fromVariable.Use();
toVariable.Use();
Expand Down

0 comments on commit 6169f26

Please sign in to comment.