Skip to content

Commit

Permalink
added implicit literal substitution so you can compare int and ulong …
Browse files Browse the repository at this point in the history
…for example
  • Loading branch information
AqlaSolutions committed Dec 31, 2020
1 parent 2cd9295 commit edab1d0
Show file tree
Hide file tree
Showing 8 changed files with 769 additions and 660 deletions.
4 changes: 2 additions & 2 deletions RunSharp.TestsShared/Infrastructure/PEVerify.cs
Original file line number Diff line number Diff line change
Expand Up @@ -38,9 +38,9 @@ public static class PEVerify
public static void AssertValid(string path)
{
#if NET5_0
var references = Assembly.LoadFile(path).GetReferencedAssemblies().Select(x => x.CodeBase).Where(x => x != null).ToArray();
var references = Assembly.LoadFile(Path.GetFullPath(path)).GetReferencedAssemblies().Select(x => x.CodeBase).Where(x => x != null).ToArray();
var errors = new ILVerify.ILVerify(path, references).Run().ToList();
Assert.IsEmpty(errors);
Assert.IsEmpty(errors, "Checking "+ path);
return;
#endif
string sdkRootPath = Environment.GetEnvironmentVariable(!Environment.Is64BitOperatingSystem ? "ProgramFiles" : "ProgramFiles(x86)");
Expand Down
18 changes: 18 additions & 0 deletions RunSharp.TestsShared/Tests/TestNullable.cs
Original file line number Diff line number Diff line change
Expand Up @@ -319,5 +319,23 @@ public static void ExecuteBoxNull(MethodGen m)
g.Assign(boxed, nullable);
g.ThrowAssert(boxed == null, "null");
}


[Test]
public void IncrementNullableNonInt()
{
TestingFacade.RunMethodTest(ExecuteIncrementNullableNonInt);
}

public static void ExecuteIncrementNullableNonInt(MethodGen mg)
{
var g = mg.GetCode();
var nullable = g.Local(typeof(ulong?));
g.Assign(nullable, (ulong)0);
g.Increment(nullable);
g.ThrowAssert(nullable == 1);


}
}
}
5 changes: 5 additions & 0 deletions RunSharpShared/Aqla/ContextualOperand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -409,6 +409,11 @@ public ContextualOperand InvokeGetHashCode()
return OperandExtensions.SetLeakedState(new ContextualOperand(base.LongArrayLength(), TypeMapper), true);
}

public new Operand ValueFromNullable()
{
return UnwrapNullableValue(TypeMapper);
}

