Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

fix mapping between C# types and NeoVM types #295

Merged
merged 12 commits into from
Jun 17, 2020
57 changes: 42 additions & 15 deletions src/Neo.Compiler.MSIL/MSIL/Conv_Multi.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,23 +41,33 @@ private void ConvertLdLoc(OpCode src, NeoMethod to, int pos)
private void ConvertLdLocA(ILMethod method, OpCode src, NeoMethod to, int pos)
{
// There are two cases, and we need to figure out what the reference address is for
var n1 = method.body_Codes[method.GetNextCodeAddr(src.addr)];
var n2 = method.body_Codes[method.GetNextCodeAddr(n1.addr)];

if (n1.code == CodeEx.Initobj)// Initializes the structure and must give the reference address
var next = method.body_Codes[method.GetNextCodeAddr(src.addr)];
while (next != null)
{
//some initobj, need setloc after initobj.save slot first.
ldloca_slot = pos;
}
else if (n2.code == CodeEx.Call && n2.tokenMethod.Is_ctor())
{
//some ctor,need setloc after ctor.save slot first.
ldloca_slot = pos;
}
else
{
ConvertLdLoc(src, to, pos);
if (next.code == CodeEx.Initobj)
{
ldloca_slot = pos;
return;
}
else if (next.code == CodeEx.Call && next.tokenMethod.Is_ctor())
{
//some ctor,need setloc after ctor.save slot first.
ldloca_slot = pos;
return;
}
else if (next.code.ToString().IndexOf("Ld") == 0)//可以是各種Ld
{
next = method.body_Codes[method.GetNextCodeAddr(next.addr)];
continue;
}
else
{
break;
}
}
ConvertLdLoc(src, to, pos);

}

private void ConvertCastclass(OpCode src, NeoMethod to)
Expand Down Expand Up @@ -671,6 +681,20 @@ private int ConvertCall(OpCode src, NeoMethod to)
ldloca_slot = -1;
return 0;
}
else if (src.tokenMethod.IndexOf("System.Void System.ValueTuple`") == 0)
{
var _type = (src.tokenUnknown as Mono.Cecil.MethodReference);
var type = _type.Resolve();
var count = type.DeclaringType.GenericParameters.Count;
ConvertPushNumber(count, src, to);
//ConvertPushI4WithConv(from, count, src, to);
Insert1(VM.OpCode.PACK, null, to);
Insert1(VM.OpCode.DUP, null, to);
Insert1(VM.OpCode.REVERSEITEMS, null, to);
ConvertStLoc(src, to, ldloca_slot);
ldloca_slot = -1;
return 0;
}
else if (src.tokenMethod.Contains("::op_LeftShift("))
{
Convert1by1(VM.OpCode.SHL, src, to);
Expand Down Expand Up @@ -1373,8 +1397,11 @@ private int ConvertNewObj(ILMethod from, OpCode src, NeoMethod to)
}
return 0;
}
else if (_type.DeclaringType.FullName == "System.Decimal")
{
throw new Exception("unsupported type:System.Decimal.");
}
var type = _type.Resolve();

// Replace the New Array operation if there is an [OpCode] on the constructor
foreach (var m in type.DeclaringType.Methods)
{
Expand Down
81 changes: 81 additions & 0 deletions tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_Types.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,81 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Numerics;
using System.Runtime.CompilerServices;

namespace Neo.Compiler.MSIL.UnitTests.TestClasses
{
class Contract_Types : SmartContract.Framework.SmartContract
{
public enum EDummy : byte
{
test = 5
}

public delegate EDummy enumDel();
public delegate void del(string msg);
public static event del dummyEvent;

public class DummyClass
{
public string Value;
}

public struct DummyStruct
{
public string Value;
}

public static object checkNull() { return null; }
public static bool checkBoolTrue() { return true; }
public static bool checkBoolFalse() { return false; }
public static sbyte checkSbyte() { return (sbyte)5; }
public static byte checkByte() { return (byte)5; }
public static short checkShort() { return (short)5; }
public static ushort checkUshort() { return (ushort)5; }
public static int checkInt() { return (int)5; }
public static uint checkUint() { return (uint)5; }
public static long checkLong() { return (long)5; }
public static ulong checkUlong() { return (ulong)5; }
public static char checkChar() { return 'n'; }
public static string checkString() { return "neo"; }
public static object[] checkArrayObj() { return new object[] { "neo" }; }
public static BigInteger checkBigInteger() { return (BigInteger)5; }
public static byte[] checkByteArray() { return new byte[] { 1, 2, 3 }; }
public static EDummy checkEnum() { return EDummy.test; }
public static enumDel checkDelegate()
{
return new enumDel(checkEnum);
}
public static Func<EDummy> checkLambda()
{
return checkEnum;
}
public static void checkEvent()
{
dummyEvent("neo");
}
public static DummyClass checkClass()
{
var ret = new DummyClass();
ret.Value = "neo";
return ret;
}
public static DummyStruct checkStruct()
{
var ret = new DummyStruct();
ret.Value = "neo";
return ret;
}
public static (string value1, string value2) checkTuple()
{
return ("neo", "smart economy");
}
public static (string value1, string value2) checkTuple2()
{
var tuple = ("neo", "smart economy");
return tuple;
}
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Numerics;
using System.Runtime.CompilerServices;

namespace Neo.Compiler.MSIL.UnitTests.TestClasses
{
class Contract_Types_Decimal : SmartContract.Framework.SmartContract
{
public static Decimal checkDecimal() { return 0.1M; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Numerics;
using System.Runtime.CompilerServices;

namespace Neo.Compiler.MSIL.UnitTests.TestClasses
{
class Contract_Types_Double : SmartContract.Framework.SmartContract
{
public static double checkDouble() { return 0.1D; }
}
}
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
using System;
using System.Collections.Generic;
using System.Text;
using System.Numerics;
using System.Runtime.CompilerServices;

namespace Neo.Compiler.MSIL.UnitTests.TestClasses
{
class Contract_Types_Float : SmartContract.Framework.SmartContract
{
public static float checkFloat() { return 0.1F; }
}
}
Loading