diff --git a/src/Neo.Compiler.CSharp/MethodConvert/Expression/AssignmentExpression.ComplexAssignment.cs b/src/Neo.Compiler.CSharp/MethodConvert/Expression/AssignmentExpression.ComplexAssignment.cs index 22a4d7b86..5d3521f10 100644 --- a/src/Neo.Compiler.CSharp/MethodConvert/Expression/AssignmentExpression.ComplexAssignment.cs +++ b/src/Neo.Compiler.CSharp/MethodConvert/Expression/AssignmentExpression.ComplexAssignment.cs @@ -270,12 +270,15 @@ private void EmitComplexAssignmentOperator(ITypeSymbol type, SyntaxToken operato "%=" => (OpCode.MOD, true), "&=" => isBoolean ? (OpCode.BOOLAND, false) : (OpCode.AND, true), "^=" when !isBoolean => (OpCode.XOR, true), + "^=" when isBoolean => (OpCode.XOR, false), "|=" => isBoolean ? (OpCode.BOOLOR, false) : (OpCode.OR, true), "<<=" => (OpCode.SHL, true), ">>=" => (OpCode.SHR, true), _ => throw new CompilationException(operatorToken, DiagnosticId.SyntaxNotSupported, $"Unsupported operator: {operatorToken}") }; AddInstruction(opcode); + if (opcode == OpCode.XOR && isBoolean) + ChangeType(VM.Types.StackItemType.Boolean); if (isString) ChangeType(VM.Types.StackItemType.ByteString); if (checkResult) EnsureIntegerInRange(type); } diff --git a/src/Neo.Compiler.CSharp/MethodConvert/Expression/Expression.cs b/src/Neo.Compiler.CSharp/MethodConvert/Expression/Expression.cs index d06badb61..f4819a790 100644 --- a/src/Neo.Compiler.CSharp/MethodConvert/Expression/Expression.cs +++ b/src/Neo.Compiler.CSharp/MethodConvert/Expression/Expression.cs @@ -265,6 +265,9 @@ private static byte[] ConvertToECPoint(string strValue) private void EnsureIntegerInRange(ITypeSymbol type) { if (type.Name == "BigInteger") return; + while (type.NullableAnnotation == NullableAnnotation.Annotated) + // Supporting nullable integer like `byte?` + type = ((INamedTypeSymbol)type).TypeArguments.First(); var (minValue, maxValue, mask) = type.Name switch { "SByte" => ((BigInteger)sbyte.MinValue, (BigInteger)sbyte.MaxValue, (BigInteger)0xff), @@ -276,6 +279,7 @@ private void EnsureIntegerInRange(ITypeSymbol type) "UInt16" => (ushort.MinValue, ushort.MaxValue, 0xffff), "UInt32" => (uint.MinValue, uint.MaxValue, 0xffffffff), "UInt64" => (ulong.MinValue, ulong.MaxValue, 0xffffffffffffffff), + //"Boolean" => (0, 1, 0x01), _ => throw new CompilationException(DiagnosticId.SyntaxNotSupported, $"Unsupported type: {type}") }; JumpTarget checkUpperBoundTarget = new(), adjustTarget = new(), endTarget = new(); diff --git a/tests/Neo.Compiler.CSharp.TestContracts/Contract_MemberAccess.cs b/tests/Neo.Compiler.CSharp.TestContracts/Contract_MemberAccess.cs index 167f9b3ec..de11d693c 100644 --- a/tests/Neo.Compiler.CSharp.TestContracts/Contract_MemberAccess.cs +++ b/tests/Neo.Compiler.CSharp.TestContracts/Contract_MemberAccess.cs @@ -13,24 +13,51 @@ public static void TestMain() //Runtime.Log(MyClass.Data3.ToString()); Runtime.Log(my.Data4); Runtime.Log(my.Method()); + } + + public static void TestComplexAssignment() + { + var my = new MyClass(); + ExecutionEngine.Assert(my.PropertyComplexAssignment() == -1); + ExecutionEngine.Assert((my.Data1 /= -1) == 1); + ExecutionEngine.Assert(my.FieldComplexAssignment() == 0); + ExecutionEngine.Assert(my.FieldComplexAssignmentString() == "hello2"); + ExecutionEngine.Assert((my.Data4 += "33") == "hello233"); + } + public static void TestStaticComplexAssignment() + { MyClass.Data3 = 0; ExecutionEngine.Assert(MyClass.Data3 == 0); MyClass.Data3 += 1; ExecutionEngine.Assert(MyClass.Data3 == 1); + + ExecutionEngine.Assert(MyClass.Data6 == false); + MyClass.Data6 |= true; + ExecutionEngine.Assert(MyClass.Data6 == true); + MyClass.Data6 ^= true; + ExecutionEngine.Assert(MyClass.Data6 == false); } public class MyClass { - public int Data1 { get; set; } + public int Data1 { get; set; } // non-static IPropertySymbol public const string Data2 = "msg"; - public static int Data3 = 3; + public static int Data3 = 3; // static IFieldSymbol + + public string Data4 = "hello"; // non-static IFieldSymbol - public string Data4 = "hello"; + public int Data5 = 5; // non-static IFieldSymbol + + public static bool Data6 { get; set; } = false; // static IPropertySymbol public string Method() => ""; + + public int PropertyComplexAssignment() => Data1 -= 1; + public int FieldComplexAssignment() => Data5 ^= Data5; + public string FieldComplexAssignmentString() => Data4 += "2"; } } } diff --git a/tests/Neo.Compiler.CSharp.TestContracts/Contract_NULL.cs b/tests/Neo.Compiler.CSharp.TestContracts/Contract_NULL.cs index f9cc8654b..8e127a7a6 100644 --- a/tests/Neo.Compiler.CSharp.TestContracts/Contract_NULL.cs +++ b/tests/Neo.Compiler.CSharp.TestContracts/Contract_NULL.cs @@ -96,8 +96,13 @@ public void VoidMethod() { } public int IntProperty => 42; - public byte? NullableProperty; + public byte? NullableField; public byte?[]? NullableArray { get; set; } + public static bool? StaticNullableField = true; + public static int? StaticNullableProperty { get; set; } = 0; + + public byte? FieldCoalesce(byte? f) => NullableField ??= f; + public byte?[]? PropertyCoalesce(byte?[]? p) => NullableArray ??= p; } public static void NullType() @@ -106,21 +111,44 @@ public static void NullType() obj1?.VoidMethod(); } - public static void NullCoalescingAssignment() + public static void NullCoalescingAssignment(byte? nullableArg) { - TestClass t = new() { NullableProperty = 1 }; - ExecutionEngine.Assert(t.NullableProperty == 1); - t.NullableProperty = null; + nullableArg ??= 1; + TestClass t = new() { NullableField = nullableArg }; + ExecutionEngine.Assert(t.NullableField == 1); + t.NullableField = null; ExecutionEngine.Assert(t.NullableArray == null); - t.NullableArray ??= [0, null, 2, 3, t.NullableProperty]; - t.NullableProperty ??= t.NullableArray[0]; - ExecutionEngine.Assert(t.NullableProperty == 0); - t.NullableProperty ??= t.NullableArray[1]; - ExecutionEngine.Assert(t.NullableProperty == 0); + t.NullableArray ??= [0, null, 2, 3, t.NullableField]; + t.PropertyCoalesce([null]); + t.FieldCoalesce(t.NullableArray![0]); + ExecutionEngine.Assert(t.NullableField == 0); + t.NullableField ??= t.NullableArray[1]; + ExecutionEngine.Assert(t.NullableField == 0); t.NullableArray[1] ??= 1; ExecutionEngine.Assert(t.NullableArray[1] == 1); t.NullableArray[1] ??= 2; ExecutionEngine.Assert(t.NullableArray[1] == 1); + t.NullableArray[1]++; + ExecutionEngine.Assert(t.NullableArray[1] == 2); + t.NullableArray = [null]; + ExecutionEngine.Assert(t.NullableArray[0] == null); + } + + public static void StaticNullableCoalesceAssignment() + { + TestClass.StaticNullableField ??= null; + ExecutionEngine.Assert(TestClass.StaticNullableField == true); + TestClass.StaticNullableField = null; + ExecutionEngine.Assert((TestClass.StaticNullableField ??= false) == false); + + TestClass.StaticNullableProperty ??= null; + ExecutionEngine.Assert(TestClass.StaticNullableProperty == 0); + TestClass.StaticNullableProperty = null; + ExecutionEngine.Assert((TestClass.StaticNullableProperty ??= 1) == 1); + TestClass.StaticNullableProperty++; + ExecutionEngine.Assert(TestClass.StaticNullableProperty == 2); + --TestClass.StaticNullableProperty; + ExecutionEngine.Assert(TestClass.StaticNullableProperty == 1); } } } diff --git a/tests/Neo.Compiler.CSharp.TestContracts/Contract_PostfixUnary.cs b/tests/Neo.Compiler.CSharp.TestContracts/Contract_PostfixUnary.cs index 49e263e6a..8c2786f8a 100644 --- a/tests/Neo.Compiler.CSharp.TestContracts/Contract_PostfixUnary.cs +++ b/tests/Neo.Compiler.CSharp.TestContracts/Contract_PostfixUnary.cs @@ -13,11 +13,21 @@ public class Person { public string Name { get; set; } - public int Age; + public int Age = 1; + public int Gender { get; set; } = 0; public int[] BWH { get; set; } = { 80, 60, 80 }; - public Person(string name) { Name = name; } + public static int Height = 170; + public static int Weight { get; set; } = 50; + + public static void Invert() + { + ExecutionEngine.Assert(~(Height++) == -171); + ExecutionEngine.Assert(~(--Weight) == -50); + } + + public Person(string name) { Name = name; Age--; ++Age; --Age; } } public static string? Test() @@ -50,11 +60,15 @@ public static void TestUndefinedCase() ExecutionEngine.Assert(p.BWH[0] == 80); p.BWH[0] = ++p.BWH[0]; ExecutionEngine.Assert(p.BWH[0] == 81); + + ExecutionEngine.Assert(p.Gender++ == 0); } public static void TestInvert() { - ExecutionEngine.Assert(~1 == -2); + Person.Invert(); + ExecutionEngine.Assert(~(Person.Height--) == -172); + ExecutionEngine.Assert(~(++Person.Height) == -172); } } } diff --git a/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_MemberAccess.cs b/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_MemberAccess.cs index 2e7cb7ecf..e74ec0bbc 100644 --- a/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_MemberAccess.cs +++ b/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_MemberAccess.cs @@ -10,12 +10,12 @@ public abstract class Contract_MemberAccess(Neo.SmartContract.Testing.SmartContr { #region Compiled data - public static Neo.SmartContract.Manifest.ContractManifest Manifest => Neo.SmartContract.Manifest.ContractManifest.Parse(@"{""name"":""Contract_MemberAccess"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""testMain"",""parameters"":[],""returntype"":""Void"",""offset"":0,""safe"":false},{""name"":""_initialize"",""parameters"":[],""returntype"":""Void"",""offset"":118,""safe"":false}],""events"":[]},""permissions"":[{""contract"":""0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0"",""methods"":[""itoa""]}],""trusts"":[],""extra"":{""nef"":{""optimization"":""All""}}}"); + public static Neo.SmartContract.Manifest.ContractManifest Manifest => Neo.SmartContract.Manifest.ContractManifest.Parse(@"{""name"":""Contract_MemberAccess"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""testMain"",""parameters"":[],""returntype"":""Void"",""offset"":0,""safe"":false},{""name"":""testComplexAssignment"",""parameters"":[],""returntype"":""Void"",""offset"":59,""safe"":false},{""name"":""testStaticComplexAssignment"",""parameters"":[],""returntype"":""Void"",""offset"":331,""safe"":false},{""name"":""_initialize"",""parameters"":[],""returntype"":""Void"",""offset"":414,""safe"":false}],""events"":[]},""permissions"":[{""contract"":""0xacce6fd80d44e1796aa0c2c625e9e4e0ce39efc0"",""methods"":[""itoa""]}],""trusts"":[],""extra"":{""nef"":{""optimization"":""All""}}}"); /// /// Optimization: "All" /// - public static Neo.SmartContract.NefFile Nef => Neo.IO.Helper.AsSerializable(Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHA7znO4OTpJcbCoGp54UQN2G/OrARpdG9hAQABDwAAe1cBAAwFaGVsbG8QEsBwaBDONwAAQc/nR5YMA21zZ0HP50eWaBHOQc/nR5ZoNERBz+dHlhBgWBCXOVgRnkoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ9gWBGXOUBXAAEMAEBWARNgQLlKFjs=")); + public static Neo.SmartContract.NefFile Nef => Neo.IO.Helper.AsSerializable(Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAHA7znO4OTpJcbCoGp54UQN2G/OrARpdG9hAQABDwAA/aUBVwEAFQwFaGVsbG8QE8BwaBDONwAAQc/nR5YMA21zZ0HP50eWaBHOQc/nR5ZoNAhBz+dHlkBXAAEMAEBXAQAVDAVoZWxsbxATwHBoNHMPlzloShDOD6FKAgAAAIAuBCIKSgL///9/Mh4D/////wAAAACRSgL///9/MgwDAAAAAAEAAACfTlAQUdARlzloNG4QlzloNaYAAAAMBmhlbGxvMpc5aEoRzgwCMzOL2yhOEVDQDAhoZWxsbzIzM5c5QFcAAXhKEM4Rn0oCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ9OUBBR0EBXAAF4ShLOeBLOk0oCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ9OElDQQFcAAXhKEc4MATKL2yhOEVDQQBBgWBCXOVgRnkoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ9gWBGXOVkJlzlZCKxhWQiXOVkIk9sgYVkJlzlAVgITYAlhQFa5l84=")); #endregion @@ -25,11 +25,86 @@ public abstract class Contract_MemberAccess(Neo.SmartContract.Testing.SmartContr /// Unsafe method /// /// - /// Script: VwEADAVoZWxsbxASwHBoEM43AABBz+dHlgwDbXNnQc/nR5ZoEc5Bz+dHlmg0REHP50eWEGBYEJc5WBGeSgIAAACALgQiCkoC////fzIeA/////8AAAAAkUoC////fzIMAwAAAAABAAAAn2BYEZc5QA== + /// Script: VwEAFQwFaGVsbG8QE8BwaDRzD5c5aEoQzg+hSgIAAACALgQiCkoC////fzIeA/////8AAAAAkUoC////fzIMAwAAAAABAAAAn05QEFHQEZc5aDRuEJc5aDWmAAAADAZoZWxsbzKXOWhKEc4MAjMzi9soThFQ0AwIaGVsbG8yMzOXOUA= /// INITSLOT 0100 [64 datoshi] + /// PUSH5 [1 datoshi] /// PUSHDATA1 68656C6C6F 'hello' [8 datoshi] /// PUSH0 [1 datoshi] - /// PUSH2 [1 datoshi] + /// PUSH3 [1 datoshi] + /// PACK [2048 datoshi] + /// STLOC0 [2 datoshi] + /// LDLOC0 [2 datoshi] + /// CALL 73 [512 datoshi] + /// PUSHM1 [1 datoshi] + /// EQUAL [32 datoshi] + /// ASSERT [1 datoshi] + /// LDLOC0 [2 datoshi] + /// DUP [2 datoshi] + /// PUSH0 [1 datoshi] + /// PICKITEM [64 datoshi] + /// PUSHM1 [1 datoshi] + /// DIV [8 datoshi] + /// DUP [2 datoshi] + /// PUSHINT32 00000080 [1 datoshi] + /// JMPGE 04 [2 datoshi] + /// JMP 0A [2 datoshi] + /// DUP [2 datoshi] + /// PUSHINT32 FFFFFF7F [1 datoshi] + /// JMPLE 1E [2 datoshi] + /// PUSHINT64 FFFFFFFF00000000 [1 datoshi] + /// AND [8 datoshi] + /// DUP [2 datoshi] + /// PUSHINT32 FFFFFF7F [1 datoshi] + /// JMPLE 0C [2 datoshi] + /// PUSHINT64 0000000001000000 [1 datoshi] + /// SUB [8 datoshi] + /// TUCK [2 datoshi] + /// SWAP [2 datoshi] + /// PUSH0 [1 datoshi] + /// ROT [2 datoshi] + /// SETITEM [8192 datoshi] + /// PUSH1 [1 datoshi] + /// EQUAL [32 datoshi] + /// ASSERT [1 datoshi] + /// LDLOC0 [2 datoshi] + /// CALL 6E [512 datoshi] + /// PUSH0 [1 datoshi] + /// EQUAL [32 datoshi] + /// ASSERT [1 datoshi] + /// LDLOC0 [2 datoshi] + /// CALL_L A6000000 [512 datoshi] + /// PUSHDATA1 68656C6C6F32 'hello2' [8 datoshi] + /// EQUAL [32 datoshi] + /// ASSERT [1 datoshi] + /// LDLOC0 [2 datoshi] + /// DUP [2 datoshi] + /// PUSH1 [1 datoshi] + /// PICKITEM [64 datoshi] + /// PUSHDATA1 3333 '33' [8 datoshi] + /// CAT [2048 datoshi] + /// CONVERT 28 'ByteString' [8192 datoshi] + /// TUCK [2 datoshi] + /// PUSH1 [1 datoshi] + /// SWAP [2 datoshi] + /// SETITEM [8192 datoshi] + /// PUSHDATA1 68656C6C6F323333 'hello233' [8 datoshi] + /// EQUAL [32 datoshi] + /// ASSERT [1 datoshi] + /// RET [0 datoshi] + /// + [DisplayName("testComplexAssignment")] + public abstract void TestComplexAssignment(); + + /// + /// Unsafe method + /// + /// + /// Script: VwEAFQwFaGVsbG8QE8BwaBDONwAAQc/nR5YMA21zZ0HP50eWaBHOQc/nR5ZoNAhBz+dHlkA= + /// INITSLOT 0100 [64 datoshi] + /// PUSH5 [1 datoshi] + /// PUSHDATA1 68656C6C6F 'hello' [8 datoshi] + /// PUSH0 [1 datoshi] + /// PUSH3 [1 datoshi] /// PACK [2048 datoshi] /// STLOC0 [2 datoshi] /// LDLOC0 [2 datoshi] @@ -44,8 +119,18 @@ public abstract class Contract_MemberAccess(Neo.SmartContract.Testing.SmartContr /// PICKITEM [64 datoshi] /// SYSCALL CFE74796 'System.Runtime.Log' [32768 datoshi] /// LDLOC0 [2 datoshi] - /// CALL 44 [512 datoshi] + /// CALL 08 [512 datoshi] /// SYSCALL CFE74796 'System.Runtime.Log' [32768 datoshi] + /// RET [0 datoshi] + /// + [DisplayName("testMain")] + public abstract void TestMain(); + + /// + /// Unsafe method + /// + /// + /// Script: EGBYEJc5WBGeSgIAAACALgQiCkoC////fzIeA/////8AAAAAkUoC////fzIMAwAAAAABAAAAn2BYEZc5WQmXOVkIrGFZCJc5WQiT2yBhWQmXOUA= /// PUSH0 [1 datoshi] /// STSFLD0 [2 datoshi] /// LDSFLD0 [2 datoshi] @@ -74,10 +159,31 @@ public abstract class Contract_MemberAccess(Neo.SmartContract.Testing.SmartContr /// PUSH1 [1 datoshi] /// EQUAL [32 datoshi] /// ASSERT [1 datoshi] + /// LDSFLD1 [2 datoshi] + /// PUSHF [1 datoshi] + /// EQUAL [32 datoshi] + /// ASSERT [1 datoshi] + /// LDSFLD1 [2 datoshi] + /// PUSHT [1 datoshi] + /// BOOLOR [8 datoshi] + /// STSFLD1 [2 datoshi] + /// LDSFLD1 [2 datoshi] + /// PUSHT [1 datoshi] + /// EQUAL [32 datoshi] + /// ASSERT [1 datoshi] + /// LDSFLD1 [2 datoshi] + /// PUSHT [1 datoshi] + /// XOR [8 datoshi] + /// CONVERT 20 'Boolean' [8192 datoshi] + /// STSFLD1 [2 datoshi] + /// LDSFLD1 [2 datoshi] + /// PUSHF [1 datoshi] + /// EQUAL [32 datoshi] + /// ASSERT [1 datoshi] /// RET [0 datoshi] /// - [DisplayName("testMain")] - public abstract void TestMain(); + [DisplayName("testStaticComplexAssignment")] + public abstract void TestStaticComplexAssignment(); #endregion } diff --git a/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_NULL.cs b/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_NULL.cs index e0d0cc279..854433e38 100644 --- a/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_NULL.cs +++ b/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_NULL.cs @@ -10,12 +10,12 @@ public abstract class Contract_NULL(Neo.SmartContract.Testing.SmartContractIniti { #region Compiled data - public static Neo.SmartContract.Manifest.ContractManifest Manifest => Neo.SmartContract.Manifest.ContractManifest.Parse(@"{""name"":""Contract_NULL"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""isNull"",""parameters"":[{""name"":""value"",""type"":""Any""}],""returntype"":""Boolean"",""offset"":0,""safe"":false},{""name"":""equalNullA"",""parameters"":[{""name"":""value"",""type"":""Any""}],""returntype"":""Boolean"",""offset"":8,""safe"":false},{""name"":""equalNullB"",""parameters"":[{""name"":""value"",""type"":""Any""}],""returntype"":""Boolean"",""offset"":15,""safe"":false},{""name"":""equalNotNullA"",""parameters"":[{""name"":""value"",""type"":""Any""}],""returntype"":""Boolean"",""offset"":21,""safe"":false},{""name"":""equalNotNullB"",""parameters"":[{""name"":""value"",""type"":""Any""}],""returntype"":""Boolean"",""offset"":28,""safe"":false},{""name"":""nullCoalescing"",""parameters"":[{""name"":""code"",""type"":""String""}],""returntype"":""String"",""offset"":35,""safe"":false},{""name"":""nullCollation"",""parameters"":[{""name"":""code"",""type"":""String""}],""returntype"":""String"",""offset"":49,""safe"":false},{""name"":""nullPropertyGT"",""parameters"":[{""name"":""a"",""type"":""String""}],""returntype"":""Boolean"",""offset"":68,""safe"":false},{""name"":""nullPropertyLT"",""parameters"":[{""name"":""a"",""type"":""String""}],""returntype"":""Boolean"",""offset"":80,""safe"":false},{""name"":""nullPropertyGE"",""parameters"":[{""name"":""a"",""type"":""String""}],""returntype"":""Boolean"",""offset"":92,""safe"":false},{""name"":""nullPropertyLE"",""parameters"":[{""name"":""a"",""type"":""String""}],""returntype"":""Boolean"",""offset"":104,""safe"":false},{""name"":""nullProperty"",""parameters"":[{""name"":""a"",""type"":""String""}],""returntype"":""Boolean"",""offset"":116,""safe"":false},{""name"":""ifNull"",""parameters"":[{""name"":""obj"",""type"":""Any""}],""returntype"":""Boolean"",""offset"":128,""safe"":false},{""name"":""nullCollationAndCollation"",""parameters"":[{""name"":""code"",""type"":""String""}],""returntype"":""Any"",""offset"":138,""safe"":false},{""name"":""nullCollationAndCollation2"",""parameters"":[{""name"":""code"",""type"":""String""}],""returntype"":""Any"",""offset"":167,""safe"":false},{""name"":""nullType"",""parameters"":[],""returntype"":""Void"",""offset"":208,""safe"":false},{""name"":""nullCoalescingAssignment"",""parameters"":[],""returntype"":""Void"",""offset"":221,""safe"":false}],""events"":[]},""permissions"":[],""trusts"":[],""extra"":{""nef"":{""optimization"":""All""}}}"); + public static Neo.SmartContract.Manifest.ContractManifest Manifest => Neo.SmartContract.Manifest.ContractManifest.Parse(@"{""name"":""Contract_NULL"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""isNull"",""parameters"":[{""name"":""value"",""type"":""Any""}],""returntype"":""Boolean"",""offset"":0,""safe"":false},{""name"":""equalNullA"",""parameters"":[{""name"":""value"",""type"":""Any""}],""returntype"":""Boolean"",""offset"":8,""safe"":false},{""name"":""equalNullB"",""parameters"":[{""name"":""value"",""type"":""Any""}],""returntype"":""Boolean"",""offset"":15,""safe"":false},{""name"":""equalNotNullA"",""parameters"":[{""name"":""value"",""type"":""Any""}],""returntype"":""Boolean"",""offset"":21,""safe"":false},{""name"":""equalNotNullB"",""parameters"":[{""name"":""value"",""type"":""Any""}],""returntype"":""Boolean"",""offset"":28,""safe"":false},{""name"":""nullCoalescing"",""parameters"":[{""name"":""code"",""type"":""String""}],""returntype"":""String"",""offset"":35,""safe"":false},{""name"":""nullCollation"",""parameters"":[{""name"":""code"",""type"":""String""}],""returntype"":""String"",""offset"":49,""safe"":false},{""name"":""nullPropertyGT"",""parameters"":[{""name"":""a"",""type"":""String""}],""returntype"":""Boolean"",""offset"":68,""safe"":false},{""name"":""nullPropertyLT"",""parameters"":[{""name"":""a"",""type"":""String""}],""returntype"":""Boolean"",""offset"":80,""safe"":false},{""name"":""nullPropertyGE"",""parameters"":[{""name"":""a"",""type"":""String""}],""returntype"":""Boolean"",""offset"":92,""safe"":false},{""name"":""nullPropertyLE"",""parameters"":[{""name"":""a"",""type"":""String""}],""returntype"":""Boolean"",""offset"":104,""safe"":false},{""name"":""nullProperty"",""parameters"":[{""name"":""a"",""type"":""String""}],""returntype"":""Boolean"",""offset"":116,""safe"":false},{""name"":""ifNull"",""parameters"":[{""name"":""obj"",""type"":""Any""}],""returntype"":""Boolean"",""offset"":128,""safe"":false},{""name"":""nullCollationAndCollation"",""parameters"":[{""name"":""code"",""type"":""String""}],""returntype"":""Any"",""offset"":138,""safe"":false},{""name"":""nullCollationAndCollation2"",""parameters"":[{""name"":""code"",""type"":""String""}],""returntype"":""Any"",""offset"":167,""safe"":false},{""name"":""nullType"",""parameters"":[],""returntype"":""Void"",""offset"":208,""safe"":false},{""name"":""nullCoalescingAssignment"",""parameters"":[{""name"":""nullableArg"",""type"":""Integer""}],""returntype"":""Void"",""offset"":221,""safe"":false},{""name"":""staticNullableCoalesceAssignment"",""parameters"":[],""returntype"":""Void"",""offset"":486,""safe"":false},{""name"":""_initialize"",""parameters"":[],""returntype"":""Void"",""offset"":653,""safe"":false}],""events"":[]},""permissions"":[],""trusts"":[],""extra"":{""nef"":{""optimization"":""All""}}}"); /// /// Optimization: "All" /// - public static Neo.SmartContract.NefFile Nef => Neo.IO.Helper.AsSerializable(Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP1/AVcBAXhwaNhAVwABC3iXQFcAAXjYQFcAAQt4mEBXAAF42KpAVwEBeErYJAUREoxwaEBXAQF4StgmCkUMBWxpbnV4cGhAVwABeErYJAPKELdAVwABeErYJAPKELVAVwABeErYJAPKELhAVwABeErYJAPKELZAVwABeErYJAPKEJhAVwABeCYECEAJQFcBAUGb9mfOcHhoQZJd6DFK2CYKRQwBe9sw2yhAVwEBQZv2Z85wDAMxMTF4aEHmPxiEeGhBkl3oMUrYJgpFDAF72zDbKEBXAQALcGhK2CQDQEVAVwEACxESwHBoEM4RlzkLSmgQUdBFaBHO2DloShHOStgkBUYiEUVoEM4TEgsQFcBOUBFR0EVoEEtLztgkBc4iC2gRzhDOSlRT0EVoEM4QlzloEEtLztgkBc4iC2gRzhHOSlRT0EVoEM4QlzloEc4RS0vO2CQFziIHEUpUU9BFaBHOEc4RlzloEc4RS0vO2CQFziIHEkpUU9BFaBHOEc4RlzlArhsXHA==")); + public static Neo.SmartContract.NefFile Nef => Neo.IO.Helper.AsSerializable(Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP2UAlcBAXhwaNhAVwABC3iXQFcAAXjYQFcAAQt4mEBXAAF42KpAVwEBeErYJAUREoxwaEBXAQF4StgmCkUMBWxpbnV4cGhAVwABeErYJAPKELdAVwABeErYJAPKELVAVwABeErYJAPKELhAVwABeErYJAPKELZAVwABeErYJAPKEJhAVwABeCYECEAJQFcBAUGb9mfOcHhoQZJd6DFK2CYKRQwBe9sw2yhAVwEBQZv2Z85wDAMxMTF4aEHmPxiEeGhBkl3oMUrYJgpFDAF72zDbKEBXAQALcGhK2CQDQEVAVwEBeNgkBXgiBRFKgEULeBLAcGgQzhGXOQtKaBBR0EVoEc7YOWhKEc5K2CQFRiIRRWgQzhMSCxAVwE5QEVHQRQsRwGg1nwAAAEVoEc4Qzmg1pgAAAEVoEM4QlzloEEtLztgkBc4iC2gRzhHOSlRT0EVoEM4QlzloEc4RS0vO2CQFziIHEUpUU9BFaBHOEc4RlzloEc4RS0vO2CQFziIHEkpUU9BFaBHOEc4RlzloEc4RS0vOSlRTnEoQLgQiCEoB/wAyBgH/AJHQRWgRzhHOEpc5CxHASmgRUdBFaBHOEM7YOUBXAAJ4Ec5K2CYKRXh5TlARUdBAVwACeBBLS87YJATOQHlKVFPQQFjYJAVYIgULSmBFWAiXOQtgWNgkBVgiBQlKYAmXOVlK2CYGRQtKYUVZEJc5C2FZStgmBkURSmERlzlZSpxKAgAAAIAuBCIKSgL///9/Mh4D/////wAAAACRSgL///9/MgwDAAAAAAEAAACfYUVZEpc5WZ1KAgAAAIAuBCIKSgL///9/Mh4D/////wAAAACRSgL///9/MgwDAAAAAAEAAACfYVkRlzlAVgIIYBBhQBH1/Ns=")); #endregion @@ -131,10 +131,19 @@ public abstract class Contract_NULL(Neo.SmartContract.Testing.SmartContractIniti /// Unsafe method /// /// - /// Script: VwEACxESwHBoEM4RlzkLSmgQUdBFaBHO2DloShHOStgkBUYiEUVoEM4TEgsQFcBOUBFR0EVoEEtLztgkBc4iC2gRzhDOSlRT0EVoEM4QlzloEEtLztgkBc4iC2gRzhHOSlRT0EVoEM4QlzloEc4RS0vO2CQFziIHEUpUU9BFaBHOEc4RlzloEc4RS0vO2CQFziIHEkpUU9BFaBHOEc4RlzlA - /// INITSLOT 0100 [64 datoshi] - /// PUSHNULL [1 datoshi] + /// Script: VwEBeNgkBXgiBRFKgEULeBLAcGgQzhGXOQtKaBBR0EVoEc7YOWhKEc5K2CQFRiIRRWgQzhMSCxAVwE5QEVHQRQsRwGg1nwAAAEVoEc4Qzmg1pgAAAEVoEM4QlzloEEtLztgkBc4iC2gRzhHOSlRT0EVoEM4QlzloEc4RS0vO2CQFziIHEUpUU9BFaBHOEc4RlzloEc4RS0vO2CQFziIHEkpUU9BFaBHOEc4RlzloEc4RS0vOSlRTnEoQLgQiCEoB/wAyBgH/AJHQRWgRzhHOEpc5CxHASmgRUdBFaBHOEM7YOUA= + /// INITSLOT 0101 [64 datoshi] + /// LDARG0 [2 datoshi] + /// ISNULL [2 datoshi] + /// JMPIF 05 [2 datoshi] + /// LDARG0 [2 datoshi] + /// JMP 05 [2 datoshi] /// PUSH1 [1 datoshi] + /// DUP [2 datoshi] + /// STARG0 [2 datoshi] + /// DROP [2 datoshi] + /// PUSHNULL [1 datoshi] + /// LDARG0 [2 datoshi] /// PUSH2 [1 datoshi] /// PACK [2048 datoshi] /// STLOC0 [2 datoshi] @@ -181,24 +190,19 @@ public abstract class Contract_NULL(Neo.SmartContract.Testing.SmartContractIniti /// ROT [2 datoshi] /// SETITEM [8192 datoshi] /// DROP [2 datoshi] + /// PUSHNULL [1 datoshi] + /// PUSH1 [1 datoshi] + /// PACK [2048 datoshi] /// LDLOC0 [2 datoshi] - /// PUSH0 [1 datoshi] - /// OVER [2 datoshi] - /// OVER [2 datoshi] - /// PICKITEM [64 datoshi] - /// ISNULL [2 datoshi] - /// JMPIF 05 [2 datoshi] - /// PICKITEM [64 datoshi] - /// JMP 0B [2 datoshi] + /// CALL_L 9F000000 [512 datoshi] + /// DROP [2 datoshi] /// LDLOC0 [2 datoshi] /// PUSH1 [1 datoshi] /// PICKITEM [64 datoshi] /// PUSH0 [1 datoshi] /// PICKITEM [64 datoshi] - /// DUP [2 datoshi] - /// REVERSE4 [2 datoshi] - /// REVERSE3 [2 datoshi] - /// SETITEM [8192 datoshi] + /// LDLOC0 [2 datoshi] + /// CALL_L A6000000 [512 datoshi] /// DROP [2 datoshi] /// LDLOC0 [2 datoshi] /// PUSH0 [1 datoshi] @@ -281,10 +285,56 @@ public abstract class Contract_NULL(Neo.SmartContract.Testing.SmartContractIniti /// PUSH1 [1 datoshi] /// EQUAL [32 datoshi] /// ASSERT [1 datoshi] + /// LDLOC0 [2 datoshi] + /// PUSH1 [1 datoshi] + /// PICKITEM [64 datoshi] + /// PUSH1 [1 datoshi] + /// OVER [2 datoshi] + /// OVER [2 datoshi] + /// PICKITEM [64 datoshi] + /// DUP [2 datoshi] + /// REVERSE4 [2 datoshi] + /// REVERSE3 [2 datoshi] + /// INC [4 datoshi] + /// DUP [2 datoshi] + /// PUSH0 [1 datoshi] + /// JMPGE 04 [2 datoshi] + /// JMP 08 [2 datoshi] + /// DUP [2 datoshi] + /// PUSHINT16 FF00 [1 datoshi] + /// JMPLE 06 [2 datoshi] + /// PUSHINT16 FF00 [1 datoshi] + /// AND [8 datoshi] + /// SETITEM [8192 datoshi] + /// DROP [2 datoshi] + /// LDLOC0 [2 datoshi] + /// PUSH1 [1 datoshi] + /// PICKITEM [64 datoshi] + /// PUSH1 [1 datoshi] + /// PICKITEM [64 datoshi] + /// PUSH2 [1 datoshi] + /// EQUAL [32 datoshi] + /// ASSERT [1 datoshi] + /// PUSHNULL [1 datoshi] + /// PUSH1 [1 datoshi] + /// PACK [2048 datoshi] + /// DUP [2 datoshi] + /// LDLOC0 [2 datoshi] + /// PUSH1 [1 datoshi] + /// ROT [2 datoshi] + /// SETITEM [8192 datoshi] + /// DROP [2 datoshi] + /// LDLOC0 [2 datoshi] + /// PUSH1 [1 datoshi] + /// PICKITEM [64 datoshi] + /// PUSH0 [1 datoshi] + /// PICKITEM [64 datoshi] + /// ISNULL [2 datoshi] + /// ASSERT [1 datoshi] /// RET [0 datoshi] /// [DisplayName("nullCoalescingAssignment")] - public abstract void NullCoalescingAssignment(); + public abstract void NullCoalescingAssignment(BigInteger? nullableArg); /// /// Unsafe method @@ -464,5 +514,111 @@ public abstract class Contract_NULL(Neo.SmartContract.Testing.SmartContractIniti [DisplayName("nullType")] public abstract void NullType(); + /// + /// Unsafe method + /// + /// + /// Script: WNgkBVgiBQtKYEVYCJc5C2BY2CQFWCIFCUpgCZc5WUrYJgZFC0phRVkQlzkLYVlK2CYGRRFKYRGXOVlKnEoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ9hRVkSlzlZnUoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ9hWRGXOUA= + /// LDSFLD0 [2 datoshi] + /// ISNULL [2 datoshi] + /// JMPIF 05 [2 datoshi] + /// LDSFLD0 [2 datoshi] + /// JMP 05 [2 datoshi] + /// PUSHNULL [1 datoshi] + /// DUP [2 datoshi] + /// STSFLD0 [2 datoshi] + /// DROP [2 datoshi] + /// LDSFLD0 [2 datoshi] + /// PUSHT [1 datoshi] + /// EQUAL [32 datoshi] + /// ASSERT [1 datoshi] + /// PUSHNULL [1 datoshi] + /// STSFLD0 [2 datoshi] + /// LDSFLD0 [2 datoshi] + /// ISNULL [2 datoshi] + /// JMPIF 05 [2 datoshi] + /// LDSFLD0 [2 datoshi] + /// JMP 05 [2 datoshi] + /// PUSHF [1 datoshi] + /// DUP [2 datoshi] + /// STSFLD0 [2 datoshi] + /// PUSHF [1 datoshi] + /// EQUAL [32 datoshi] + /// ASSERT [1 datoshi] + /// LDSFLD1 [2 datoshi] + /// DUP [2 datoshi] + /// ISNULL [2 datoshi] + /// JMPIFNOT 06 [2 datoshi] + /// DROP [2 datoshi] + /// PUSHNULL [1 datoshi] + /// DUP [2 datoshi] + /// STSFLD1 [2 datoshi] + /// DROP [2 datoshi] + /// LDSFLD1 [2 datoshi] + /// PUSH0 [1 datoshi] + /// EQUAL [32 datoshi] + /// ASSERT [1 datoshi] + /// PUSHNULL [1 datoshi] + /// STSFLD1 [2 datoshi] + /// LDSFLD1 [2 datoshi] + /// DUP [2 datoshi] + /// ISNULL [2 datoshi] + /// JMPIFNOT 06 [2 datoshi] + /// DROP [2 datoshi] + /// PUSH1 [1 datoshi] + /// DUP [2 datoshi] + /// STSFLD1 [2 datoshi] + /// PUSH1 [1 datoshi] + /// EQUAL [32 datoshi] + /// ASSERT [1 datoshi] + /// LDSFLD1 [2 datoshi] + /// DUP [2 datoshi] + /// INC [4 datoshi] + /// DUP [2 datoshi] + /// PUSHINT32 00000080 [1 datoshi] + /// JMPGE 04 [2 datoshi] + /// JMP 0A [2 datoshi] + /// DUP [2 datoshi] + /// PUSHINT32 FFFFFF7F [1 datoshi] + /// JMPLE 1E [2 datoshi] + /// PUSHINT64 FFFFFFFF00000000 [1 datoshi] + /// AND [8 datoshi] + /// DUP [2 datoshi] + /// PUSHINT32 FFFFFF7F [1 datoshi] + /// JMPLE 0C [2 datoshi] + /// PUSHINT64 0000000001000000 [1 datoshi] + /// SUB [8 datoshi] + /// STSFLD1 [2 datoshi] + /// DROP [2 datoshi] + /// LDSFLD1 [2 datoshi] + /// PUSH2 [1 datoshi] + /// EQUAL [32 datoshi] + /// ASSERT [1 datoshi] + /// LDSFLD1 [2 datoshi] + /// DEC [4 datoshi] + /// DUP [2 datoshi] + /// PUSHINT32 00000080 [1 datoshi] + /// JMPGE 04 [2 datoshi] + /// JMP 0A [2 datoshi] + /// DUP [2 datoshi] + /// PUSHINT32 FFFFFF7F [1 datoshi] + /// JMPLE 1E [2 datoshi] + /// PUSHINT64 FFFFFFFF00000000 [1 datoshi] + /// AND [8 datoshi] + /// DUP [2 datoshi] + /// PUSHINT32 FFFFFF7F [1 datoshi] + /// JMPLE 0C [2 datoshi] + /// PUSHINT64 0000000001000000 [1 datoshi] + /// SUB [8 datoshi] + /// STSFLD1 [2 datoshi] + /// LDSFLD1 [2 datoshi] + /// PUSH1 [1 datoshi] + /// EQUAL [32 datoshi] + /// ASSERT [1 datoshi] + /// RET [0 datoshi] + /// + [DisplayName("staticNullableCoalesceAssignment")] + public abstract void StaticNullableCoalesceAssignment(); + #endregion } diff --git a/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_PostfixUnary.cs b/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_PostfixUnary.cs index 23859ccc7..165c1617a 100644 --- a/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_PostfixUnary.cs +++ b/tests/Neo.Compiler.CSharp.UnitTests/TestingArtifacts/Contract_PostfixUnary.cs @@ -10,12 +10,12 @@ public abstract class Contract_PostfixUnary(Neo.SmartContract.Testing.SmartContr { #region Compiled data - public static Neo.SmartContract.Manifest.ContractManifest Manifest => Neo.SmartContract.Manifest.ContractManifest.Parse(@"{""name"":""Contract_PostfixUnary"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""test"",""parameters"":[],""returntype"":""String"",""offset"":0,""safe"":false},{""name"":""isValid"",""parameters"":[{""name"":""person"",""type"":""Any""}],""returntype"":""Boolean"",""offset"":168,""safe"":false},{""name"":""testUndefinedCase"",""parameters"":[],""returntype"":""Void"",""offset"":187,""safe"":false},{""name"":""testInvert"",""parameters"":[],""returntype"":""Void"",""offset"":517,""safe"":false}],""events"":[]},""permissions"":[],""trusts"":[],""extra"":{""nef"":{""optimization"":""All""}}}"); + public static Neo.SmartContract.Manifest.ContractManifest Manifest => Neo.SmartContract.Manifest.ContractManifest.Parse(@"{""name"":""Contract_PostfixUnary"",""groups"":[],""features"":{},""supportedstandards"":[],""abi"":{""methods"":[{""name"":""test"",""parameters"":[],""returntype"":""String"",""offset"":0,""safe"":false},{""name"":""isValid"",""parameters"":[{""name"":""person"",""type"":""Any""}],""returntype"":""Boolean"",""offset"":337,""safe"":false},{""name"":""testUndefinedCase"",""parameters"":[],""returntype"":""Void"",""offset"":356,""safe"":false},{""name"":""testInvert"",""parameters"":[],""returntype"":""Void"",""offset"":749,""safe"":false},{""name"":""_initialize"",""parameters"":[],""returntype"":""Void"",""offset"":976,""safe"":false}],""events"":[]},""permissions"":[],""trusts"":[],""extra"":{""nef"":{""optimization"":""All""}}}"); /// /// Optimization: "All" /// - public static Neo.SmartContract.NefFile Nef => Neo.IO.Helper.AsSerializable(Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP0IAlcBAABQADwAUBPAEAsTwAwESm9obks1hwAAAHBoNYsAAAAmeWhKEc5OnEoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ8RUNBFaBLOEUtLzkpUU5xKAgAAAIAuBCIKSgL///9/Mh4D/////wAAAACRSgL///9/MgwDAAAAAAEAAACf0EVoEM5AC0BXAAJ5SngQUdBFQFcBAXhwaNgmBAlAeBDOcGjYqkBXAQAAUAA8AFATwBALE8AMCVVuZGVmaW5lZEs0x3BoEc4QlzloShHOTpxKAgAAAIAuBCIKSgL///9/Mh4D/////wAAAACRSgL///9/MgwDAAAAAAEAAACfEVDQSmgRUdBFaBHOEJc5aEoRzpxKAgAAAIAuBCIKSgL///9/Mh4D/////wAAAACRSgL///9/MgwDAAAAAAEAAACfThFQ0EpoEVHQRWgRzhGXOWgSzhDOAFCXOWgSzhBLS85KVFOcSgIAAACALgQiCkoC////fzIeA/////8AAAAAkUoC////fzIMAwAAAAABAAAAn9BKaBLOEFHQRWgSzhDOAFCXOWgSzhBLS86cSgIAAACALgQiCkoC////fzIeA/////8AAAAAkUoC////fzIMAwAAAAABAAAAn0pUU9BKaBLOEFHQRWgSzhDOAFGXOUAIOUCv254D")); + public static Neo.SmartContract.NefFile Nef => Neo.IO.Helper.AsSerializable(Convert.FromBase64String(@"TkVGM1Rlc3RpbmdFbmdpbmUAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAAP3aA1cBAABQADwAUBPAEBELFMAMBEpvaG5LNYcAAABwaDUzAQAAJnloShHOTpxKAgAAAIAuBCIKSgL///9/Mh4D/////wAAAACRSgL///9/MgwDAAAAAAEAAACfEVDQRWgTzhFLS85KVFOcSgIAAACALgQiCkoC////fzIeA/////8AAAAAkUoC////fzIMAwAAAAABAAAAn9BFaBDOQAtAVwACeUp4EFHQRXhKEc5OnUoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ8RUNBFeEoRzpxKAgAAAIAuBCIKSgL///9/Mh4D/////wAAAACRSgL///9/MgwDAAAAAAEAAACfThFQ0EV4ShHOnUoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ9OEVDQRUBXAQF4cGjYJgQJQHgQznBo2KpAVwEAAFAAPABQE8AQEQsUwAwJVW5kZWZpbmVkSzUe////cGgRzhCXOWhKEc5OnEoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ8RUNBKaBFR0EVoEc4QlzloShHOnEoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ9OEVDQSmgRUdBFaBHOEZc5aBPOEM4AUJc5aBPOEEtLzkpUU5xKAgAAAIAuBCIKSgL///9/Mh4D/////wAAAACRSgL///9/MgwDAAAAAAEAAACf0EpoE84QUdBFaBPOEM4AUJc5aBPOEEtLzpxKAgAAAIAuBCIKSgL///9/Mh4D/////wAAAACRSgL///9/MgwDAAAAAAEAAACfSlRT0EpoE84QUdBFaBPOEM4AUZc5aEoSzk6cSgIAAACALgQiCkoC////fzIeA/////8AAAAAkUoC////fzIMAwAAAAABAAAAn1ASUdAQlzlANHNYSp1KAgAAAIAuBCIKSgL///9/Mh4D/////wAAAACRSgL///9/MgwDAAAAAAEAAACfYJABVP+XOVicSgIAAACALgQiCkoC////fzIeA/////8AAAAAkUoC////fzIMAwAAAAABAAAAn0pgkAFU/5c5QFhKnEoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ9gkAFV/5c5WZ1KAgAAAIAuBCIKSgL///9/Mh4D/////wAAAACRSgL///9/MgwDAAAAAAEAAACfSmGQAM6XOUBWAgGqAGAAMmFAAp4WYQ==")); #endregion @@ -50,7 +50,7 @@ public abstract class Contract_PostfixUnary(Neo.SmartContract.Testing.SmartContr /// Unsafe method /// /// - /// Script: VwEAAFAAPABQE8AQCxPADARKb2huSzWHAAAAcGg1iwAAACZ5aEoRzk6cSgIAAACALgQiCkoC////fzIeA/////8AAAAAkUoC////fzIMAwAAAAABAAAAnxFQ0EVoEs4RS0vOSlRTnEoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ/QRWgQzkALQA== + /// Script: VwEAAFAAPABQE8AQEQsUwAwESm9obks1hwAAAHBoNTMBAAAmeWhKEc5OnEoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ8RUNBFaBPOEUtLzkpUU5xKAgAAAIAuBCIKSgL///9/Mh4D/////wAAAACRSgL///9/MgwDAAAAAAEAAACf0EVoEM5AC0A= /// INITSLOT 0100 [64 datoshi] /// PUSHINT8 50 [1 datoshi] /// PUSHINT8 3C [1 datoshi] @@ -58,15 +58,16 @@ public abstract class Contract_PostfixUnary(Neo.SmartContract.Testing.SmartContr /// PUSH3 [1 datoshi] /// PACK [2048 datoshi] /// PUSH0 [1 datoshi] + /// PUSH1 [1 datoshi] /// PUSHNULL [1 datoshi] - /// PUSH3 [1 datoshi] + /// PUSH4 [1 datoshi] /// PACK [2048 datoshi] /// PUSHDATA1 4A6F686E 'John' [8 datoshi] /// OVER [2 datoshi] /// CALL_L 87000000 [512 datoshi] /// STLOC0 [2 datoshi] /// LDLOC0 [2 datoshi] - /// CALL_L 8B000000 [512 datoshi] + /// CALL_L 33010000 [512 datoshi] /// JMPIFNOT 79 [2 datoshi] /// LDLOC0 [2 datoshi] /// DUP [2 datoshi] @@ -93,7 +94,7 @@ public abstract class Contract_PostfixUnary(Neo.SmartContract.Testing.SmartContr /// SETITEM [8192 datoshi] /// DROP [2 datoshi] /// LDLOC0 [2 datoshi] - /// PUSH2 [1 datoshi] + /// PUSH3 [1 datoshi] /// PICKITEM [64 datoshi] /// PUSH1 [1 datoshi] /// OVER [2 datoshi] @@ -133,8 +134,51 @@ public abstract class Contract_PostfixUnary(Neo.SmartContract.Testing.SmartContr /// Unsafe method /// /// - /// Script: CDlA - /// PUSHT [1 datoshi] + /// Script: NHNYSp1KAgAAAIAuBCIKSgL///9/Mh4D/////wAAAACRSgL///9/MgwDAAAAAAEAAACfYJABVP+XOVicSgIAAACALgQiCkoC////fzIeA/////8AAAAAkUoC////fzIMAwAAAAABAAAAn0pgkAFU/5c5QA== + /// CALL 73 [512 datoshi] + /// LDSFLD0 [2 datoshi] + /// DUP [2 datoshi] + /// DEC [4 datoshi] + /// DUP [2 datoshi] + /// PUSHINT32 00000080 [1 datoshi] + /// JMPGE 04 [2 datoshi] + /// JMP 0A [2 datoshi] + /// DUP [2 datoshi] + /// PUSHINT32 FFFFFF7F [1 datoshi] + /// JMPLE 1E [2 datoshi] + /// PUSHINT64 FFFFFFFF00000000 [1 datoshi] + /// AND [8 datoshi] + /// DUP [2 datoshi] + /// PUSHINT32 FFFFFF7F [1 datoshi] + /// JMPLE 0C [2 datoshi] + /// PUSHINT64 0000000001000000 [1 datoshi] + /// SUB [8 datoshi] + /// STSFLD0 [2 datoshi] + /// INVERT [4 datoshi] + /// PUSHINT16 54FF [1 datoshi] + /// EQUAL [32 datoshi] + /// ASSERT [1 datoshi] + /// LDSFLD0 [2 datoshi] + /// INC [4 datoshi] + /// DUP [2 datoshi] + /// PUSHINT32 00000080 [1 datoshi] + /// JMPGE 04 [2 datoshi] + /// JMP 0A [2 datoshi] + /// DUP [2 datoshi] + /// PUSHINT32 FFFFFF7F [1 datoshi] + /// JMPLE 1E [2 datoshi] + /// PUSHINT64 FFFFFFFF00000000 [1 datoshi] + /// AND [8 datoshi] + /// DUP [2 datoshi] + /// PUSHINT32 FFFFFF7F [1 datoshi] + /// JMPLE 0C [2 datoshi] + /// PUSHINT64 0000000001000000 [1 datoshi] + /// SUB [8 datoshi] + /// DUP [2 datoshi] + /// STSFLD0 [2 datoshi] + /// INVERT [4 datoshi] + /// PUSHINT16 54FF [1 datoshi] + /// EQUAL [32 datoshi] /// ASSERT [1 datoshi] /// RET [0 datoshi] /// @@ -145,7 +189,7 @@ public abstract class Contract_PostfixUnary(Neo.SmartContract.Testing.SmartContr /// Unsafe method /// /// - /// Script: VwEAAFAAPABQE8AQCxPADAlVbmRlZmluZWRLNMdwaBHOEJc5aEoRzk6cSgIAAACALgQiCkoC////fzIeA/////8AAAAAkUoC////fzIMAwAAAAABAAAAnxFQ0EpoEVHQRWgRzhCXOWhKEc6cSgIAAACALgQiCkoC////fzIeA/////8AAAAAkUoC////fzIMAwAAAAABAAAAn04RUNBKaBFR0EVoEc4RlzloEs4QzgBQlzloEs4QS0vOSlRTnEoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ/QSmgSzhBR0EVoEs4QzgBQlzloEs4QS0vOnEoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ9KVFPQSmgSzhBR0EVoEs4QzgBRlzlA + /// Script: VwEAAFAAPABQE8AQEQsUwAwJVW5kZWZpbmVkSzUe////cGgRzhCXOWhKEc5OnEoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ8RUNBKaBFR0EVoEc4QlzloShHOnEoCAAAAgC4EIgpKAv///38yHgP/////AAAAAJFKAv///38yDAMAAAAAAQAAAJ9OEVDQSmgRUdBFaBHOEZc5aBPOEM4AUJc5aBPOEEtLzkpUU5xKAgAAAIAuBCIKSgL///9/Mh4D/////wAAAACRSgL///9/MgwDAAAAAAEAAACf0EpoE84QUdBFaBPOEM4AUJc5aBPOEEtLzpxKAgAAAIAuBCIKSgL///9/Mh4D/////wAAAACRSgL///9/MgwDAAAAAAEAAACfSlRT0EpoE84QUdBFaBPOEM4AUZc5aEoSzk6cSgIAAACALgQiCkoC////fzIeA/////8AAAAAkUoC////fzIMAwAAAAABAAAAn1ASUdAQlzlA /// INITSLOT 0100 [64 datoshi] /// PUSHINT8 50 [1 datoshi] /// PUSHINT8 3C [1 datoshi] @@ -153,12 +197,13 @@ public abstract class Contract_PostfixUnary(Neo.SmartContract.Testing.SmartContr /// PUSH3 [1 datoshi] /// PACK [2048 datoshi] /// PUSH0 [1 datoshi] + /// PUSH1 [1 datoshi] /// PUSHNULL [1 datoshi] - /// PUSH3 [1 datoshi] + /// PUSH4 [1 datoshi] /// PACK [2048 datoshi] /// PUSHDATA1 556E646566696E6564 'Undefined' [8 datoshi] /// OVER [2 datoshi] - /// CALL C7 [512 datoshi] + /// CALL_L 1EFFFFFF [512 datoshi] /// STLOC0 [2 datoshi] /// LDLOC0 [2 datoshi] /// PUSH1 [1 datoshi] @@ -237,7 +282,7 @@ public abstract class Contract_PostfixUnary(Neo.SmartContract.Testing.SmartContr /// EQUAL [32 datoshi] /// ASSERT [1 datoshi] /// LDLOC0 [2 datoshi] - /// PUSH2 [1 datoshi] + /// PUSH3 [1 datoshi] /// PICKITEM [64 datoshi] /// PUSH0 [1 datoshi] /// PICKITEM [64 datoshi] @@ -245,7 +290,7 @@ public abstract class Contract_PostfixUnary(Neo.SmartContract.Testing.SmartContr /// EQUAL [32 datoshi] /// ASSERT [1 datoshi] /// LDLOC0 [2 datoshi] - /// PUSH2 [1 datoshi] + /// PUSH3 [1 datoshi] /// PICKITEM [64 datoshi] /// PUSH0 [1 datoshi] /// OVER [2 datoshi] @@ -272,14 +317,14 @@ public abstract class Contract_PostfixUnary(Neo.SmartContract.Testing.SmartContr /// SETITEM [8192 datoshi] /// DUP [2 datoshi] /// LDLOC0 [2 datoshi] - /// PUSH2 [1 datoshi] + /// PUSH3 [1 datoshi] /// PICKITEM [64 datoshi] /// PUSH0 [1 datoshi] /// ROT [2 datoshi] /// SETITEM [8192 datoshi] /// DROP [2 datoshi] /// LDLOC0 [2 datoshi] - /// PUSH2 [1 datoshi] + /// PUSH3 [1 datoshi] /// PICKITEM [64 datoshi] /// PUSH0 [1 datoshi] /// PICKITEM [64 datoshi] @@ -287,7 +332,7 @@ public abstract class Contract_PostfixUnary(Neo.SmartContract.Testing.SmartContr /// EQUAL [32 datoshi] /// ASSERT [1 datoshi] /// LDLOC0 [2 datoshi] - /// PUSH2 [1 datoshi] + /// PUSH3 [1 datoshi] /// PICKITEM [64 datoshi] /// PUSH0 [1 datoshi] /// OVER [2 datoshi] @@ -314,20 +359,47 @@ public abstract class Contract_PostfixUnary(Neo.SmartContract.Testing.SmartContr /// SETITEM [8192 datoshi] /// DUP [2 datoshi] /// LDLOC0 [2 datoshi] - /// PUSH2 [1 datoshi] + /// PUSH3 [1 datoshi] /// PICKITEM [64 datoshi] /// PUSH0 [1 datoshi] /// ROT [2 datoshi] /// SETITEM [8192 datoshi] /// DROP [2 datoshi] /// LDLOC0 [2 datoshi] - /// PUSH2 [1 datoshi] + /// PUSH3 [1 datoshi] /// PICKITEM [64 datoshi] /// PUSH0 [1 datoshi] /// PICKITEM [64 datoshi] /// PUSHINT8 51 [1 datoshi] /// EQUAL [32 datoshi] /// ASSERT [1 datoshi] + /// LDLOC0 [2 datoshi] + /// DUP [2 datoshi] + /// PUSH2 [1 datoshi] + /// PICKITEM [64 datoshi] + /// TUCK [2 datoshi] + /// INC [4 datoshi] + /// DUP [2 datoshi] + /// PUSHINT32 00000080 [1 datoshi] + /// JMPGE 04 [2 datoshi] + /// JMP 0A [2 datoshi] + /// DUP [2 datoshi] + /// PUSHINT32 FFFFFF7F [1 datoshi] + /// JMPLE 1E [2 datoshi] + /// PUSHINT64 FFFFFFFF00000000 [1 datoshi] + /// AND [8 datoshi] + /// DUP [2 datoshi] + /// PUSHINT32 FFFFFF7F [1 datoshi] + /// JMPLE 0C [2 datoshi] + /// PUSHINT64 0000000001000000 [1 datoshi] + /// SUB [8 datoshi] + /// SWAP [2 datoshi] + /// PUSH2 [1 datoshi] + /// ROT [2 datoshi] + /// SETITEM [8192 datoshi] + /// PUSH0 [1 datoshi] + /// EQUAL [32 datoshi] + /// ASSERT [1 datoshi] /// RET [0 datoshi] /// [DisplayName("testUndefinedCase")] diff --git a/tests/Neo.Compiler.CSharp.UnitTests/UnitTest_MemberAccess.cs b/tests/Neo.Compiler.CSharp.UnitTests/UnitTest_MemberAccess.cs index d74764deb..9b510b015 100644 --- a/tests/Neo.Compiler.CSharp.UnitTests/UnitTest_MemberAccess.cs +++ b/tests/Neo.Compiler.CSharp.UnitTests/UnitTest_MemberAccess.cs @@ -13,7 +13,7 @@ public void Test_Main() var logs = new Queue(); Contract.OnRuntimeLog += (sender, log) => logs.Enqueue(log); Contract.TestMain(); - AssertGasConsumed(6111210); + AssertGasConsumed(6108390); // Check logs Assert.AreEqual(4, logs.Count); @@ -22,5 +22,19 @@ public void Test_Main() Assert.AreEqual("hello", logs.Dequeue()); Assert.AreEqual("", logs.Dequeue()); } + + [TestMethod] + public void Test_ComplexAssignment() + { + Contract.TestComplexAssignment(); + AssertGasConsumed(2964570); + } + + [TestMethod] + public void Test_StaticComplexAssignment() + { + Contract.TestStaticComplexAssignment(); + AssertGasConsumed(1237410); + } } } diff --git a/tests/Neo.Compiler.CSharp.UnitTests/UnitTest_NULL.cs b/tests/Neo.Compiler.CSharp.UnitTests/UnitTest_NULL.cs index f69b9aabe..54e86c978 100644 --- a/tests/Neo.Compiler.CSharp.UnitTests/UnitTest_NULL.cs +++ b/tests/Neo.Compiler.CSharp.UnitTests/UnitTest_NULL.cs @@ -13,74 +13,74 @@ public void IsNull() // True Assert.IsTrue(Contract.IsNull(null)); - AssertGasConsumed(1047210); + AssertGasConsumed(1047870); // False Assert.IsFalse(Contract.IsNull(1)); - AssertGasConsumed(1047210); + AssertGasConsumed(1047870); } [TestMethod] public void IfNull() { Assert.IsFalse(Contract.IfNull(null)); - AssertGasConsumed(1047120); + AssertGasConsumed(1047780); } [TestMethod] public void NullProperty() { Assert.IsTrue(Contract.NullProperty(null)); - AssertGasConsumed(1048200); + AssertGasConsumed(1048860); Assert.IsFalse(Contract.NullProperty("")); - AssertGasConsumed(1048530); + AssertGasConsumed(1049190); Assert.IsTrue(Contract.NullProperty("123")); - AssertGasConsumed(1048530); + AssertGasConsumed(1049190); } [TestMethod] public void NullPropertyGT() { Assert.IsFalse(Contract.NullPropertyGT(null)); - AssertGasConsumed(1047480); + AssertGasConsumed(1048140); Assert.IsFalse(Contract.NullPropertyGT("")); - AssertGasConsumed(1047810); + AssertGasConsumed(1048470); Assert.IsTrue(Contract.NullPropertyGT("123")); - AssertGasConsumed(1047810); + AssertGasConsumed(1048470); } [TestMethod] public void NullPropertyLT() { Assert.IsFalse(Contract.NullPropertyLT(null)); - AssertGasConsumed(1047480); + AssertGasConsumed(1048140); Assert.IsFalse(Contract.NullPropertyLT("")); - AssertGasConsumed(1047810); + AssertGasConsumed(1048470); Assert.IsFalse(Contract.NullPropertyLT("123")); - AssertGasConsumed(1047810); + AssertGasConsumed(1048470); } [TestMethod] public void NullPropertyGE() { Assert.IsFalse(Contract.NullPropertyGE(null)); - AssertGasConsumed(1047480); + AssertGasConsumed(1048140); Assert.IsTrue(Contract.NullPropertyGE("")); - AssertGasConsumed(1047810); + AssertGasConsumed(1048470); Assert.IsTrue(Contract.NullPropertyGE("123")); - AssertGasConsumed(1047810); + AssertGasConsumed(1048470); } [TestMethod] public void NullPropertyLE() { Assert.IsFalse(Contract.NullPropertyLE(null)); - AssertGasConsumed(1047480); + AssertGasConsumed(1048140); Assert.IsTrue(Contract.NullPropertyLE("")); - AssertGasConsumed(1047810); + AssertGasConsumed(1048470); Assert.IsFalse(Contract.NullPropertyLE("123")); - AssertGasConsumed(1047810); + AssertGasConsumed(1048470); } [TestMethod] @@ -92,13 +92,13 @@ public void NullCoalescing() // a123b->12 { var data = (VM.Types.ByteString)Contract.NullCoalescing("a123b")!; - AssertGasConsumed(1109040); + AssertGasConsumed(1109700); Assert.AreEqual("12", System.Text.Encoding.ASCII.GetString(data.GetSpan())); } // null->null { Assert.IsNull(Contract.NullCoalescing(null)); - AssertGasConsumed(1047330); + AssertGasConsumed(1047990); } } @@ -111,13 +111,13 @@ public void NullCollation() // nes->nes { Assert.AreEqual("nes", Contract.NullCollation("nes")); - AssertGasConsumed(1047540); + AssertGasConsumed(1048200); } // null->linux { Assert.AreEqual("linux", Contract.NullCollation(null)); - AssertGasConsumed(1047630); + AssertGasConsumed(1048290); } } @@ -125,14 +125,14 @@ public void NullCollation() public void NullCollationAndCollation() { Assert.AreEqual(new BigInteger(123), ((VM.Types.ByteString)Contract.NullCollationAndCollation("nes")!).GetInteger()); - AssertGasConsumed(2522880); + AssertGasConsumed(2523540); } [TestMethod] public void NullCollationAndCollation2() { Assert.AreEqual("111", ((VM.Types.ByteString)Contract.NullCollationAndCollation2("nes")!).GetString()); - AssertGasConsumed(3614460); + AssertGasConsumed(3615120); } [TestMethod] @@ -141,22 +141,22 @@ public void EqualNull() // True Assert.IsTrue(Contract.EqualNullA(null)); - AssertGasConsumed(1048020); + AssertGasConsumed(1048680); // False Assert.IsFalse(Contract.EqualNullA(1)); - AssertGasConsumed(1048020); + AssertGasConsumed(1048680); // True Assert.IsTrue(Contract.EqualNullB(null)); - AssertGasConsumed(1047090); + AssertGasConsumed(1047750); // False Assert.IsFalse(Contract.EqualNullB(1)); - AssertGasConsumed(1047090); + AssertGasConsumed(1047750); } [TestMethod] @@ -165,36 +165,43 @@ public void EqualNotNull() // True Assert.IsFalse(Contract.EqualNotNullA(null)); - AssertGasConsumed(1048020); + AssertGasConsumed(1048680); // False Assert.IsTrue(Contract.EqualNotNullA(1)); - AssertGasConsumed(1048020); + AssertGasConsumed(1048680); // True Assert.IsFalse(Contract.EqualNotNullB(null)); - AssertGasConsumed(1047210); + AssertGasConsumed(1047870); // False Assert.IsTrue(Contract.EqualNotNullB(1)); - AssertGasConsumed(1047210); + AssertGasConsumed(1047870); } [TestMethod] public void NullTypeTest() { Contract.NullType(); // no error - AssertGasConsumed(986340); + AssertGasConsumed(987000); } [TestMethod] public void NullCoalescingAssignment() { - Contract.NullCoalescingAssignment(); - AssertGasConsumed(2139660); + Contract.NullCoalescingAssignment(null); + AssertGasConsumed(2867310); + } + + [TestMethod] + public void StaticNullableCoalesceAssignment() + { + Contract.StaticNullableCoalesceAssignment(); + AssertGasConsumed(993870); } } }