public new ContextualOperand Ref()
{
return new ContextualOperand(base.Ref(), TypeMapper);
Expand Down
29 changes: 28 additions & 1 deletion RunSharpShared/CodeGen.Helpers.cs
Original file line number Diff line number Diff line change
Expand Up @@ -401,12 +401,39 @@ protected internal void EmitGetHelper(Operand op, Type desiredType, bool allowEx

internal void EmitGetHelper(Operand op, Type desiredType, Conversion conv, Type from = null)
{
if (desiredType.IsPrimitive && op.ConstantValue != null)
{
var opType = op.GetReturnType(TypeMapper);
if (opType.IsPrimitive && opType != desiredType)
{
// hot swap literals
var c = op.ConstantValue;

object converted = null;
try
{
converted = Convert.ChangeType(c, System.Type.GetType(desiredType.FullName));
}
catch
{
}

if (converted != null)
{
Operand.FromObject(converted).EmitGet(this);
return;
}
}

}


if (conv == null)
{
EmitGetHelper(op, desiredType, false);
return;
}

EmitGetHelper_Conversion(op, desiredType.IsByRef ? desiredType.GetElementType() : desiredType, conv, from);
if (desiredType.IsByRef)
EmitGetHelper_Ref(op, desiredType);
Expand Down
6 changes: 3 additions & 3 deletions RunSharpShared/CodeGen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -361,7 +361,7 @@ protected internal override void EmitAddressOf(CodeGen g)
protected internal override bool TrivialAccess => true;
}

internal class _Local : Operand
public class _Local : Operand
{
protected override bool DetectsLeaking => false;

Expand All @@ -370,12 +370,12 @@ internal class _Local : Operand
readonly Block _scope;
Type _t, _tHint;

public _Local(CodeGen owner)
internal _Local(CodeGen owner)
{
_owner = owner;
_scope = owner.GetBlockForVariable();
}
public _Local(CodeGen owner, Type t)
internal _Local(CodeGen owner, Type t)
{
_owner = owner; _t = t;
_scope = owner.GetBlockForVariable();
Expand Down
28 changes: 19 additions & 9 deletions RunSharpShared/Operand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -67,6 +67,8 @@ protected void EmitGetHelper(CodeGen g, Operand op, Type desiredType, bool allow

protected internal static readonly Operand[] EmptyArray = { };

public void _ManualEmitGet(CodeGen g) => EmitGet(g);

#region Virtual methods
protected internal virtual void EmitGet(CodeGen g)
{
Expand Down Expand Up @@ -789,6 +791,14 @@ public Operand LongArrayLength()
{
return OperandExtensions.SetLeakedState(new ArrayLength(this, true), true);
}

public Operand UnwrapNullableValue(ITypeMapper typeMapper)
{
Type t = Helpers.GetNullableUnderlyingType(GetReturnType(typeMapper));
if (t == null) return this;
return Cast(t);
}

#endregion

public Operand Ref()
Expand Down Expand Up @@ -880,15 +890,15 @@ protected internal bool LeakedState
}
}

/// <summary>
/// Set not leaked for this and *all used operands recursively*. Returns itself.
/// </summary>
/// <remarks>Usage: <br/>
/// <code>
/// var asStream = ag.ExpressionFactory.New(typeof(MemoryStream)).Cast(typeof(Stream)).SetNotLeaked(false)();
/// </code>
/// </remarks>
public Operand SetNotLeaked()
/// <summary>
/// Set not leaked for this and *all used operands recursively*. Returns itself.
/// </summary>
/// <remarks>Usage: <br/>
/// <code>
/// var asStream = ag.ExpressionFactory.New(typeof(MemoryStream)).Cast(typeof(Stream)).SetNotLeaked(false)();
/// </code>
/// </remarks>
public Operand SetNotLeaked()
{
LeakedState = false;
return this;
Expand Down
37 changes: 32 additions & 5 deletions RunSharpShared/Operands/OverloadableOperation.cs
Original file line number Diff line number Diff line change
Expand Up @@ -178,17 +178,44 @@ void PrepareAf(ITypeMapper typeMapper)
return;
}
else if (_operands.Length == 1)
{
// convert increment/decrement to binary operators
if (_op.OpCode == OpCodes.Add)
{
// choose type for "1"
Operand second;
var t = _operands[0].GetReturnType(typeMapper);
var inner = Helpers.GetNullableUnderlyingType(t);
t = inner ?? t;
if (t.FullName == typeof(int).FullName)
second = (int) 1;
else if (t.FullName == typeof(long).FullName)
second = (long) 1;
else if (t.FullName == typeof(ulong).FullName)
second = (ulong)1;
else if (t.FullName == typeof(uint).FullName)
second = (uint)1;
else if (t.FullName == typeof(short).FullName)
second = (short)1;
else if (t.FullName == typeof(ushort).FullName)
second = (ushort)1;
else if (t.FullName == typeof(double).FullName)
second = (double)1;
else if (t.FullName == typeof(decimal).FullName)
second = (decimal)1;
else if (t.FullName == typeof(byte).FullName)
second = (byte)1;
else if (t.FullName == typeof(sbyte).FullName)
second = (sbyte) 1;
else throw new InvalidOperationException("Can't apply increment on type " + t);

// convert increment/decrement to binary operators
if (_op.OpCode == OpCodes.Add)
{
_afInterceptor = _operands[0] + 1;
_afInterceptor = _operands[0] + second;
_returnType = _afInterceptor.GetReturnType(typeMapper);
return;
}
if (_op.OpCode == OpCodes.Sub)
{
_afInterceptor = _operands[0] - 1;
_afInterceptor = _operands[0] - second;
_returnType = _afInterceptor.GetReturnType(typeMapper);
return;
}
Expand Down
Loading

0 comments on commit edab1d0

Please sign in to comment.