From 8acf90f9f0f5c5a1abe2e6ec9395e1bd95543e4e Mon Sep 17 00:00:00 2001 From: lights li Date: Wed, 11 Mar 2020 11:41:26 +0800 Subject: [PATCH] Add Type Convert (#196) MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit * this unittest for https://github.com/neo-project/neo-devpack-dotnet/issues/195 * Clean code * 區分push pushNumber pushBoolean pushDataArray 過去合約中所有的數值是統一的Push 小於等於16的數字 和 byte[0] 和 true false 是Integer >16的數字 和 byte[n>0] 是 ByteArray 現在在合約中使用數值將直接得到正確的類型 new byte[0] 是ByteArray true 是Boolean 17 是Integer * 1.修改了unittest null 因爲現在會返回integer類型了,不再是DataArray 2.修改了TypeConvert 應該現在 new byte[0] 直接是ByteArray類型了 * 1.Use Helper.AsByteArray() to convert to ByteArray 2.Use Helper.AsBigInteger() to convert to BigInteger 3.fix unittest * fix one small fault. * add value equal test * Clean code * Clean code * fix format Co-authored-by: Shargon --- src/Neo.Compiler.MSIL/MSIL/Conv_Common.cs | 70 ++++++++++++------- src/Neo.Compiler.MSIL/MSIL/Conv_Multi.cs | 48 ++++++------- src/Neo.Compiler.MSIL/MSIL/Converter.cs | 34 +++++---- src/Neo.SmartContract.Framework/Helper.cs | 37 +++++----- .../Neo.Compiler.MSIL.UnitTests.csproj | 6 ++ .../TestClasses/Contract_TypeConvert.cs | 36 ++++++++++ .../UnitTest_NULL.cs | 11 +-- .../UnitTest_TypeConvert.cs | 37 ++++++++++ .../Services/Neo/ContractTest.cs | 4 +- 9 files changed, 190 insertions(+), 93 deletions(-) create mode 100644 tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_TypeConvert.cs create mode 100644 tests/Neo.Compiler.MSIL.UnitTests/UnitTest_TypeConvert.cs diff --git a/src/Neo.Compiler.MSIL/MSIL/Conv_Common.cs b/src/Neo.Compiler.MSIL/MSIL/Conv_Common.cs index 72641a9a9..77dab5231 100644 --- a/src/Neo.Compiler.MSIL/MSIL/Conv_Common.cs +++ b/src/Neo.Compiler.MSIL/MSIL/Conv_Common.cs @@ -93,9 +93,29 @@ private NeoCode _Convert1by1(VM.OpCode code, OpCode src, NeoMethod to, byte[] da return _code; } - private NeoCode _ConvertPush(byte[] data, OpCode src, NeoMethod to) + private void _ConvertPushNumber(System.Numerics.BigInteger i, OpCode src, NeoMethod to) + { + if (i == 0) _Convert1by1(VM.OpCode.PUSH0, src, to); + else if (i == -1) _Convert1by1(VM.OpCode.PUSHM1, src, to); + else if (i > 0 && i <= 16) _Convert1by1(VM.OpCode.PUSH0 + (byte)i, src, to); + else + { + _ConvertPushDataArray(i.ToByteArray(), src, to); + _Insert1(VM.OpCode.CONVERT, "", to, new byte[1] { (byte)VM.Types.StackItemType.Integer }); + } + } + + private void _ConvertPushBoolean(bool b, OpCode src, NeoMethod to) + { + if (!b) + _Convert1by1(VM.OpCode.PUSH0, src, to); + else + _Convert1by1(VM.OpCode.PUSH1, src, to); + _Insert1(VM.OpCode.CONVERT, "", to, new byte[1] { (byte)VM.Types.StackItemType.Boolean }); + } + + private void _ConvertPushDataArray(byte[] data, OpCode src, NeoMethod to) { - if (data.Length == 0) return _Convert1by1(VM.OpCode.PUSH0, src, to); byte prefixLen; VM.OpCode code; if (data.Length <= byte.MaxValue) @@ -116,15 +136,13 @@ private NeoCode _ConvertPush(byte[] data, OpCode src, NeoMethod to) byte[] bytes = new byte[data.Length + prefixLen]; Buffer.BlockCopy(BitConverter.GetBytes(data.Length), 0, bytes, 0, prefixLen); Buffer.BlockCopy(data, 0, bytes, prefixLen, data.Length); - return _Convert1by1(code, src, to, bytes); + _Convert1by1(code, src, to, bytes); } - private NeoCode _ConvertPush(long i, OpCode src, NeoMethod to) + private void _ConvertPushString(string str, OpCode src, NeoMethod to) { - if (i == 0) return _Convert1by1(VM.OpCode.PUSH0, src, to); - if (i == -1) return _Convert1by1(VM.OpCode.PUSHM1, src, to); - if (i > 0 && i <= 16) return _Convert1by1(VM.OpCode.PUSH0 + (byte)i, src, to); - return _ConvertPush(((BigInteger)i).ToByteArray(), src, to); + var data = Encoding.UTF8.GetBytes(str); + _ConvertPushDataArray(data, src, to); } private int _ConvertPushI8WithConv(ILMethod from, long i, OpCode src, NeoMethod to) @@ -136,14 +154,14 @@ private int _ConvertPushI8WithConv(ILMethod from, long i, OpCode src, NeoMethod { ulong v = (ulong)i; outv = v; - _ConvertPush(outv.ToByteArray(), src, to); + _ConvertPushNumber(outv, src, to); return 1; } else if (code == CodeEx.Conv_U1) { byte v = (byte)i; outv = v; - _ConvertPush(outv.ToByteArray(), src, to); + _ConvertPushNumber(outv, src, to); return 1; } @@ -151,7 +169,7 @@ private int _ConvertPushI8WithConv(ILMethod from, long i, OpCode src, NeoMethod { ushort v = (ushort)i; outv = v; - _ConvertPush(outv.ToByteArray(), src, to); + _ConvertPushNumber(outv, src, to); return 1; } @@ -159,7 +177,7 @@ private int _ConvertPushI8WithConv(ILMethod from, long i, OpCode src, NeoMethod { uint v = (uint)i; outv = v; - _ConvertPush(outv.ToByteArray(), src, to); + _ConvertPushNumber(outv, src, to); return 1; } @@ -171,12 +189,12 @@ private int _ConvertPushI8WithConv(ILMethod from, long i, OpCode src, NeoMethod // Be careful with converting ulong to biginteger ulong v = (ulong)i; outv = v; - _ConvertPush(outv.ToByteArray(), src, to); + _ConvertPushNumber(outv, src, to); return 1; } } - _ConvertPush(i, src, to); + _ConvertPushNumber(i, src, to); return 0; } @@ -190,14 +208,14 @@ private int _ConvertPushI4WithConv(ILMethod from, int i, OpCode src, NeoMethod t { ulong v = (uint)i; outv = v; - _ConvertPush(outv.ToByteArray(), src, to); + _ConvertPushNumber(outv, src, to); return 1; } else if (code == CodeEx.Conv_U1) { byte v = (byte)i; outv = v; - _ConvertPush(outv.ToByteArray(), src, to); + _ConvertPushNumber(outv, src, to); return 1; } @@ -205,7 +223,7 @@ private int _ConvertPushI4WithConv(ILMethod from, int i, OpCode src, NeoMethod t { ushort v = (ushort)i; outv = v; - _ConvertPush(outv.ToByteArray(), src, to); + _ConvertPushNumber(outv, src, to); return 1; } @@ -213,13 +231,13 @@ private int _ConvertPushI4WithConv(ILMethod from, int i, OpCode src, NeoMethod t { uint v = (uint)i; outv = v; - _ConvertPush(outv.ToByteArray(), src, to); + _ConvertPushNumber(outv, src, to); return 1; } else { - _ConvertPush(i, src, to); + _ConvertPushNumber(i, src, to); return 0; } } @@ -247,29 +265,27 @@ private void _insertSharedStaticVarCode(NeoMethod to) if (_src is byte[]) { var bytesrc = (byte[])_src; - _ConvertPush(bytesrc, null, to); + _ConvertPushDataArray(bytesrc, null, to); } else if (_src is int intsrc) { - _ConvertPush(intsrc, null, to); + _ConvertPushNumber(intsrc, null, to); } else if (_src is long longsrc) { - _ConvertPush(longsrc, null, to); + _ConvertPushNumber(longsrc, null, to); } else if (_src is bool bsrc) { - _ConvertPush(bsrc ? 1 : 0, null, to); + _ConvertPushBoolean(bsrc, null, to); } else if (_src is string strsrc) { - var bytesrc = Encoding.UTF8.GetBytes(strsrc); - _ConvertPush(bytesrc, null, to); + _ConvertPushString(strsrc, null, to); } else if (_src is BigInteger bisrc) { - byte[] bytes = bisrc.ToByteArray(); - _ConvertPush(bytes, null, to); + _ConvertPushNumber(bisrc, null, to); } else { diff --git a/src/Neo.Compiler.MSIL/MSIL/Conv_Multi.cs b/src/Neo.Compiler.MSIL/MSIL/Conv_Multi.cs index aacabba70..bc94f5a06 100644 --- a/src/Neo.Compiler.MSIL/MSIL/Conv_Multi.cs +++ b/src/Neo.Compiler.MSIL/MSIL/Conv_Multi.cs @@ -635,7 +635,7 @@ private int _ConvertCall(OpCode src, NeoMethod to) } else if (src.tokenMethod == "System.Char System.String::get_Chars(System.Int32)") { - _ConvertPush(1, src, to); + _ConvertPushNumber(1, src, to); _Convert1by1(VM.OpCode.SUBSTR, null, to); return 0; } @@ -796,16 +796,16 @@ private int _ConvertCall(OpCode src, NeoMethod to) } else if (calltype == 4) { - _ConvertPush(callhash, src, to); + _ConvertPushDataArray(callhash, src, to); _Insert1(VM.OpCode.SYSCALL, "", to, BitConverter.GetBytes(InteropService.Contract.Call)); } else if (calltype == 5) { - var callp = Encoding.UTF8.GetBytes(callname); - _ConvertPush(callp, src, to); + //var callp = Encoding.UTF8.GetBytes(callname); + _ConvertPushString(callname, src, to); // package the arguments into an array - _ConvertPush(pcount + 1, null, to); + _ConvertPushNumber(pcount + 1, null, to); _Convert1by1(VM.OpCode.PACK, null, to); //a syscall @@ -820,7 +820,7 @@ private int _ConvertCall(OpCode src, NeoMethod to) } else if (calltype == 6) { - _ConvertPush(callpcount, src, to); + _ConvertPushNumber(callpcount, src, to); _Convert1by1(VM.OpCode.ROLL, null, to); _Convert1by1(VM.OpCode.SYSCALL, null, to, BitConverter.GetBytes(InteropService.Contract.Call)); } @@ -1078,8 +1078,8 @@ private int _ConvertNewArr(ILMethod method, OpCode src, NeoMethod to) { char info = BitConverter.ToChar(data, i); _Convert1by1(VM.OpCode.DUP, null, to); - _ConvertPush(i / 2, null, to); - _ConvertPush(info, null, to); + _ConvertPushNumber(i / 2, null, to); + _ConvertPushNumber(info, null, to); _Convert1by1(VM.OpCode.SETITEM, null, to); } return 3; @@ -1090,8 +1090,8 @@ private int _ConvertNewArr(ILMethod method, OpCode src, NeoMethod to) { var info = BitConverter.ToUInt32(data, i); _Convert1by1(VM.OpCode.DUP, null, to); - _ConvertPush(i / 4, null, to); - _ConvertPush(info, null, to); + _ConvertPushNumber(i / 4, null, to); + _ConvertPushNumber(info, null, to); _Convert1by1(VM.OpCode.SETITEM, null, to); } return 3; @@ -1102,8 +1102,8 @@ private int _ConvertNewArr(ILMethod method, OpCode src, NeoMethod to) { var info = BitConverter.ToInt32(data, i); _Convert1by1(VM.OpCode.DUP, null, to); - _ConvertPush(i / 4, null, to); - _ConvertPush(info, null, to); + _ConvertPushNumber(i / 4, null, to); + _ConvertPushNumber(info, null, to); _Convert1by1(VM.OpCode.SETITEM, null, to); } return 3; @@ -1114,8 +1114,8 @@ private int _ConvertNewArr(ILMethod method, OpCode src, NeoMethod to) { var info = BitConverter.ToInt64(data, i); _Convert1by1(VM.OpCode.DUP, null, to); - _ConvertPush(i / 8, null, to); - _ConvertPush(info, null, to); + _ConvertPushNumber(i / 8, null, to); + _ConvertPushNumber(info, null, to); _Convert1by1(VM.OpCode.SETITEM, null, to); } return 3; @@ -1126,8 +1126,8 @@ private int _ConvertNewArr(ILMethod method, OpCode src, NeoMethod to) { var info = (System.Numerics.BigInteger)BitConverter.ToUInt64(data, i); _Convert1by1(VM.OpCode.DUP, null, to); - _ConvertPush(i / 8, null, to); - _ConvertPush(info.ToByteArray(), null, to); + _ConvertPushNumber(i / 8, null, to); + _ConvertPushNumber(info, null, to); _Convert1by1(VM.OpCode.SETITEM, null, to); } return 3; @@ -1160,7 +1160,7 @@ private int _ConvertNewArr(ILMethod method, OpCode src, NeoMethod to) // System.Byte or System.SByte var data = method.body_Codes[n2].tokenUnknown as byte[]; - this._ConvertPush(data, src, to); + this._ConvertPushDataArray(data, src, to); return 3; } @@ -1208,7 +1208,7 @@ private int _ConvertNewArr(ILMethod method, OpCode src, NeoMethod to) bool bLdLoc = (_code.code == CodeEx.Ldloc || _code.code == CodeEx.Ldloc_0 || _code.code == CodeEx.Ldloc_1 || _code.code == CodeEx.Ldloc_2 || _code.code == CodeEx.Ldloc_3 || _code.code == CodeEx.Ldloc_S); if (bLdLoc == false)//It means there's no initialization at all { - this._ConvertPush(outbyte, src, to); + this._ConvertPushDataArray(outbyte, src, to); return 0; } while (true) @@ -1237,7 +1237,7 @@ private int _ConvertNewArr(ILMethod method, OpCode src, NeoMethod to) else if (bLdLoc && !bStelem) { //This is not a predictive array initialization, we lost one case for handling - this._ConvertPush(outbyte, src, to); + this._ConvertPushDataArray(outbyte, src, to); // Two cases here if (skip == 1) { @@ -1256,7 +1256,7 @@ private int _ConvertNewArr(ILMethod method, OpCode src, NeoMethod to) } //Sometimes c# will use the real value for initialization. If the value is byte, it may be an error - this._ConvertPush(outbyte, src, to); + this._ConvertPushDataArray(outbyte, src, to); return skip; } } @@ -1266,7 +1266,7 @@ private int _ConvertInitObj(OpCode src, NeoMethod to) { var type = (src.tokenUnknown as Mono.Cecil.TypeReference).Resolve(); _Convert1by1(VM.OpCode.NOP, src, to); - _ConvertPush(type.Fields.Count, null, to); + _ConvertPushNumber(type.Fields.Count, null, to); if (type.IsValueType) { _Insert1(VM.OpCode.NEWSTRUCT, null, to); @@ -1323,7 +1323,7 @@ private int _ConvertNewObj(OpCode src, NeoMethod to) } _Convert1by1(VM.OpCode.NOP, src, to); - _ConvertPush(type.DeclaringType.Fields.Count, null, to); + _ConvertPushNumber(type.DeclaringType.Fields.Count, null, to); if (type.DeclaringType.IsValueType) { _Insert1(VM.OpCode.NEWSTRUCT, null, to); @@ -1345,7 +1345,7 @@ private int _ConvertStfld(ILMethod method, OpCode src, NeoMethod to) //_Convert1by1(VM.OpCode.CLONESTRUCTONLY, src, to); - _ConvertPush(id, null, to);//index + _ConvertPushNumber(id, null, to);//index _Convert1by1(VM.OpCode.SWAP, null, to);//put item top _Convert1by1(VM.OpCode.SETITEM, null, to);//moidfy //item //index //array @@ -1359,7 +1359,7 @@ private int _ConvertLdfld(OpCode src, NeoMethod to) var id = type.Fields.IndexOf(field); if (id < 0) throw new Exception("impossible."); - _ConvertPush(id, src, to); + _ConvertPushNumber(id, src, to); _Convert1by1(VM.OpCode.PICKITEM, null, to); return 0; diff --git a/src/Neo.Compiler.MSIL/MSIL/Converter.cs b/src/Neo.Compiler.MSIL/MSIL/Converter.cs index d8354c83d..be6a342c0 100644 --- a/src/Neo.Compiler.MSIL/MSIL/Converter.cs +++ b/src/Neo.Compiler.MSIL/MSIL/Converter.cs @@ -518,31 +518,31 @@ private int ConvertCode(ILMethod method, OpCode src, NeoMethod to) skipcount = _ConvertPushI4WithConv(method, src.tokenI32, src, to); break; case CodeEx.Ldc_I4_0: - _ConvertPush(0, src, to); + _ConvertPushNumber(0, src, to); break; case CodeEx.Ldc_I4_1: - _ConvertPush(1, src, to); + _ConvertPushNumber(1, src, to); break; case CodeEx.Ldc_I4_2: - _ConvertPush(2, src, to); + _ConvertPushNumber(2, src, to); break; case CodeEx.Ldc_I4_3: - _ConvertPush(3, src, to); + _ConvertPushNumber(3, src, to); break; case CodeEx.Ldc_I4_4: - _ConvertPush(4, src, to); + _ConvertPushNumber(4, src, to); break; case CodeEx.Ldc_I4_5: - _ConvertPush(5, src, to); + _ConvertPushNumber(5, src, to); break; case CodeEx.Ldc_I4_6: - _ConvertPush(6, src, to); + _ConvertPushNumber(6, src, to); break; case CodeEx.Ldc_I4_7: - _ConvertPush(7, src, to); + _ConvertPushNumber(7, src, to); break; case CodeEx.Ldc_I4_8: - _ConvertPush(8, src, to); + _ConvertPushNumber(8, src, to); break; case CodeEx.Ldc_I4_M1: skipcount = _ConvertPushI4WithConv(method, -1, src, to); @@ -551,7 +551,7 @@ private int ConvertCode(ILMethod method, OpCode src, NeoMethod to) skipcount = _ConvertPushI8WithConv(method, src.tokenI64, src, to); break; case CodeEx.Ldstr: - _ConvertPush(Encoding.UTF8.GetBytes(src.tokenStr), src, to); + _ConvertPushString(src.tokenStr, src, to); break; case CodeEx.Stloc_0: _ConvertStLoc(method, src, to, 0); @@ -1035,29 +1035,27 @@ private int ConvertCode(ILMethod method, OpCode src, NeoMethod to) if (_src is byte[]) { var bytesrc = (byte[])_src; - _ConvertPush(bytesrc, src, to); + _ConvertPushDataArray(bytesrc, src, to); } else if (_src is int intsrc) { - _ConvertPush(intsrc, src, to); + _ConvertPushNumber(intsrc, src, to); } else if (_src is long longsrc) { - _ConvertPush(longsrc, src, to); + _ConvertPushNumber(longsrc, src, to); } else if (_src is bool bsrc) { - _ConvertPush(bsrc ? 1 : 0, src, to); + _ConvertPushBoolean(bsrc, src, to); } else if (_src is string strsrc) { - var bytesrc = Encoding.UTF8.GetBytes(strsrc); - _ConvertPush(bytesrc, src, to); + _ConvertPushString(strsrc, src, to); } else if (_src is BigInteger bisrc) { - byte[] bytes = bisrc.ToByteArray(); - _ConvertPush(bytes, src, to); + _ConvertPushNumber(bisrc, src, to); } else { diff --git a/src/Neo.SmartContract.Framework/Helper.cs b/src/Neo.SmartContract.Framework/Helper.cs index 94afa3f26..e3630d53b 100644 --- a/src/Neo.SmartContract.Framework/Helper.cs +++ b/src/Neo.SmartContract.Framework/Helper.cs @@ -5,59 +5,62 @@ namespace Neo.SmartContract.Framework { public static class Helper { + /// + /// StackItemType HEX String + /// + //const string StackItemType_Pointer = "0x10"; + //const string StackItemType_Boolean = "0x20"; + const string StackItemType_Integer = "0x21"; + const string StackItemType_ByteArray = "0x28"; + //const string StackItemType_Buffer = "0x30"; + //const string StackItemType_Array = "0x40"; + //const string StackItemType_Struct = "0x41"; + //const string StackItemType_Map = "0x48"; + //const string StackItemType_InteropInterface = "0x60"; /// /// Converts byte to byte[] considering the byte as a BigInteger (0x00 at the end) /// - [Script] + [OpCode(OpCode.CONVERT, StackItemType_ByteArray)] public extern static byte[] AsByteArray(this byte source); /// /// Converts sbyte to byte[]. /// - [Script] + [OpCode(OpCode.CONVERT, StackItemType_ByteArray)] public extern static byte[] AsByteArray(this sbyte source); /// /// Converts sbyte[] to byte[]. /// - [Script] + [OpCode(OpCode.CONVERT, StackItemType_ByteArray)] public extern static byte[] AsByteArray(this sbyte[] source); /// /// Converts byte[] to sbyte[]. /// - [Script] + [OpCode(OpCode.CONVERT, StackItemType_ByteArray)] public extern static sbyte[] AsSbyteArray(this byte[] source); /// /// Converts byte[] to BigInteger. No guarantees are assumed regarding BigInteger working range. /// Examples: [0x0a] -> 10; [0x80] -> -128; [] -> 0; [0xff00] -> 255 /// - [Script] + [OpCode(OpCode.CONVERT, StackItemType_Integer)] public extern static BigInteger AsBigInteger(this byte[] source); - /// - /// Converts byte[] to BigInteger and ensures output is within BigInteger range (32-bytes) in standard format; faults otherwise. - /// Examples: -128 [0x80ff] -> -128 [0x80]; 0 [0x000000] -> 0 [0x00]; 0 [] -> 0 [0x00]; 255 [0xff00000000000000] -> 255 [0xff00] - /// - [OpCode(OpCode.PUSH0)] - [OpCode(OpCode.ADD)] - public extern static BigInteger ToBigInteger(this byte[] source); - //{ - // return source.AsBigInteger() + 0; - //} + /// /// Converts BigInteger to byte[]. No guarantees are assumed regarding BigInteger working range. /// Examples: 10 -> [0x0a]; 10 -> [0x0a00]; -128 -> [0x80]; -128 -> [0x80ff]; 0 -> []; 0 -> [0x00]; 255 -> [0xff00] /// - [Script] + [OpCode(OpCode.CONVERT, StackItemType_ByteArray)] public extern static byte[] AsByteArray(this BigInteger source); /// /// Converts string to byte[]. Examples: "hello" -> [0x68656c6c6f]; "" -> []; "Neo" -> [0x4e656f] /// - [Script] + [OpCode(OpCode.CONVERT, StackItemType_ByteArray)] public extern static byte[] AsByteArray(this string source); /// diff --git a/tests/Neo.Compiler.MSIL.UnitTests/Neo.Compiler.MSIL.UnitTests.csproj b/tests/Neo.Compiler.MSIL.UnitTests/Neo.Compiler.MSIL.UnitTests.csproj index 53a854964..291748acd 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/Neo.Compiler.MSIL.UnitTests.csproj +++ b/tests/Neo.Compiler.MSIL.UnitTests/Neo.Compiler.MSIL.UnitTests.csproj @@ -29,4 +29,10 @@ + + + Never + + + diff --git a/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_TypeConvert.cs b/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_TypeConvert.cs new file mode 100644 index 000000000..b7ffcc35e --- /dev/null +++ b/tests/Neo.Compiler.MSIL.UnitTests/TestClasses/Contract_TypeConvert.cs @@ -0,0 +1,36 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Numerics; +using Neo.SmartContract.Framework; + +namespace Neo.Compiler.MSIL.UnitTests.TestClasses +{ + class Contract_TypeConvert : SmartContract.Framework.SmartContract + { + public static object testType() + { + BigInteger int0 = 0; + var bts0 = int0.AsByteArray(); + BigInteger int1 = 2; + var bts1 = int1.AsByteArray(); + + var bts2=new byte[1] { 3 }; + var int2 = bts2.AsBigInteger(); + + var bts3 = new byte[0]; + var int3 = bts3.AsBigInteger(); + + var arrobj = new object[8]; + arrobj[0] = int0; + arrobj[1] = bts0; + arrobj[2] = int1; + arrobj[3] = bts1; + arrobj[4] = bts2; + arrobj[5] = int2; + arrobj[6] = bts3; + arrobj[7] = int3; + return arrobj; + } + } +} diff --git a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_NULL.cs b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_NULL.cs index 8fefecaca..2a99c13bf 100644 --- a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_NULL.cs +++ b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_NULL.cs @@ -117,7 +117,7 @@ public void NullCollationAndCollation() }); { var result = _testengine.ExecuteTestCaseStandard("nullCollationAndCollation", "nes"); - var item = result.Pop() as ByteArray; + var item = result.Pop() as Integer; var num = item.ToBigInteger(); Assert.IsTrue(num == 123); } @@ -137,10 +137,11 @@ public void NullCollationAndCollation2() }); { var result = _testengine.ExecuteTestCaseStandard("nullCollationAndCollation2", "nes"); - var item = result.Pop() as ByteArray; - System.ReadOnlySpan data = item; - var num = System.Text.Encoding.ASCII.GetString(data); - Assert.IsTrue(num == "111"); + var item = result.Pop() as Integer; + var bts = System.Text.Encoding.ASCII.GetBytes("111"); + var num = new System.Numerics.BigInteger(bts); + + Assert.IsTrue(item.ToBigInteger() == num); } } [TestMethod] diff --git a/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_TypeConvert.cs b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_TypeConvert.cs new file mode 100644 index 000000000..58f1e67f8 --- /dev/null +++ b/tests/Neo.Compiler.MSIL.UnitTests/UnitTest_TypeConvert.cs @@ -0,0 +1,37 @@ +using Microsoft.VisualStudio.TestTools.UnitTesting; +using Neo.Compiler.MSIL.UnitTests.Utils; +using Neo.VM.Types; +using System.Linq; + +namespace Neo.Compiler.MSIL.UnitTests +{ + [TestClass] + public class UnitTest_TypeConvert + { + [TestMethod] + public void UnitTest_TestTypeConvert() + { + var testengine = new TestEngine(); + testengine.AddEntryScript("./TestClasses/Contract_TypeConvert.cs"); + var result = testengine.ExecuteTestCaseStandard("testType"); + + //test 0,1,2 + Assert.IsTrue(result.TryPop(out Array arr)); + Assert.IsTrue(arr[0].Type == StackItemType.Integer); + Assert.IsTrue(arr[1].Type == StackItemType.ByteArray); + Assert.IsTrue((arr[0] as PrimitiveType).ToBigInteger() == (arr[1] as PrimitiveType).ToBigInteger()); + + Assert.IsTrue(arr[2].Type == StackItemType.Integer); + Assert.IsTrue(arr[3].Type == StackItemType.ByteArray); + Assert.IsTrue((arr[2] as PrimitiveType).ToBigInteger() == (arr[3] as PrimitiveType).ToBigInteger()); + + Assert.IsTrue(arr[4].Type == StackItemType.ByteArray); + Assert.IsTrue(arr[5].Type == StackItemType.Integer); + Assert.IsTrue((arr[4] as PrimitiveType).ToBigInteger() == (arr[5] as PrimitiveType).ToBigInteger()); + + Assert.IsTrue(arr[6].Type == StackItemType.ByteArray); + Assert.IsTrue(arr[7].Type == StackItemType.Integer); + Assert.IsTrue((arr[6] as PrimitiveType).ToBigInteger() == (arr[7] as PrimitiveType).ToBigInteger()); + } + } +} diff --git a/tests/Neo.SmartContract.Framework.UnitTests/Services/Neo/ContractTest.cs b/tests/Neo.SmartContract.Framework.UnitTests/Services/Neo/ContractTest.cs index 59b513be6..6607be5b8 100644 --- a/tests/Neo.SmartContract.Framework.UnitTests/Services/Neo/ContractTest.cs +++ b/tests/Neo.SmartContract.Framework.UnitTests/Services/Neo/ContractTest.cs @@ -55,7 +55,7 @@ public void Test_CreateCallDestroy() Assert.AreEqual(1, result.Count); var item = result.Pop(); - Assert.IsTrue(item.Type == StackItemType.InteropInterface); + Assert.IsTrue(item.Type == VM.Types.StackItemType.InteropInterface); var ledger = (item as InteropInterface).GetInterface(); Assert.AreEqual(manifest.Hash, ledger.ScriptHash); @@ -150,7 +150,7 @@ public void Test_Update() Assert.AreEqual(1, result.Count); var item = result.Pop(); - Assert.IsTrue(item.Type == StackItemType.InteropInterface); + Assert.IsTrue(item.Type == VM.Types.StackItemType.InteropInterface); var ledger = (item as InteropInterface).GetInterface(); Assert.AreEqual(manifest.Hash, ledger.ScriptHash);