Skip to content

Commit

Permalink
fix mapping between C# types and NeoVM types (neo-project#295)
Browse files Browse the repository at this point in the history
fixed neo-project#290

Co-authored-by: lights li <lightsever@hotmail.com>
Co-authored-by: erikzhang <erik@neo.org>
  • Loading branch information
3 people authored and ProDog committed Jun 22, 2020
1 parent 717deaf commit d022639
Show file tree
Hide file tree
Showing 6 changed files with 503 additions and 15 deletions.
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

0 comments on commit d022639

Please sign in to comment.