diff --git a/JSIL/ILBlockTranslator.cs b/JSIL/ILBlockTranslator.cs index a93fc3b4b..2da7af1b9 100644 --- a/JSIL/ILBlockTranslator.cs +++ b/JSIL/ILBlockTranslator.cs @@ -547,6 +547,23 @@ protected JSExpression Translate_BinaryOp (ILExpression node, JSBinaryOperator o AutoCastingState.Pop(); } + if (node.Code.GetName().Contains(".un")) + { + var lType = lhs.GetActualType(TypeSystem); + var lUnsigned = TypeUtil.GetUnsignedType(lType, TypeSystem); + if (lType != lUnsigned) + { + lhs = JSCastExpression.New(lhs, lUnsigned, TypeSystem, isCoercion: true); + } + + var rType = rhs.GetActualType(TypeSystem); + var rUnsigned = TypeUtil.GetUnsignedType(rType, TypeSystem); + if (lType != rUnsigned) + { + rhs = JSCastExpression.New(rhs, rUnsigned, TypeSystem, isCoercion: true); + } + } + if (TypeUtil.IsPointer(lhs.GetActualType(TypeSystem))) arePointersInvolved |= true; else if (TypeUtil.IsPointer(rhs.GetActualType(TypeSystem))) diff --git a/JSIL/TypeUtil.cs b/JSIL/TypeUtil.cs index 65d43a67e..eea595b10 100644 --- a/JSIL/TypeUtil.cs +++ b/JSIL/TypeUtil.cs @@ -163,6 +163,40 @@ public static bool IsNumeric (TypeReference type) { } } + public static TypeReference GetUnsignedType(TypeReference type, TypeSystem typeSystem) + { + type = DereferenceType(type); + + switch (type.MetadataType) + { + case MetadataType.UIntPtr: + case MetadataType.IntPtr: + return typeSystem.UIntPtr; + + case MetadataType.SByte: + case MetadataType.Byte: + return typeSystem.Byte; + + case MetadataType.Int16: + case MetadataType.UInt16: + return typeSystem.UInt16; + + case MetadataType.Int32: + case MetadataType.UInt32: + return typeSystem.UInt32; + + case MetadataType.Int64: + case MetadataType.UInt64: + return typeSystem.UInt64; + + case MetadataType.Char: + return typeSystem.Char; + + default: + return type; + } + } + public static bool? IsSigned (TypeReference type) { type = DereferenceType(type); diff --git a/Tests/SimpleTestCases/ble.un.il b/Tests/SimpleTestCases/ble.un.il new file mode 100644 index 000000000..27cdccc4e --- /dev/null +++ b/Tests/SimpleTestCases/ble.un.il @@ -0,0 +1,27 @@ +.assembly Hello {} +.assembly extern mscorlib {} + +.class public abstract sealed Program + extends [mscorlib]System.Object +{ + .method static void Main() + { + .entrypoint + .maxstack 1 + + ldc.i4 -1 + ldc.i4.5 + ble.un.s END + ldstr "int32" + call void [mscorlib]System.Console::WriteLine(string) + + ldc.i8 -1 + ldc.i8 5 + ble.un.s END + ldstr "int64" + call void [mscorlib]System.Console::WriteLine(string) + + END: + ret + } +} \ No newline at end of file diff --git a/Tests/SimpleTests.csproj b/Tests/SimpleTests.csproj index fe2112c10..c56b4840a 100644 --- a/Tests/SimpleTests.csproj +++ b/Tests/SimpleTests.csproj @@ -66,6 +66,7 @@ +