[dlr] Handle more expressions in interpreter
authorMarek Safar <marek.safar@gmail.com>
Sun, 26 Jan 2014 10:34:00 +0000 (11:34 +0100)
committerMarek Safar <marek.safar@gmail.com>
Sun, 26 Jan 2014 10:35:09 +0000 (11:35 +0100)
48 files changed:
mcs/class/Mono.Dynamic.Interpreter/Mono.Dynamic.Interpreter.dll.sources
mcs/class/System.Core/Makefile
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Add.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_AndAlso.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Bind.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Call.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Coalesce.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Convert.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Equal.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_GreaterThan.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_GreaterThanOrEqual.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Invoke.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Lambda.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_LessThan.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_LessThanOrEqual.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_ListBind.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_ListInit.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_MemberBind.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_MemberInit.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Negate.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Not.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_OrElse.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Power.cs
mcs/class/System.Core/Test/System.Linq.Expressions/ExpressionTest_Quote.cs
mcs/class/System.Core/Test/System.Linq/EnumerableAsQueryableTest.cs
mcs/class/System.Core/Test/System.Runtime.CompilerServices/DynamicAttributeTest.cs
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/AddInstruction.cs
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/AndInstruction.cs
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/ControlFlowInstructions.cs
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/EqualInstruction.cs
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/GreaterThanInstruction.cs
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/GreaterThanOrEqualInstruction.cs [new file with mode: 0644]
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/InstructionFactory.cs
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/InstructionList.cs
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/LessThanInstruction.cs
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/LessThanOrEqualInstruction.cs [new file with mode: 0644]
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/MulInstruction.cs
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NegateInstruction.cs
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NotEqualInstruction.cs
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NotInstruction.cs
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/OrInstruction.cs
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/ShlInstruction.cs
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/ShrInstruction.cs
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/StackOperations.cs
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/SubInstruction.cs
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/TypeOperations.cs
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/XorInstruction.cs
mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/LightCompiler.cs

index 87441100a5eb97efcad5425d092fea64dda6e89b..ca26df987e5c22a32124319885f171980ca04556 100644 (file)
@@ -53,11 +53,13 @@ Assembly/AssemblyInfo.cs
 ../dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/EqualInstruction.cs
 ../dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/FieldOperations.cs
 ../dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/GreaterThanInstruction.cs
+../dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/GreaterThanOrEqualInstruction.cs
 ../dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/Instruction.cs
 ../dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/InstructionFactory.cs
 ../dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/InstructionList.cs
 ../dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/LabelInfo.cs
 ../dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/LessThanInstruction.cs
+../dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/LessThanOrEqualInstruction.cs
 ../dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/LocalAccess.cs
 ../dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/ModInstruction.cs
 ../dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/MulInstruction.cs
index 934c3f3cb604938c6b8f35fa7dc982237ba8b639..34e428674aab6e8a53750f61f0a3e015c400b068 100644 (file)
@@ -54,6 +54,7 @@ TEST_MCS_FLAGS = $(LIB_MCS_FLAGS)
 include ../../build/library.make
 
 ifdef CYCLIC_DEP_FILES
+TEST_HARNESS_EXCLUDES += -exclude:NotWorkingInterpreter
 $(build_lib): $(INTERPRETER_DEP_FILE)
 endif
 
index ced567853d48616f01d066e98235cc36b93c3a12..b13a6499a9b65a41130173e4d567876973500943 100644 (file)
@@ -183,6 +183,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void AddTestNullable ()
                {
                        var a = Expression.Parameter (typeof (int?), "a");
@@ -237,6 +238,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void UserDefinedAddLifted ()
                {
                        var l = Expression.Parameter (typeof (Slot?), "l");
@@ -376,6 +378,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void AddLiftedDecimals ()
                {
                        var l = Expression.Parameter (typeof (decimal?), "l");
index 27a7e2ec3e7bea0dd1fd727152f7e343c10fd104..1384adc7501a54e5a5f9be19152c766afcd6dc89 100644 (file)
@@ -150,6 +150,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void AndAlsoTestNullable ()
                {
                        var a = Expression.Parameter (typeof (bool?), "a");
@@ -193,6 +194,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void AndAlsoNullableBoolItem ()
                {
                        var i = Expression.Parameter (typeof (Item<bool?>), "i");
@@ -238,6 +240,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void UserDefinedAndAlso ()
                {
                        var l = Expression.Parameter (typeof (Slot), "l");
@@ -258,6 +261,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void UserDefinedAndAlsoShortCircuit ()
                {
                        var i = Expression.Parameter (typeof (Item<Slot>), "i");
@@ -273,6 +277,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                [Category ("NotDotNet")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=350228
                public void UserDefinedLiftedAndAlsoShortCircuit ()
                {
@@ -289,6 +294,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void UserDefinedAndAlsoLiftedToNull ()
                {
                        var l = Expression.Parameter (typeof (Slot?), "l");
@@ -367,6 +373,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test] // from https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=350487
+               [Category ("NotWorkingInterpreter")]
                public void Connect350487 ()
                {
                        var p = Expression.Parameter (typeof (B), "b");
index 177e628008957f73c7a317af83661855d49bb5bd..3fd2b598221f16298b7d380230c3a4cdef1182eb 100644 (file)
@@ -145,6 +145,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void BindValueTypes ()
                {
                        var i = Expression.Parameter (typeof (int), "i");
index 128678f91f8a96405de8e80c18c48305e1873850..e4cd69c59778a525e26c09bd89a2c4612a086061 100644 (file)
@@ -87,7 +87,7 @@ namespace MonoTests.System.Linq.Expressions {
                }
 
                [Test]
-#if NET_4_0 && !MONOTOUCH
+#if NET_4_0
                [ExpectedException (typeof (ArgumentException))]
 #else
                [ExpectedException (typeof (ArgumentNullException))]
@@ -227,6 +227,7 @@ namespace MonoTests.System.Linq.Expressions {
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void CallMethodOnStruct ()
                {
                        var param = Expression.Parameter (typeof (EineStrukt), "s");
@@ -263,6 +264,7 @@ namespace MonoTests.System.Linq.Expressions {
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void CallStaticMethodWithRefParameter ()
                {
                        var p = Expression.Parameter (typeof (int), "i");
@@ -274,6 +276,7 @@ namespace MonoTests.System.Linq.Expressions {
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void CallStaticMethodWithRefParameterAndOtherParameter ()
                {
                        var i = Expression.Parameter (typeof (int), "i");
@@ -310,6 +313,7 @@ namespace MonoTests.System.Linq.Expressions {
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void Connect282729 ()
                {
                        // test from https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=282729
@@ -337,6 +341,7 @@ namespace MonoTests.System.Linq.Expressions {
 
                [Test]
                [Category ("NotWorking")]
+               [Category ("NotWorkingInterpreter")]
                public void Connect290278 ()
                {
                        // test from https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=290278
@@ -359,6 +364,7 @@ namespace MonoTests.System.Linq.Expressions {
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void Connect297597 ()
                {
                        // test from https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=297597
@@ -375,9 +381,6 @@ namespace MonoTests.System.Linq.Expressions {
                }
 
                [Test]
-#if MONOTOUCH
-               [Category ("NotWorking")]
-#endif
                [Category ("NotDotNet")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=319190
                public void Connect319190 ()
                {
@@ -395,6 +398,7 @@ namespace MonoTests.System.Linq.Expressions {
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void Connect282702 ()
                {
                        var lambda = Expression.Lambda<Func<Func<int>>> (
@@ -484,9 +488,7 @@ namespace MonoTests.System.Linq.Expressions {
                }
 
                [Test]
-#if MONOTOUCH
-               [Category ("NotWorking")]
-#endif
+               [Category ("NotWorkingInterpreter")]
                public void CallNullableGetValueOrDefault () // #568989
                {
                        var value = Expression.Parameter (typeof (int?), "value");
index 0fe89ea671075b2d1b4cc916ba211cc5bc61f49b..e9c43fe4da1252cebe8430e89daceac8eec918e5 100644 (file)
@@ -87,6 +87,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void CoalesceNullableInt ()
                {
                        var a = Expression.Parameter (typeof (int?), "a");
@@ -115,6 +116,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void CoalesceNullableToNonNullable ()
                {
                        var a = Expression.Parameter (typeof (int?), "a");
@@ -132,6 +134,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                [Category ("NotDotNet")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=349822
                public void CoalesceUserDefinedConversion ()
                {
@@ -165,6 +168,7 @@ namespace MonoTests.System.Linq.Expressions
                [Test]
                // #12987
                [Category ("MobileNotWorking")]
+               [Category ("NotWorkingInterpreter")]
                public void CoalesceNullableSlotIntoInteger ()
                {
                        var s = Expression.Parameter (typeof (Slot?), "s");
index 1a9026ed15ae7f821edcdfdfadcf436d6f7b35f9..7fb96f71519940f299885b81aef6aebf1a1d8c46 100644 (file)
@@ -365,6 +365,7 @@ namespace MonoTests.System.Linq.Expressions {
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void CompileNullableToNotNullable ()
                {
                        var p = Expression.Parameter (typeof (int?), "i");
@@ -457,6 +458,7 @@ namespace MonoTests.System.Linq.Expressions {
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void ConvertImplicitToShortToNullableInt ()
                {
                        var a = Expression.Parameter (typeof (ImplicitToShort?), "a");
@@ -482,6 +484,7 @@ namespace MonoTests.System.Linq.Expressions {
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void NullableImplicitToShort ()
                {
                        var i = Expression.Parameter (typeof (ImplicitToShort?), "i");
@@ -517,6 +520,7 @@ namespace MonoTests.System.Linq.Expressions {
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void ConvertNullableULongToNullableDecimal ()
                {
                        var p = Expression.Parameter (typeof (ulong?), "l");
@@ -561,6 +565,7 @@ namespace MonoTests.System.Linq.Expressions {
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void ConvertNullableImplictToIntToNullableLong ()
                {
                        var i = Expression.Parameter (typeof (ImplicitToInt?), "i");
index be7e129d895e25738056d99896c3727327a1c985..497955c4a4e2873a32175a4371fd195698cc11fa 100644 (file)
@@ -248,6 +248,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void UserDefinedEqualLifted ()
                {
                        var l = Expression.Parameter (typeof (Slot?), "l");
@@ -269,6 +270,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void UserDefinedEqualLiftedToNull ()
                {
                        var l = Expression.Parameter (typeof (Slot?), "l");
@@ -472,6 +474,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void NullableNullEqual ()
                {
                        var param = Expression.Parameter (typeof (DateTime?), "x");
index bc21ff6fe0e86095b18a58c5d73db4b8ea96e4db..06aaa4ab66f07ba7a3dce559d3235ec564205cf2 100644 (file)
@@ -191,6 +191,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void UserDefinedGreaterThanLifted ()
                {
                        var l = Expression.Parameter (typeof (Slot?), "l");
@@ -213,6 +214,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void UserDefinedGreaterThanLiftedToNull ()
                {
                        var l = Expression.Parameter (typeof (Slot?), "l");
index bde5f1fa70140ece547af8afdcd2e08e1584d747..96220fdc948119e4c758a50e17621e69f144ebf1 100644 (file)
@@ -165,6 +165,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void UserDefinedGreaterThanOrEqualLifted ()
                {
                        var l = Expression.Parameter (typeof (Slot?), "l");
@@ -187,6 +188,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void UserDefinedGreaterThanOrEqualLiftedToNull ()
                {
                        var l = Expression.Parameter (typeof (Slot?), "l");
index afbb4bcce4fab4f0af719fef4c86fbe0a1fb7c8d..f98394334003573270b25e869bea1916ace279e8 100644 (file)
@@ -130,6 +130,7 @@ namespace MonoTests.System.Linq.Expressions {
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void InvokeWithExpressionLambdaAsArguments ()
                {
                        var p = Expression.Parameter (typeof (string), "s");
index 7fed10137cf6bfdacbf546bc5d25dbef905d6031..8c83e312ec13b1abf17b93da7e581be6468b1e24 100644 (file)
@@ -118,9 +118,6 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
-#if MONOTOUCH
-               [Category ("NotWorking")]
-#endif
                [ExpectedException(typeof(InvalidOperationException))]
                public void ParameterOutOfScope ()
                {
index 7a24ea291115799077da2a32e12b1db5fe1d2b33..b9285ecbf9d2cb56073357b210af5832b1e770d3 100644 (file)
@@ -165,6 +165,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void UserDefinedLessThanLifted ()
                {
                        var l = Expression.Parameter (typeof (Slot?), "l");
@@ -187,6 +188,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void UserDefinedLessThanLiftedToNull ()
                {
                        var l = Expression.Parameter (typeof (Slot?), "l");
index da9473bee1263c39d2eddbc5fd7aac04ae4f4e5f..5e89cd0e1949c5c73a724503412860c1d03ff5e7 100644 (file)
@@ -165,6 +165,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void UserDefinedLessThanOrEqualLifted ()
                {
                        var l = Expression.Parameter (typeof (Slot?), "l");
@@ -187,6 +188,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void UserDefinedLessThanOrEqualLiftedToNull ()
                {
                        var l = Expression.Parameter (typeof (Slot?), "l");
index 70b75148d7fee33043ab9710b0af28bf5ba42a1b..7800818d019dc97e742933dbf02773b89283efaf 100644 (file)
@@ -99,6 +99,7 @@ namespace MonoTests.System.Linq.Expressions {
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void CompiledListBinding ()
                {
                        var add = typeof (List<string>).GetMethod ("Add");
index 4abca78cc2b2abfd1d18a7e9c81f82ad4e2e452c..4e4425b2772483facbde58f58c8c3d5897234812 100644 (file)
@@ -126,6 +126,7 @@ namespace MonoTests.System.Linq.Expressions {
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void CompileListOfStringsInit ()
                {
                        var add = typeof (List<string>).GetMethod ("Add");
@@ -145,6 +146,7 @@ namespace MonoTests.System.Linq.Expressions {
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                [Category ("NotDotNet")]
                public void CompileArrayListOfStringsInit ()
                {
index 0512378e24c6e86b415f75736b37a0a4ca25e435..1592f02c4d36bc683c1264c90a5817ebdca1b981 100644 (file)
@@ -139,6 +139,7 @@ namespace MonoTests.System.Linq.Expressions {
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void CompiledMemberBinding ()
                {
                        var getfoo = Expression.Lambda<Func<Foo>> (
index 73921f1b448aeee07c39d2239b4a7318337da0b4..292931fe0c5ba558895dee3aa7151114088e066f 100644 (file)
@@ -93,6 +93,7 @@ namespace MonoTests.System.Linq.Expressions {
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void CompiledInit ()
                {
                        var i = Expression.Lambda<Func<Thing>> (
index 3cd02c5ab333a3d6fc96d4dca3d4ea185c1d8acc..8c0149821b9a3be1b10a4fbc01577381dec0735f 100644 (file)
@@ -69,7 +69,7 @@ namespace MonoTests.System.Linq.Expressions
                [ExpectedException (typeof (InvalidOperationException))]
                public void NegateBool ()
                {
-                       Expression.UnaryPlus (true.ToConstant ());
+                       Expression.Negate (true.ToConstant ());
                }
 
                [Test]
@@ -155,6 +155,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void UserDefinedNotNullableNegateNullable ()
                {
                        var s = Expression.Parameter (typeof (Slot?), "s");
@@ -292,6 +293,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void NegateLiftedDecimal ()
                {
                        var d = Expression.Parameter (typeof (decimal?), "l");
index 3a8f86e1f892703bd5dea93266e03aa13b9525d3..3dc4401d7297156580c5917b6a867bd913f13ed5 100644 (file)
@@ -163,6 +163,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void UserDefinedNotNullable ()
                {
                        var s = Expression.Parameter (typeof (Slot?), "s");
index 873dd0d0e27da8eedad817a64d8229163341eee6..ddef13f4702f3d0db7191bb95668e8e68a95347c 100644 (file)
@@ -180,6 +180,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void OrElseTestNullable ()
                {
                        var a = Expression.Parameter (typeof (bool?), "a");
@@ -223,6 +224,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void OrElseNullableBoolItem ()
                {
                        var i = Expression.Parameter (typeof (Item<bool?>), "i");
@@ -263,6 +265,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void UserDefinedOrElse ()
                {
                        var l = Expression.Parameter (typeof (Slot), "l");
@@ -304,6 +307,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 #endif
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void UserDefinedOrElseShortCircuit ()
                {
                        var i = Expression.Parameter (typeof (Item<Slot>), "i");
@@ -320,6 +324,7 @@ namespace MonoTests.System.Linq.Expressions
 
                [Test]
                [Category ("NotDotNet")] // https://connect.microsoft.com/VisualStudio/feedback/ViewFeedback.aspx?FeedbackID=350228
+               [Category ("NotWorkingInterpreter")]
                public void UserDefinedLiftedOrElseShortCircuit ()
                {
                        var i = Expression.Parameter (typeof (Item<Slot?>), "i");
index 72d9ea793b0b3044ad678849c6cfa3abd210afcb..a161b482a1a2e1a910c074175b88d17aa73bb25f 100644 (file)
@@ -90,6 +90,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void NullablePower ()
                {
                        var a = Expression.Parameter (typeof (double?), "a");
index 497c5288860c6ab5de5352992cdd3b5106cc9937..80c6623fbe5ecc177c17a4f80d9286e64c2d08c8 100644 (file)
@@ -48,9 +48,6 @@ namespace MonoTests.System.Linq.Expressions
                }
 #else
                [Test]
-#if MONOTOUCH
-               [Category ("NotWorking")]
-#endif
                [ExpectedException (typeof (ArgumentException))]
                public void QuoteConstant ()
                {
@@ -59,6 +56,7 @@ namespace MonoTests.System.Linq.Expressions
 #endif
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void CompiledQuote ()
                {
                        var quote42 = Expression.Lambda<Func<Expression<Func<int>>>> (
@@ -72,9 +70,7 @@ namespace MonoTests.System.Linq.Expressions
                }
 
                [Test]
-#if MONOTOUCH
-               [Category ("NotWorking")]
-#endif
+               [Category ("NotWorkingInterpreter")]
                public void ParameterInQuotedExpression () // #550722
                {
                        // Expression<Func<string, Expression<Func<string>>>> e = (string s) => () => s;
index 0a04d7208a73f35f2d9d5d868949a5b9cde896f6..7269f376c2badb017b8358557b2caee2932b43c1 100644 (file)
@@ -324,6 +324,7 @@ namespace MonoTests.System.Linq {
                }
 
                [Test]
+               [Category ("NotWorkingInterpreter")]
                public void UserExtensionMethod ()
                {
                        BindingFlags extensionFlags = BindingFlags.Static | BindingFlags.Public;
index 27d0848150d776bd7acfe90f9c8fa9c2e1f55e91..070d65bdb0de088288282e96eea7666636db155b 100644 (file)
@@ -26,7 +26,7 @@
 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
 //
 
-#if NET_4_0 && !MONOTOUCH
+#if NET_4_0
 
 using System;
 using System.Runtime.CompilerServices;
index 1f1775c180f2defa04a4daf9fb75b1c43ad979a1..3846e4d215ffefff7b4f919cce824e27e458dcd6 100644 (file)
@@ -153,7 +153,7 @@ namespace Microsoft.Scripting.Interpreter {
             public override int Run(InterpretedFrame frame) {
                 object l = frame.Data[frame.StackIndex - 2];
                 object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (Int16)checked((Int16)l + (Int16)r);
+                frame.Data[frame.StackIndex - 2] = checked((Int16)((Int16)l + (Int16)r));
                 frame.StackIndex--;
                 return +1;
             }
@@ -163,7 +163,7 @@ namespace Microsoft.Scripting.Interpreter {
             public override int Run(InterpretedFrame frame) {
                 object l = frame.Data[frame.StackIndex - 2];
                 object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (Int64)checked((Int64)l + (Int64)r);
+                frame.Data[frame.StackIndex - 2] = checked((Int64)((Int64)l + (Int64)r));
                 frame.StackIndex--;
                 return +1;
             }
@@ -173,7 +173,7 @@ namespace Microsoft.Scripting.Interpreter {
             public override int Run(InterpretedFrame frame) {
                 object l = frame.Data[frame.StackIndex - 2];
                 object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (UInt16)checked((UInt16)l + (UInt16)r);
+                frame.Data[frame.StackIndex - 2] = checked((UInt16)((UInt16)l + (UInt16)r));
                 frame.StackIndex--;
                 return +1;
             }
@@ -183,7 +183,7 @@ namespace Microsoft.Scripting.Interpreter {
             public override int Run(InterpretedFrame frame) {
                 object l = frame.Data[frame.StackIndex - 2];
                 object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (UInt32)checked((UInt32)l + (UInt32)r);
+                frame.Data[frame.StackIndex - 2] = checked((UInt32)((UInt32)l + (UInt32)r));
                 frame.StackIndex--;
                 return +1;
             }
@@ -193,7 +193,7 @@ namespace Microsoft.Scripting.Interpreter {
             public override int Run(InterpretedFrame frame) {
                 object l = frame.Data[frame.StackIndex - 2];
                 object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (UInt64)checked((UInt64)l + (UInt64)r);
+                frame.Data[frame.StackIndex - 2] = checked((UInt64)((UInt64)l + (UInt64)r));
                 frame.StackIndex--;
                 return +1;
             }
index 09ec87df22ac85bb5fe47576280a0eac3c6c7d50..2b423f581f0d3f421958d380fb7bea6a893bc6d8 100644 (file)
@@ -34,6 +34,7 @@ using Microsoft.Scripting.Utils;
 namespace Microsoft.Scripting.Interpreter {
     internal abstract class AndInstruction : Instruction {
         private static Instruction _Int16, _Int32, _Int64, _UInt16, _UInt32, _UInt64, _Boolean;
+        private static Instruction _Int16Lifted, _Int32Lifted, _Int64Lifted, _UInt16Lifted, _UInt32Lifted, _UInt64Lifted, _BooleanLifted;
 
         public override int ConsumedStack { get { return 2; } }
         public override int ProducedStack { get { return 1; } }
@@ -43,9 +44,9 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class AndInt32 : AndInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = ScriptingRuntimeHelpers.Int32ToObject((Int32)l & (Int32)r);
+                var l = (Int32)frame.Data[frame.StackIndex - 2];
+                var r = (Int32)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = ScriptingRuntimeHelpers.Int32ToObject(l & r);
                 frame.StackIndex--;
                 return 1;
             }
@@ -53,9 +54,9 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class AndInt16 : AndInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (Int16)((Int16)l & (Int16)r);
+                var l = (Int16)frame.Data[frame.StackIndex - 2];
+                var r = (Int16)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int16)(l & r);
                 frame.StackIndex--;
                 return 1;
             }
@@ -63,9 +64,9 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class AndInt64 : AndInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (Int64)((Int64)l & (Int64)r);
+                var l = (Int64)frame.Data[frame.StackIndex - 2];
+                var r = (Int64)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int64)(l & r);
                 frame.StackIndex--;
                 return 1;
             }
@@ -73,9 +74,9 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class AndUInt16 : AndInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (UInt16)((UInt16)l & (UInt16)r);
+                var l = (UInt16)frame.Data[frame.StackIndex - 2];
+                var r = (UInt16)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt16)(l & r);
                 frame.StackIndex--;
                 return 1;
             }
@@ -83,9 +84,9 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class AndUInt32 : AndInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (UInt32)((UInt32)l & (UInt32)r);
+                var l = (UInt32)frame.Data[frame.StackIndex - 2];
+                var r = (UInt32)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt32)(l & r);
                 frame.StackIndex--;
                 return 1;
             }
@@ -93,9 +94,9 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class AndUInt64 : AndInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (UInt64)((UInt64)l & (UInt64)r);
+                var l = (UInt64)frame.Data[frame.StackIndex - 2];
+                var r = (UInt64)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt64)(l & r);
                 frame.StackIndex--;
                 return 1;
             }
@@ -103,9 +104,79 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class AndBoolean : AndInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (Boolean)((Boolean)l & (Boolean)r);
+                var l = (Boolean)frame.Data[frame.StackIndex - 2];
+                var r = (Boolean)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Boolean)(l & r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class AndInt32Lifted : AndInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Int32?)frame.Data[frame.StackIndex - 2];
+                var r = (Int32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int32?)(l & r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class AndInt16Lifted : AndInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Int16?)frame.Data[frame.StackIndex - 2];
+                var r = (Int16?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int16?)(l & r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class AndInt64Lifted : AndInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Int64?)frame.Data[frame.StackIndex - 2];
+                var r = (Int64?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int64?)(l & r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class AndUInt16Lifted : AndInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (UInt16?)frame.Data[frame.StackIndex - 2];
+                var r = (UInt16?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt16?)(l & r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class AndUInt32Lifted : AndInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (UInt32?)frame.Data[frame.StackIndex - 2];
+                var r = (UInt32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt32?)(l & r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class AndUInt64Lifted : AndInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (UInt64?)frame.Data[frame.StackIndex - 2];
+                var r = (UInt64?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt64?)(l & r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class AndBooleanLifted : AndInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Boolean?)frame.Data[frame.StackIndex - 2];
+                var r = (Boolean?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Boolean?)(l & r);
                 frame.StackIndex--;
                 return 1;
             }
@@ -127,6 +198,22 @@ namespace Microsoft.Scripting.Interpreter {
             }
         }
 
+        public static Instruction CreateLifted(Type type) {
+            Debug.Assert(!type.IsEnum());
+            switch (type.GetTypeCode()) {
+                case TypeCode.Int16: return _Int16Lifted ?? (_Int16Lifted = new AndInt16Lifted());
+                case TypeCode.Int32: return _Int32Lifted ?? (_Int32Lifted = new AndInt32Lifted());
+                case TypeCode.Int64: return _Int64Lifted ?? (_Int64Lifted = new AndInt64Lifted());
+                case TypeCode.UInt16: return _UInt16Lifted ?? (_UInt16Lifted = new AndUInt16Lifted());
+                case TypeCode.UInt32: return _UInt32Lifted ?? (_UInt32Lifted = new AndUInt32Lifted());
+                case TypeCode.UInt64: return _UInt64Lifted ?? (_UInt64Lifted = new AndUInt64Lifted());
+                case TypeCode.Boolean: return _BooleanLifted ?? (_BooleanLifted = new AndBooleanLifted());
+
+                default:
+                    throw Assert.Unreachable;
+            }
+        }
+
         public override string ToString() {
             return "And()";
         }
index 376488e08f95fce4aee703a3e1468ec4784d7117..b7549ee4b77393092a14cc3f2fb3c0fe93b9fee7 100644 (file)
@@ -119,6 +119,34 @@ namespace Microsoft.Scripting.Interpreter {
         }
     }
 
+       internal sealed class BranchNullInstruction : OffsetInstruction {
+               private static Instruction[] _cache;
+
+               public override Instruction[] Cache {
+                       get {
+                               if (_cache == null) {
+                                       _cache = new Instruction[CacheSize];
+                               }
+                               return _cache;
+                       }
+               }
+
+               internal BranchNullInstruction() {
+               }
+
+               public override int ConsumedStack { get { return 1; } }
+
+               public override int Run(InterpretedFrame frame) {
+                       Debug.Assert(_offset != Unknown);
+
+                       if (frame.Pop() == null) {
+                               return _offset;
+                       }
+
+                       return +1;
+               }
+       }
+
     internal sealed class CoalescingBranchInstruction : OffsetInstruction {
         private static Instruction[] _cache;
 
index e4edde9bab23bf84c327b481f51a30fe04623d77..38e904d3eaeabdd218d59fc34c2b2fc0cbe86237 100644 (file)
@@ -25,6 +25,8 @@ namespace Microsoft.Scripting.Interpreter {
     internal abstract class EqualInstruction : Instruction {
         // Perf: EqualityComparer<T> but is 3/2 to 2 times slower.
         private static Instruction _Reference, _Boolean, _SByte, _Int16, _Char, _Int32, _Int64, _Byte, _UInt16, _UInt32, _UInt64, _Single, _Double;
+        private static Instruction _BooleanLifted, _SByteLifted, _Int16Lifted, _CharLifted, _Int32Lifted, _Int64Lifted,
+            _ByteLifted, _UInt16Lifted, _UInt32Lifted, _UInt64Lifted, _SingleLifted, _DoubleLifted;
 
         public override int ConsumedStack { get { return 2; } }
         public override int ProducedStack { get { return 1; } }
@@ -32,86 +34,171 @@ namespace Microsoft.Scripting.Interpreter {
         private EqualInstruction() {
         }
 
+        public bool LiftedToNull { get; set; }
+
         internal sealed class EqualBoolean : EqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((Boolean)frame.Pop()) == ((Boolean)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l == r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Boolean)l == (Boolean)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class EqualSByte : EqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((SByte)frame.Pop()) == ((SByte)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l == r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (SByte)l == (SByte)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class EqualInt16 : EqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((Int16)frame.Pop()) == ((Int16)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l == r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Int16)l == (Int16)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class EqualChar : EqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((Char)frame.Pop()) == ((Char)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l == r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Char)l == (Char)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class EqualInt32 : EqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((Int32)frame.Pop()) == ((Int32)frame.Pop()));
-                return +1;
-            }
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l == r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Int32)l == (Int32)r;
+
+                frame.StackIndex--;
+                return +1;            }
         }
 
         internal sealed class EqualInt64 : EqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((Int64)frame.Pop()) == ((Int64)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l == r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Int64)l == (Int64)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class EqualByte : EqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((Byte)frame.Pop()) == ((Byte)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l == r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Byte)l == (Byte)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class EqualUInt16 : EqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((UInt16)frame.Pop()) == ((UInt16)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l == r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (UInt16)l == (UInt16)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class EqualUInt32 : EqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((UInt32)frame.Pop()) == ((UInt32)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l == r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (UInt32)l == (UInt32)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class EqualUInt64 : EqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((UInt64)frame.Pop()) == ((UInt64)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l == r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (UInt64)l == (UInt64)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class EqualSingle : EqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((Single)frame.Pop()) == ((Single)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l == r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Single)l == (Single)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class EqualDouble : EqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((Double)frame.Pop()) == ((Double)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l == r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Double)l == (Double)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
@@ -154,6 +241,29 @@ namespace Microsoft.Scripting.Interpreter {
             }
         }
 
+        public static Instruction CreateLifted(Type type) {
+            // Boxed enums can be unboxed as their underlying types:
+            switch ((type.IsEnum() ? Enum.GetUnderlyingType(type) : type).GetTypeCode()) {
+                case TypeCode.Boolean: return _BooleanLifted ?? (_BooleanLifted = new EqualBoolean() { LiftedToNull = true });
+                case TypeCode.SByte: return _SByteLifted ?? (_SByteLifted = new EqualSByte() { LiftedToNull = true });
+                case TypeCode.Byte: return _ByteLifted ?? (_ByteLifted = new EqualByte() { LiftedToNull = true });
+                case TypeCode.Char: return _CharLifted ?? (_CharLifted = new EqualChar() { LiftedToNull = true });
+                case TypeCode.Int16: return _Int16Lifted ?? (_Int16Lifted = new EqualInt16() { LiftedToNull = true });
+                case TypeCode.Int32: return _Int32Lifted ?? (_Int32Lifted = new EqualInt32() { LiftedToNull = true });
+                case TypeCode.Int64: return _Int64Lifted ?? (_Int64Lifted = new EqualInt64() { LiftedToNull = true });
+
+                case TypeCode.UInt16: return _UInt16Lifted ?? (_UInt16Lifted = new EqualInt16() { LiftedToNull = true });
+                case TypeCode.UInt32: return _UInt32Lifted ?? (_UInt32Lifted = new EqualInt32() { LiftedToNull = true });
+                case TypeCode.UInt64: return _UInt64Lifted ?? (_UInt64Lifted = new EqualInt64() { LiftedToNull = true });
+
+                case TypeCode.Single: return _SingleLifted ?? (_SingleLifted = new EqualSingle() { LiftedToNull = true });
+                case TypeCode.Double: return _DoubleLifted ?? (_DoubleLifted = new EqualDouble() { LiftedToNull = true });
+
+                default:
+                    throw Assert.Unreachable;
+            }
+        }
+
         public override string ToString() {
             return "Equal()";
         }
index a35f16b0e349ad004c96d3bb4b0e5e84a1838c83..8849613fd51f1fbd9efc07e0b7799a418ebf4e98 100644 (file)
@@ -1,17 +1,30 @@
-/* ****************************************************************************
- *
- * Copyright (c) Microsoft Corporation. 
- *
- * This source code is subject to terms and conditions of the Apache License, Version 2.0. A 
- * copy of the license can be found in the License.html file at the root of this distribution. If 
- * you cannot locate the  Apache License, Version 2.0, please send an email to 
- * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
- * by the terms of the Apache License, Version 2.0.
- *
- * You must not remove this notice, or any other, from this software.
- *
- *
- * ***************************************************************************/
+// 
+// GreaterThanInstruction.cs:
+//
+// Authors: Marek Safar (marek.safar@gmail.com)
+//     
+// Copyright 2014 Xamarin Inc
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
 
 using System;
 using System.Collections.Generic;
@@ -22,8 +35,9 @@ using Microsoft.Scripting.Runtime;
 using Microsoft.Scripting.Utils;
 
 namespace Microsoft.Scripting.Interpreter {
-    internal abstract class GreaterThanInstruction : Instruction {
+    public abstract class GreaterThanInstruction : Instruction {
         private static Instruction _SByte, _Int16, _Char, _Int32, _Int64, _Byte, _UInt16, _UInt32, _UInt64, _Single, _Double;
+        private static Instruction _SByteLifted, _Int16Lifted, _CharLifted, _Int32Lifted, _Int64Lifted, _ByteLifted, _UInt16Lifted, _UInt32Lifted, _UInt64Lifted, _SingleLifted, _DoubleLifted;
 
         public override int ConsumedStack { get { return 2; } }
         public override int ProducedStack { get { return 1; } }
@@ -31,90 +45,158 @@ namespace Microsoft.Scripting.Interpreter {
         private GreaterThanInstruction() {
         }
 
+        public bool LiftedToNull { get; set; }
+
         internal sealed class GreaterThanSByte : GreaterThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                SByte right = (SByte)frame.Pop();
-                frame.Push(((SByte)frame.Pop()) > right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (SByte)l > (SByte)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class GreaterThanInt16 : GreaterThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                Int16 right = (Int16)frame.Pop();
-                frame.Push(((Int16)frame.Pop()) > right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Int16)l > (Int16)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class GreaterThanChar : GreaterThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                Char right = (Char)frame.Pop();
-                frame.Push(((Char)frame.Pop()) > right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Char)l > (Char)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class GreaterThanInt32 : GreaterThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                Int32 right = (Int32)frame.Pop();
-                frame.Push(((Int32)frame.Pop()) > right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Int32)l > (Int32)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class GreaterThanInt64 : GreaterThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                Int64 right = (Int64)frame.Pop();
-                frame.Push(((Int64)frame.Pop()) > right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Int64)l > (Int64)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class GreaterThanByte : GreaterThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                Byte right = (Byte)frame.Pop();
-                frame.Push(((Byte)frame.Pop()) > right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Byte)l > (Byte)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class GreaterThanUInt16 : GreaterThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                UInt16 right = (UInt16)frame.Pop();
-                frame.Push(((UInt16)frame.Pop()) > right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (UInt16)l > (UInt16)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class GreaterThanUInt32 : GreaterThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                UInt32 right = (UInt32)frame.Pop();
-                frame.Push(((UInt32)frame.Pop()) > right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (UInt32)l > (UInt32)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class GreaterThanUInt64 : GreaterThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                UInt64 right = (UInt64)frame.Pop();
-                frame.Push(((UInt64)frame.Pop()) > right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (UInt64)l > (UInt64)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class GreaterThanSingle : GreaterThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                Single right = (Single)frame.Pop();
-                frame.Push(((Single)frame.Pop()) > right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Single)l > (Single)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class GreaterThanDouble : GreaterThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                Double right = (Double)frame.Pop();
-                frame.Push(((Double)frame.Pop()) > right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Double)l > (Double)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
@@ -139,6 +221,26 @@ namespace Microsoft.Scripting.Interpreter {
             }
         }
 
+        public static Instruction CreateLifted(Type type) {
+            Debug.Assert(!type.IsEnum());
+            switch (type.GetTypeCode()) {
+                case TypeCode.SByte: return _SByteLifted ?? (_SByteLifted = new GreaterThanSByte() { LiftedToNull = true });
+                case TypeCode.Byte: return _ByteLifted ?? (_ByteLifted = new GreaterThanByte() { LiftedToNull = true });
+                case TypeCode.Char: return _CharLifted ?? (_CharLifted = new GreaterThanChar() { LiftedToNull = true });
+                case TypeCode.Int16: return _Int16Lifted ?? (_Int16Lifted = new GreaterThanInt16() { LiftedToNull = true });
+                case TypeCode.Int32: return _Int32Lifted ?? (_Int32Lifted = new GreaterThanInt32() { LiftedToNull = true });
+                case TypeCode.Int64: return _Int64Lifted ?? (_Int64Lifted = new GreaterThanInt64() { LiftedToNull = true });
+                case TypeCode.UInt16: return _UInt16Lifted ?? (_UInt16Lifted = new GreaterThanUInt16() { LiftedToNull = true });
+                case TypeCode.UInt32: return _UInt32Lifted ?? (_UInt32Lifted = new GreaterThanUInt32() { LiftedToNull = true });
+                case TypeCode.UInt64: return _UInt64Lifted ?? (_UInt64Lifted = new GreaterThanUInt64() { LiftedToNull = true });
+                case TypeCode.Single: return _SingleLifted ?? (_SingleLifted = new GreaterThanSingle() { LiftedToNull = true });
+                case TypeCode.Double: return _DoubleLifted ?? (_DoubleLifted = new GreaterThanDouble() { LiftedToNull = true });
+
+                default:
+                    throw Assert.Unreachable;
+            }
+        }
+
         public override string ToString() {
             return "GreaterThan()";
         }
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/GreaterThanOrEqualInstruction.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/GreaterThanOrEqualInstruction.cs
new file mode 100644 (file)
index 0000000..de2da8f
--- /dev/null
@@ -0,0 +1,248 @@
+// 
+// GreaterThanOrEqualInstruction.cs:
+//
+// Authors: Marek Safar (marek.safar@gmail.com)
+//     
+// Copyright 2014 Xamarin Inc
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using Microsoft.Scripting.Runtime;
+using Microsoft.Scripting.Utils;
+
+namespace Microsoft.Scripting.Interpreter {
+    public abstract class GreaterThanOrEqualInstruction : Instruction {
+        private static Instruction _SByte, _Int16, _Char, _Int32, _Int64, _Byte, _UInt16, _UInt32, _UInt64, _Single, _Double;
+        private static Instruction _SByteLifted, _Int16Lifted, _CharLifted, _Int32Lifted, _Int64Lifted, _ByteLifted, _UInt16Lifted, _UInt32Lifted, _UInt64Lifted, _SingleLifted, _DoubleLifted;
+
+        public override int ConsumedStack { get { return 2; } }
+        public override int ProducedStack { get { return 1; } }
+
+        private GreaterThanOrEqualInstruction() {
+        }
+
+        public bool LiftedToNull { get; set; }
+
+        internal sealed class GreaterThanOrEqualSByte : GreaterThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (SByte)l >= (SByte)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        internal sealed class GreaterThanOrEqualInt16 : GreaterThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Int16)l >= (Int16)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        internal sealed class GreaterThanOrEqualChar : GreaterThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Char)l >= (Char)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        internal sealed class GreaterThanOrEqualInt32 : GreaterThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Int32)l >= (Int32)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        internal sealed class GreaterThanOrEqualInt64 : GreaterThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Int64)l >= (Int64)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        internal sealed class GreaterThanOrEqualByte : GreaterThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Byte)l >= (Byte)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        internal sealed class GreaterThanOrEqualUInt16 : GreaterThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (UInt16)l >= (UInt16)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        internal sealed class GreaterThanOrEqualUInt32 : GreaterThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (UInt32)l >= (UInt32)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        internal sealed class GreaterThanOrEqualUInt64 : GreaterThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (UInt64)l >= (UInt64)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        internal sealed class GreaterThanOrEqualSingle : GreaterThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Single)l >= (Single)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        internal sealed class GreaterThanOrEqualDouble : GreaterThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Double)l >= (Double)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        public static Instruction Create(Type type) {
+            Debug.Assert(!type.IsEnum());
+            switch (type.GetTypeCode()) {
+                case TypeCode.SByte: return _SByte ?? (_SByte = new GreaterThanOrEqualSByte());
+                case TypeCode.Byte: return _Byte ?? (_Byte = new GreaterThanOrEqualByte());
+                case TypeCode.Char: return _Char ?? (_Char = new GreaterThanOrEqualChar());
+                case TypeCode.Int16: return _Int16 ?? (_Int16 = new GreaterThanOrEqualInt16());
+                case TypeCode.Int32: return _Int32 ?? (_Int32 = new GreaterThanOrEqualInt32());
+                case TypeCode.Int64: return _Int64 ?? (_Int64 = new GreaterThanOrEqualInt64());
+                case TypeCode.UInt16: return _UInt16 ?? (_UInt16 = new GreaterThanOrEqualUInt16());
+                case TypeCode.UInt32: return _UInt32 ?? (_UInt32 = new GreaterThanOrEqualUInt32());
+                case TypeCode.UInt64: return _UInt64 ?? (_UInt64 = new GreaterThanOrEqualUInt64());
+                case TypeCode.Single: return _Single ?? (_Single = new GreaterThanOrEqualSingle());
+                case TypeCode.Double: return _Double ?? (_Double = new GreaterThanOrEqualDouble());
+
+                default:
+                    throw Assert.Unreachable;
+            }
+        }
+
+        public static Instruction CreateLifted(Type type) {
+            Debug.Assert(!type.IsEnum());
+            switch (type.GetTypeCode()) {
+                case TypeCode.SByte: return _SByteLifted ?? (_SByteLifted = new GreaterThanOrEqualSByte() { LiftedToNull = true });
+                case TypeCode.Byte: return _ByteLifted ?? (_ByteLifted = new GreaterThanOrEqualByte() { LiftedToNull = true });
+                case TypeCode.Char: return _CharLifted ?? (_CharLifted = new GreaterThanOrEqualChar() { LiftedToNull = true });
+                case TypeCode.Int16: return _Int16Lifted ?? (_Int16Lifted = new GreaterThanOrEqualInt16() { LiftedToNull = true });
+                case TypeCode.Int32: return _Int32Lifted ?? (_Int32Lifted = new GreaterThanOrEqualInt32() { LiftedToNull = true });
+                case TypeCode.Int64: return _Int64Lifted ?? (_Int64Lifted = new GreaterThanOrEqualInt64() { LiftedToNull = true });
+                case TypeCode.UInt16: return _UInt16Lifted ?? (_UInt16Lifted = new GreaterThanOrEqualUInt16() { LiftedToNull = true });
+                case TypeCode.UInt32: return _UInt32Lifted ?? (_UInt32Lifted = new GreaterThanOrEqualUInt32() { LiftedToNull = true });
+                case TypeCode.UInt64: return _UInt64Lifted ?? (_UInt64Lifted = new GreaterThanOrEqualUInt64() { LiftedToNull = true });
+                case TypeCode.Single: return _SingleLifted ?? (_SingleLifted = new GreaterThanOrEqualSingle() { LiftedToNull = true });
+                case TypeCode.Double: return _DoubleLifted ?? (_DoubleLifted = new GreaterThanOrEqualDouble() { LiftedToNull = true });
+
+                default:
+                    throw Assert.Unreachable;
+            }
+        }
+
+        public override string ToString() {
+            return "GreaterThanOrEqual()";
+        }
+    }
+}
index ca0be0924d3c460fd71d323dd38693ee219e00a1..5f916ce64b6894ba3e4b87b8e23a1363915af885 100644 (file)
@@ -69,6 +69,7 @@ namespace Microsoft.Scripting.Interpreter {
         internal protected abstract Instruction DefaultValue();
         internal protected abstract Instruction NewArray();
         internal protected abstract Instruction NewArrayInit(int elementCount);
+        internal protected abstract Instruction WrapToNullable(Type elementType);
     }
 
     public sealed class InstructionFactory<T> : InstructionFactory {
@@ -81,6 +82,7 @@ namespace Microsoft.Scripting.Interpreter {
         private Instruction _defaultValue;
         private Instruction _newArray;
         private Instruction _typeAs;
+        private Instruction _nullableWrap;
 
         private InstructionFactory() { }
 
@@ -111,5 +113,9 @@ namespace Microsoft.Scripting.Interpreter {
         internal protected override Instruction NewArrayInit(int elementCount) {
             return new NewArrayInitInstruction<T>(elementCount);
         }
+
+        internal protected override Instruction WrapToNullable(Type elementType) {
+            return _nullableWrap ?? (_nullableWrap = new WrapToNullableInstruction<T>(elementType));
+        }        
     }
 }
index 3fa74e9b967cabc2f33a2baa1a7e2559e86286d2..28746e65c6b119fd8ba44b4ab871102826ed954a 100644 (file)
@@ -664,52 +664,62 @@ namespace Microsoft.Scripting.Interpreter {
 
         #endregion
 
-        public void EmitShl(Type type) {
-            Emit(ShlInstruction.Create(type));
+        public void EmitShl(Type type, bool lifted) {
+            Emit(lifted ? ShlInstruction.CreateLifted(type) : ShlInstruction.Create(type));
         }
 
-        public void EmitShr(Type type) {
-            Emit(ShrInstruction.Create(type));
+        public void EmitShr(Type type, bool lifted) {
+            Emit(lifted ? ShrInstruction.CreateLifted(type) : ShrInstruction.Create(type));
         }
 
-        public void EmitOr(Type type) {
-            Emit(OrInstruction.Create(type));
+        public void EmitOr(Type type, bool lifted) {
+            Emit(lifted ? OrInstruction.CreateLifted(type) : OrInstruction.Create(type));
         }
 
-        public void EmitAnd(Type type) {
-            Emit(AndInstruction.Create(type));
+        public void EmitAnd(Type type, bool lifted) {
+            Emit(lifted ? AndInstruction.CreateLifted (type) : AndInstruction.Create(type));
         }
 
-        public void EmitExclusiveOr(Type type) {
-            Emit(XorInstruction.Create(type));
+        public void EmitExclusiveOr(Type type, bool lifted) {
+            Emit(lifted ? XorInstruction.CreateLifted(type) : XorInstruction.Create(type));
         }        
 
         #region Comparisons
 
-        public void EmitEqual(Type type) {
-            Emit(EqualInstruction.Create(type));
+               public void EmitEqual(Type type, bool liftedResult) {
+            Emit(liftedResult ?
+                EqualInstruction.CreateLifted(TypeUtils.GetNonNullableType (type)) :
+                EqualInstruction.Create(TypeUtils.GetNonNullableType (type)));
         }
 
-        public void EmitNotEqual(Type type) {
-            Emit(NotEqualInstruction.Create(type));
+        public void EmitNotEqual(Type type, bool liftedResult) {
+            Emit(liftedResult ?
+                NotEqualInstruction.CreateLifted(TypeUtils.GetNonNullableType (type)) :
+                NotEqualInstruction.Create(TypeUtils.GetNonNullableType (type)));
         }
 
-        public void EmitLessThan(Type type) {
-            Emit(LessThanInstruction.Create(type));
+        public void EmitLessThan(Type type, bool liftedResult) {
+            Emit(liftedResult ?
+                LessThanInstruction.CreateLifted(TypeUtils.GetNonNullableType (type)) :
+                LessThanInstruction.Create(TypeUtils.GetNonNullableType (type)));
         }
 
-        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters")]
-        public void EmitLessThanOrEqual(Type type) {
-            throw new NotSupportedException();
+        public void EmitLessThanOrEqual(Type type, bool liftedResult) {
+            Emit(liftedResult ?
+                LessThanOrEqualInstruction.CreateLifted(TypeUtils.GetNonNullableType (type)) :
+                LessThanOrEqualInstruction.Create(TypeUtils.GetNonNullableType (type)));
         }
 
-        public void EmitGreaterThan(Type type) {
-            Emit(GreaterThanInstruction.Create(type));
+        public void EmitGreaterThan(Type type, bool liftedResult) {
+            Emit(liftedResult ?
+                GreaterThanInstruction.CreateLifted(TypeUtils.GetNonNullableType (type)) :
+                GreaterThanInstruction.Create(TypeUtils.GetNonNullableType (type)));
         }
 
-        [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Usage", "CA1801:ReviewUnusedParameters")]
-        public void EmitGreaterThanOrEqual(Type type) {
-            throw new NotSupportedException();
+        public void EmitGreaterThanOrEqual(Type type, bool liftedResult) {
+            Emit(liftedResult ?
+                GreaterThanOrEqualInstruction.CreateLifted(TypeUtils.GetNonNullableType (type)) :
+                GreaterThanOrEqualInstruction.Create(TypeUtils.GetNonNullableType (type)));
         }
 
         #endregion
@@ -728,15 +738,24 @@ namespace Microsoft.Scripting.Interpreter {
 
         #region Unary Operators
 
-        public void EmitNegate(Type type, bool @checked) {
+        public void EmitNegate(Type type, bool @checked, bool lifted) {
             if (@checked)
-                Emit(NegateOvfInstruction.Create(type));
+                Emit(lifted ? NegateOvfInstruction.CreateLifted(type) : NegateOvfInstruction.Create(type));
             else
-                Emit(NegateInstruction.Create(type));            
+                Emit(lifted ? NegateInstruction.CreateLifted(type) : NegateInstruction.Create(type));            
         }
 
-        public void EmitNot(Type type) {
-            Emit(NotInstruction.Create(type));
+        public void EmitNot(Type type, bool lifted) {
+            Emit(lifted ? NotInstruction.CreateLifted (type) : NotInstruction.Create(type));
+        }
+
+        #endregion
+
+        #region Nullable operations
+
+        public void EmitWrap (Type elementType)
+        {
+            Emit(InstructionFactory.GetFactory(elementType).WrapToNullable (elementType));
         }
 
         #endregion
@@ -989,6 +1008,10 @@ namespace Microsoft.Scripting.Interpreter {
             EmitBranch(new BranchFalseInstruction(), elseLabel);
         }
 
+        public void EmitBranchNull(BranchLabel elseLabel) {
+            EmitBranch(new BranchNullInstruction(), elseLabel);
+        }
+
         public void EmitThrow() {
             Emit(ThrowInstruction.Throw);
         }
index 2875e8bf9cda66472897e0014846aad62f8bee4a..3bde7a4ee8fd34a3d7956b7ded1d5ef7f43c547a 100644 (file)
@@ -1,17 +1,30 @@
-/* ****************************************************************************
- *
- * Copyright (c) Microsoft Corporation. 
- *
- * This source code is subject to terms and conditions of the Apache License, Version 2.0. A 
- * copy of the license can be found in the License.html file at the root of this distribution. If 
- * you cannot locate the  Apache License, Version 2.0, please send an email to 
- * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
- * by the terms of the Apache License, Version 2.0.
- *
- * You must not remove this notice, or any other, from this software.
- *
- *
- * ***************************************************************************/
+// 
+// LessThanInstruction.cs:
+//
+// Authors: Marek Safar (marek.safar@gmail.com)
+//     
+// Copyright 2014 Xamarin Inc
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
 
 using System;
 using System.Collections.Generic;
@@ -24,6 +37,7 @@ using Microsoft.Scripting.Utils;
 namespace Microsoft.Scripting.Interpreter {
     public abstract class LessThanInstruction : Instruction {
         private static Instruction _SByte, _Int16, _Char, _Int32, _Int64, _Byte, _UInt16, _UInt32, _UInt64, _Single, _Double;
+        private static Instruction _SByteLifted, _Int16Lifted, _CharLifted, _Int32Lifted, _Int64Lifted, _ByteLifted, _UInt16Lifted, _UInt32Lifted, _UInt64Lifted, _SingleLifted, _DoubleLifted;
 
         public override int ConsumedStack { get { return 2; } }
         public override int ProducedStack { get { return 1; } }
@@ -31,90 +45,158 @@ namespace Microsoft.Scripting.Interpreter {
         private LessThanInstruction() {
         }
 
+        public bool LiftedToNull { get; set; }
+
         internal sealed class LessThanSByte : LessThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                SByte right = (SByte)frame.Pop();
-                frame.Push(((SByte)frame.Pop()) < right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (SByte)l < (SByte)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class LessThanInt16 : LessThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                Int16 right = (Int16)frame.Pop();
-                frame.Push(((Int16)frame.Pop()) < right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Int16)l < (Int16)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class LessThanChar : LessThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                Char right = (Char)frame.Pop();
-                frame.Push(((Char)frame.Pop()) < right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Char)l < (Char)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class LessThanInt32 : LessThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                Int32 right = (Int32)frame.Pop();
-                frame.Push(((Int32)frame.Pop()) < right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Int32)l < (Int32)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class LessThanInt64 : LessThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                Int64 right = (Int64)frame.Pop();
-                frame.Push(((Int64)frame.Pop()) < right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Int64)l < (Int64)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class LessThanByte : LessThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                Byte right = (Byte)frame.Pop();
-                frame.Push(((Byte)frame.Pop()) < right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Byte)l < (Byte)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class LessThanUInt16 : LessThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                UInt16 right = (UInt16)frame.Pop();
-                frame.Push(((UInt16)frame.Pop()) < right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (UInt16)l < (UInt16)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class LessThanUInt32 : LessThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                UInt32 right = (UInt32)frame.Pop();
-                frame.Push(((UInt32)frame.Pop()) < right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (UInt32)l < (UInt32)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class LessThanUInt64 : LessThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                UInt64 right = (UInt64)frame.Pop();
-                frame.Push(((UInt64)frame.Pop()) < right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (UInt64)l < (UInt64)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class LessThanSingle : LessThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                Single right = (Single)frame.Pop();
-                frame.Push(((Single)frame.Pop()) < right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Single)l < (Single)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class LessThanDouble : LessThanInstruction {
             public override int Run(InterpretedFrame frame) {
-                Double right = (Double)frame.Pop();
-                frame.Push(((Double)frame.Pop()) < right);
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Double)l < (Double)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
@@ -139,6 +221,26 @@ namespace Microsoft.Scripting.Interpreter {
             }
         }
 
+        public static Instruction CreateLifted(Type type) {
+            Debug.Assert(!type.IsEnum());
+            switch (type.GetTypeCode()) {
+                case TypeCode.SByte: return _SByteLifted ?? (_SByteLifted = new LessThanSByte() { LiftedToNull = true });
+                case TypeCode.Byte: return _ByteLifted ?? (_ByteLifted = new LessThanByte() { LiftedToNull = true });
+                case TypeCode.Char: return _CharLifted ?? (_CharLifted = new LessThanChar() { LiftedToNull = true });
+                case TypeCode.Int16: return _Int16Lifted ?? (_Int16Lifted = new LessThanInt16() { LiftedToNull = true });
+                case TypeCode.Int32: return _Int32Lifted ?? (_Int32Lifted = new LessThanInt32() { LiftedToNull = true });
+                case TypeCode.Int64: return _Int64Lifted ?? (_Int64Lifted = new LessThanInt64() { LiftedToNull = true });
+                case TypeCode.UInt16: return _UInt16Lifted ?? (_UInt16Lifted = new LessThanUInt16() { LiftedToNull = true });
+                case TypeCode.UInt32: return _UInt32Lifted ?? (_UInt32Lifted = new LessThanUInt32() { LiftedToNull = true });
+                case TypeCode.UInt64: return _UInt64Lifted ?? (_UInt64Lifted = new LessThanUInt64() { LiftedToNull = true });
+                case TypeCode.Single: return _SingleLifted ?? (_SingleLifted = new LessThanSingle() { LiftedToNull = true });
+                case TypeCode.Double: return _DoubleLifted ?? (_DoubleLifted = new LessThanDouble() { LiftedToNull = true });
+
+                default:
+                    throw Assert.Unreachable;
+            }
+        }
+
         public override string ToString() {
             return "LessThan()";
         }
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/LessThanOrEqualInstruction.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/LessThanOrEqualInstruction.cs
new file mode 100644 (file)
index 0000000..6c120f5
--- /dev/null
@@ -0,0 +1,248 @@
+// 
+// LessThanOrEqualInstruction.cs:
+//
+// Authors: Marek Safar (marek.safar@gmail.com)
+//     
+// Copyright 2014 Xamarin Inc
+//
+// Permission is hereby granted, free of charge, to any person obtaining
+// a copy of this software and associated documentation files (the
+// "Software"), to deal in the Software without restriction, including
+// without limitation the rights to use, copy, modify, merge, publish,
+// distribute, sublicense, and/or sell copies of the Software, and to
+// permit persons to whom the Software is furnished to do so, subject to
+// the following conditions:
+// 
+// The above copyright notice and this permission notice shall be
+// included in all copies or substantial portions of the Software.
+// 
+// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
+// EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
+// MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
+// NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
+// LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
+// OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
+// WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
+//
+//
+
+using System;
+using System.Collections.Generic;
+using System.Diagnostics;
+using System.Reflection;
+using System.Runtime.CompilerServices;
+using Microsoft.Scripting.Runtime;
+using Microsoft.Scripting.Utils;
+
+namespace Microsoft.Scripting.Interpreter {
+    public abstract class LessThanOrEqualInstruction : Instruction {
+        private static Instruction _SByte, _Int16, _Char, _Int32, _Int64, _Byte, _UInt16, _UInt32, _UInt64, _Single, _Double;
+        private static Instruction _SByteLifted, _Int16Lifted, _CharLifted, _Int32Lifted, _Int64Lifted, _ByteLifted, _UInt16Lifted, _UInt32Lifted, _UInt64Lifted, _SingleLifted, _DoubleLifted;
+
+        public override int ConsumedStack { get { return 2; } }
+        public override int ProducedStack { get { return 1; } }
+
+        private LessThanOrEqualInstruction() {
+        }
+
+        public bool LiftedToNull { get; set; }
+
+        internal sealed class LessThanOrEqualSByte : LessThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (SByte)l <= (SByte)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        internal sealed class LessThanOrEqualInt16 : LessThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Int16)l <= (Int16)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        internal sealed class LessThanOrEqualChar : LessThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Char)l <= (Char)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        internal sealed class LessThanOrEqualInt32 : LessThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Int32)l <= (Int32)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        internal sealed class LessThanOrEqualInt64 : LessThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Int64)l <= (Int64)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        internal sealed class LessThanOrEqualByte : LessThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Byte)l <= (Byte)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        internal sealed class LessThanOrEqualUInt16 : LessThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (UInt16)l <= (UInt16)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        internal sealed class LessThanOrEqualUInt32 : LessThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (UInt32)l <= (UInt32)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        internal sealed class LessThanOrEqualUInt64 : LessThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (UInt64)l <= (UInt64)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        internal sealed class LessThanOrEqualSingle : LessThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Single)l <= (Single)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        internal sealed class LessThanOrEqualDouble : LessThanOrEqualInstruction {
+            public override int Run(InterpretedFrame frame) {
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) false;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Double)l <= (Double)r;
+
+                frame.StackIndex--;
+                return +1;
+            }
+        }
+
+        public static Instruction Create(Type type) {
+            Debug.Assert(!type.IsEnum());
+            switch (type.GetTypeCode()) {
+                case TypeCode.SByte: return _SByte ?? (_SByte = new LessThanOrEqualSByte());
+                case TypeCode.Byte: return _Byte ?? (_Byte = new LessThanOrEqualByte());
+                case TypeCode.Char: return _Char ?? (_Char = new LessThanOrEqualChar());
+                case TypeCode.Int16: return _Int16 ?? (_Int16 = new LessThanOrEqualInt16());
+                case TypeCode.Int32: return _Int32 ?? (_Int32 = new LessThanOrEqualInt32());
+                case TypeCode.Int64: return _Int64 ?? (_Int64 = new LessThanOrEqualInt64());
+                case TypeCode.UInt16: return _UInt16 ?? (_UInt16 = new LessThanOrEqualUInt16());
+                case TypeCode.UInt32: return _UInt32 ?? (_UInt32 = new LessThanOrEqualUInt32());
+                case TypeCode.UInt64: return _UInt64 ?? (_UInt64 = new LessThanOrEqualUInt64());
+                case TypeCode.Single: return _Single ?? (_Single = new LessThanOrEqualSingle());
+                case TypeCode.Double: return _Double ?? (_Double = new LessThanOrEqualDouble());
+
+                default:
+                    throw Assert.Unreachable;
+            }
+        }
+
+        public static Instruction CreateLifted(Type type) {
+            Debug.Assert(!type.IsEnum());
+            switch (type.GetTypeCode()) {
+                case TypeCode.SByte: return _SByteLifted ?? (_SByteLifted = new LessThanOrEqualSByte() { LiftedToNull = true });
+                case TypeCode.Byte: return _ByteLifted ?? (_ByteLifted = new LessThanOrEqualByte() { LiftedToNull = true });
+                case TypeCode.Char: return _CharLifted ?? (_CharLifted = new LessThanOrEqualChar() { LiftedToNull = true });
+                case TypeCode.Int16: return _Int16Lifted ?? (_Int16Lifted = new LessThanOrEqualInt16() { LiftedToNull = true });
+                case TypeCode.Int32: return _Int32Lifted ?? (_Int32Lifted = new LessThanOrEqualInt32() { LiftedToNull = true });
+                case TypeCode.Int64: return _Int64Lifted ?? (_Int64Lifted = new LessThanOrEqualInt64() { LiftedToNull = true });
+                case TypeCode.UInt16: return _UInt16Lifted ?? (_UInt16Lifted = new LessThanOrEqualUInt16() { LiftedToNull = true });
+                case TypeCode.UInt32: return _UInt32Lifted ?? (_UInt32Lifted = new LessThanOrEqualUInt32() { LiftedToNull = true });
+                case TypeCode.UInt64: return _UInt64Lifted ?? (_UInt64Lifted = new LessThanOrEqualUInt64() { LiftedToNull = true });
+                case TypeCode.Single: return _SingleLifted ?? (_SingleLifted = new LessThanOrEqualSingle() { LiftedToNull = true });
+                case TypeCode.Double: return _DoubleLifted ?? (_DoubleLifted = new LessThanOrEqualDouble() { LiftedToNull = true });
+
+                default:
+                    throw Assert.Unreachable;
+            }
+        }
+
+        public override string ToString() {
+            return "LessThanOrEqual()";
+        }
+    }
+}
index 4529adc45120c736c534b92a6e74cc8e7152f049..745e1a0bcad9818682a395f5d977fe29c2c14144 100644 (file)
@@ -166,7 +166,7 @@ namespace Microsoft.Scripting.Interpreter {
             public override int Run(InterpretedFrame frame) {
                 object l = frame.Data[frame.StackIndex - 2];
                 object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (Int16)checked((Int16)l * (Int16)r);
+                frame.Data[frame.StackIndex - 2] = checked((Int16)((Int16)l * (Int16)r));
                 frame.StackIndex--;
                 return +1;
             }
@@ -176,7 +176,7 @@ namespace Microsoft.Scripting.Interpreter {
             public override int Run(InterpretedFrame frame) {
                 object l = frame.Data[frame.StackIndex - 2];
                 object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (Int64)checked((Int64)l * (Int64)r);
+                frame.Data[frame.StackIndex - 2] = checked((Int64)((Int64)l * (Int64)r));
                 frame.StackIndex--;
                 return +1;
             }
@@ -186,7 +186,7 @@ namespace Microsoft.Scripting.Interpreter {
             public override int Run(InterpretedFrame frame) {
                 object l = frame.Data[frame.StackIndex - 2];
                 object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (UInt16)checked((UInt16)l * (UInt16)r);
+                frame.Data[frame.StackIndex - 2] = checked((UInt16)((UInt16)l * (UInt16)r));
                 frame.StackIndex--;
                 return +1;
             }
@@ -196,7 +196,7 @@ namespace Microsoft.Scripting.Interpreter {
             public override int Run(InterpretedFrame frame) {
                 object l = frame.Data[frame.StackIndex - 2];
                 object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (UInt32)checked((UInt32)l * (UInt32)r);
+                frame.Data[frame.StackIndex - 2] = checked((UInt32)((UInt32)l * (UInt32)r));
                 frame.StackIndex--;
                 return +1;
             }
@@ -206,7 +206,7 @@ namespace Microsoft.Scripting.Interpreter {
             public override int Run(InterpretedFrame frame) {
                 object l = frame.Data[frame.StackIndex - 2];
                 object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (UInt64)checked((UInt64)l * (UInt64)r);
+                frame.Data[frame.StackIndex - 2] = checked((UInt64)((UInt64)l * (UInt64)r));
                 frame.StackIndex--;
                 return +1;
             }
index 58c60f6803b8c19e0ab36b0288dd9c031afbb99d..5652f5bc78bf791ae4eadda551b388ef94ed0a45 100644 (file)
@@ -34,6 +34,7 @@ using Microsoft.Scripting.Utils;
 namespace Microsoft.Scripting.Interpreter {
     internal abstract class NegateInstruction : Instruction {
         private static Instruction _Int16, _Int32, _Int64, _UInt16, _UInt32, _Single, _Double;
+        private static Instruction _Int16Lifted, _Int32Lifted, _Int64Lifted, _UInt16Lifted, _UInt32Lifted, _SingleLifted, _DoubleLifted;
 
         public override int ConsumedStack { get { return 1; } }
         public override int ProducedStack { get { return 1; } }
@@ -43,7 +44,7 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class NegateInt32 : NegateInstruction {
             public override int Run(InterpretedFrame frame) {
-                object v = frame.Data[frame.StackIndex - 1];
+                var v = frame.Data[frame.StackIndex - 1];
                 frame.Data[frame.StackIndex - 1] = ScriptingRuntimeHelpers.Int32ToObject(unchecked(-(Int32)v));
                 return 1;
             }
@@ -51,24 +52,24 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class NegateInt16 : NegateInstruction {
             public override int Run(InterpretedFrame frame) {
-                object v = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 1] = (Int16)unchecked(-(Int16)v);
+                var v = (Int16)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Int16)unchecked(-v);
                 return 1;
             }
         }
 
         internal sealed class NegateInt64 : NegateInstruction {
             public override int Run(InterpretedFrame frame) {
-                object v = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 1] = (Int64)unchecked(-(Int64)v);
+                var v = (Int64)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Int64)unchecked(-v);
                 return 1;
             }
         }
 
         internal sealed class NegateUInt16 : NegateInstruction {
             public override int Run(InterpretedFrame frame) {
-                object v = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 1] = (UInt16)unchecked(-(UInt16)v);
+                var v = (UInt16)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (UInt16)unchecked(-v);
                 return 1;
 
             }
@@ -76,8 +77,8 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class NegateUInt32 : NegateInstruction {
             public override int Run(InterpretedFrame frame) {
-                object v = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 1] = (UInt32)unchecked(-(UInt32)v);
+                var v = (UInt32)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (UInt32)unchecked(-v);
                 return 1;
 
             }
@@ -85,8 +86,8 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class NegateSingle : NegateInstruction {
             public override int Run(InterpretedFrame frame) {
-                object v = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 1] = (Single)unchecked(-(Single)v);
+                var v = (Single)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Single)unchecked(-v);
                 return 1;
 
             }
@@ -94,8 +95,68 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class NegateDouble : NegateInstruction {
             public override int Run(InterpretedFrame frame) {
-                object v = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 1] = (Double)unchecked(-(Double)v);
+                var v = (Double)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Double)unchecked(-v);
+                return 1;
+
+            }
+        }
+
+        internal sealed class NegateInt32Lifted : NegateInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var v = (Int32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Int32?)(unchecked(-v));
+                return 1;
+            }
+        }
+
+        internal sealed class NegateInt16Lifted : NegateInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var v = (Int16?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Int16?)unchecked(-v);
+                return 1;
+            }
+        }
+
+        internal sealed class NegateInt64Lifted : NegateInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var v = (Int64?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Int64?)unchecked(-v);
+                return 1;
+            }
+        }
+
+        internal sealed class NegateUInt16Lifted : NegateInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var v = (UInt16?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (UInt16?)unchecked(-v);
+                return 1;
+
+            }
+        }
+
+        internal sealed class NegateUInt32Lifted : NegateInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var v = (UInt32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (UInt32?)unchecked(-v);
+                return 1;
+
+            }
+        }
+
+        internal sealed class NegateSingleLifted : NegateInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var v = (Single?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Single?)unchecked(-v);
+                return 1;
+
+            }
+        }
+
+        internal sealed class NegateDoubleLifted : NegateInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var v = (Double?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Double?)unchecked(-v);
                 return 1;
 
             }
@@ -117,6 +178,22 @@ namespace Microsoft.Scripting.Interpreter {
             }
         }
 
+        public static Instruction CreateLifted(Type type) {
+            Debug.Assert(!type.IsEnum());
+            switch (type.GetTypeCode()) {
+                case TypeCode.Int16: return _Int16Lifted ?? (_Int16Lifted = new NegateInt16Lifted());
+                case TypeCode.Int32: return _Int32Lifted ?? (_Int32Lifted = new NegateInt32Lifted());
+                case TypeCode.Int64: return _Int64Lifted ?? (_Int64Lifted = new NegateInt64Lifted());
+                case TypeCode.UInt16: return _UInt16Lifted ?? (_UInt16Lifted = new NegateUInt16Lifted());
+                case TypeCode.UInt32: return _UInt32Lifted ?? (_UInt32Lifted = new NegateUInt32Lifted());
+                case TypeCode.Single: return _SingleLifted ?? (_SingleLifted = new NegateSingleLifted());
+                case TypeCode.Double: return _DoubleLifted ?? (_DoubleLifted = new NegateDoubleLifted());
+
+                default:
+                    throw Assert.Unreachable;
+            }
+        }
+
         public override string ToString() {
             return "Negate()";
         }
@@ -124,6 +201,7 @@ namespace Microsoft.Scripting.Interpreter {
 
     internal abstract class NegateOvfInstruction : Instruction {
         private static Instruction _Int16, _Int32, _Int64, _UInt16, _UInt32, _Single, _Double;
+        private static Instruction _Int16Lifted, _Int32Lifted, _Int64Lifted, _UInt16Lifted, _UInt32Lifted, _SingleLifted, _DoubleLifted;
 
         public override int ConsumedStack { get { return 1; } }
         public override int ProducedStack { get { return 1; } }
@@ -133,32 +211,32 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class NegateOvfInt32 : NegateOvfInstruction {
             public override int Run(InterpretedFrame frame) {
-                object v = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 1] = ScriptingRuntimeHelpers.Int32ToObject(checked(-(Int32)v));
+                var v = (Int32)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = ScriptingRuntimeHelpers.Int32ToObject(checked(-v));
                 return 1;
             }
         }
 
         internal sealed class NegateOvfInt16 : NegateOvfInstruction {
             public override int Run(InterpretedFrame frame) {
-                object v = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 1] = (Int16)checked(-(Int16)v);
+                var v = (Int16)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = checked((Int16)(-v));
                 return 1;
             }
         }
 
         internal sealed class NegateOvfInt64 : NegateOvfInstruction {
             public override int Run(InterpretedFrame frame) {
-                object v = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 1] = (Int64)checked(-(Int64)v);
+                var v = (Int64)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = checked((Int64)(-v));
                 return 1;
             }
         }
 
         internal sealed class NegateOvfUInt16 : NegateOvfInstruction {
             public override int Run(InterpretedFrame frame) {
-                object v = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 1] = (UInt16)checked(-(UInt16)v);
+                var v = (UInt16)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = checked((UInt16)(-v));
                 return 1;
 
             }
@@ -166,8 +244,8 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class NegateOvfUInt32 : NegateOvfInstruction {
             public override int Run(InterpretedFrame frame) {
-                object v = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 1] = (UInt32)checked(-(UInt32)v);
+                var v = (UInt32)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = checked((UInt32)(-v));
                 return 1;
 
             }
@@ -175,8 +253,8 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class NegateOvfSingle : NegateOvfInstruction {
             public override int Run(InterpretedFrame frame) {
-                object v = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 1] = (Single)checked(-(Single)v);
+                var v = (Single)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Single)checked(-v);
                 return 1;
 
             }
@@ -184,8 +262,68 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class NegateOvfDouble : NegateOvfInstruction {
             public override int Run(InterpretedFrame frame) {
-                object v = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 1] = (Double)checked(-(Double)v);
+                var v = (Double)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Double)checked(-v);
+                return 1;
+
+            }
+        }
+
+        internal sealed class NegateOvfInt32Lifted : NegateOvfInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var v = (Int32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Int32?)(unchecked(-v));
+                return 1;
+            }
+        }
+
+        internal sealed class NegateOvfInt16Lifted : NegateOvfInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var v = (Int16?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Int16?)unchecked(-v);
+                return 1;
+            }
+        }
+
+        internal sealed class NegateOvfInt64Lifted : NegateOvfInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var v = (Int64?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Int64?)unchecked(-v);
+                return 1;
+            }
+        }
+
+        internal sealed class NegateOvfUInt16Lifted : NegateOvfInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var v = (UInt16?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (UInt16?)unchecked(-v);
+                return 1;
+
+            }
+        }
+
+        internal sealed class NegateOvfUInt32Lifted : NegateOvfInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var v = (UInt32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (UInt32?)unchecked(-v);
+                return 1;
+
+            }
+        }
+
+        internal sealed class NegateOvfSingleLifted : NegateOvfInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var v = (Single?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Single?)unchecked(-v);
+                return 1;
+
+            }
+        }
+
+        internal sealed class NegateOvfDoubleLifted : NegateOvfInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var v = (Double?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Double?)unchecked(-v);
                 return 1;
 
             }
@@ -207,6 +345,22 @@ namespace Microsoft.Scripting.Interpreter {
             }
         }
 
+        public static Instruction CreateLifted(Type type) {
+            Debug.Assert(!type.IsEnum());
+            switch (type.GetTypeCode()) {
+                case TypeCode.Int16: return _Int16Lifted ?? (_Int16Lifted = new NegateOvfInt16Lifted());
+                case TypeCode.Int32: return _Int32Lifted ?? (_Int32Lifted = new NegateOvfInt32Lifted());
+                case TypeCode.Int64: return _Int64Lifted ?? (_Int64Lifted = new NegateOvfInt64Lifted());
+                case TypeCode.UInt16: return _UInt16Lifted ?? (_UInt16Lifted = new NegateOvfUInt16Lifted());
+                case TypeCode.UInt32: return _UInt32Lifted ?? (_UInt32Lifted = new NegateOvfUInt32Lifted());
+                case TypeCode.Single: return _SingleLifted ?? (_SingleLifted = new NegateOvfSingleLifted());
+                case TypeCode.Double: return _DoubleLifted ?? (_DoubleLifted = new NegateOvfDoubleLifted());
+
+                default:
+                    throw Assert.Unreachable;
+            }
+        }
+
         public override string ToString() {
             return "NegateOvf()";
         }
index f7da9f46dd39aaa9f23494ce2dcc4e6c24881699..2bd1224374fbc722d3a0df85faa9f9e2c4d0e13f 100644 (file)
@@ -25,6 +25,8 @@ namespace Microsoft.Scripting.Interpreter {
     internal abstract class NotEqualInstruction : Instruction {
         // Perf: EqualityComparer<T> but is 3/2 to 2 times slower.
         private static Instruction _Reference, _Boolean, _SByte, _Int16, _Char, _Int32, _Int64, _Byte, _UInt16, _UInt32, _UInt64, _Single, _Double;
+        private static Instruction _BooleanLifted, _SByteLifted, _Int16Lifted, _CharLifted, _Int32Lifted, _Int64Lifted,
+            _ByteLifted, _UInt16Lifted, _UInt32Lifted, _UInt64Lifted, _SingleLifted, _DoubleLifted;
 
         public override int ConsumedStack { get { return 2; } }
         public override int ProducedStack { get { return 1; } }
@@ -32,86 +34,171 @@ namespace Microsoft.Scripting.Interpreter {
         private NotEqualInstruction() {
         }
 
+        public bool LiftedToNull { get; set; }
+
         internal sealed class NotEqualBoolean : NotEqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((Boolean)frame.Pop()) != ((Boolean)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l != r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Boolean)l != (Boolean)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class NotEqualSByte : NotEqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((SByte)frame.Pop()) != ((SByte)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l != r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (SByte)l != (SByte)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class NotEqualInt16 : NotEqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((Int16)frame.Pop()) != ((Int16)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l != r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Int16)l != (Int16)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class NotEqualChar : NotEqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((Char)frame.Pop()) != ((Char)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l != r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Char)l != (Char)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class NotEqualInt32 : NotEqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((Int32)frame.Pop()) != ((Int32)frame.Pop()));
-                return +1;
-            }
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l != r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Int32)l != (Int32)r;
+
+                frame.StackIndex--;
+                return +1;            }
         }
 
         internal sealed class NotEqualInt64 : NotEqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((Int64)frame.Pop()) != ((Int64)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l != r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Int64)l != (Int64)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class NotEqualByte : NotEqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((Byte)frame.Pop()) != ((Byte)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l != r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Byte)l != (Byte)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class NotEqualUInt16 : NotEqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((UInt16)frame.Pop()) != ((UInt16)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l != r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (UInt16)l != (UInt16)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class NotEqualUInt32 : NotEqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((UInt32)frame.Pop()) != ((UInt32)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l != r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (UInt32)l != (UInt32)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class NotEqualUInt64 : NotEqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((UInt64)frame.Pop()) != ((UInt64)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l != r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (UInt64)l != (UInt64)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class NotEqualSingle : NotEqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((Single)frame.Pop()) != ((Single)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l != r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Single)l != (Single)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
 
         internal sealed class NotEqualDouble : NotEqualInstruction {
             public override int Run(InterpretedFrame frame) {
-                frame.Push(((Double)frame.Pop()) != ((Double)frame.Pop()));
+                object l = frame.Data[frame.StackIndex - 2];
+                object r = frame.Data[frame.StackIndex - 1];
+                if (l == null || r == null)
+                    frame.Data[frame.StackIndex - 2] = LiftedToNull ? (object) null : (object) l != r;
+                else
+                    frame.Data[frame.StackIndex - 2] = (Double)l != (Double)r;
+
+                frame.StackIndex--;
                 return +1;
             }
         }
@@ -154,6 +241,29 @@ namespace Microsoft.Scripting.Interpreter {
             }
         }
 
+        public static Instruction CreateLifted(Type type) {
+            // Boxed enums can be unboxed as their underlying types:
+            switch ((type.IsEnum() ? Enum.GetUnderlyingType(type) : type).GetTypeCode()) {
+                case TypeCode.Boolean: return _BooleanLifted ?? (_BooleanLifted = new NotEqualBoolean() { LiftedToNull = true });
+                case TypeCode.SByte: return _SByteLifted ?? (_SByteLifted = new NotEqualSByte() { LiftedToNull = true });
+                case TypeCode.Byte: return _ByteLifted ?? (_ByteLifted = new NotEqualByte() { LiftedToNull = true });
+                case TypeCode.Char: return _CharLifted ?? (_CharLifted = new NotEqualChar() { LiftedToNull = true });
+                case TypeCode.Int16: return _Int16Lifted ?? (_Int16Lifted = new NotEqualInt16() { LiftedToNull = true });
+                case TypeCode.Int32: return _Int32Lifted ?? (_Int32Lifted = new NotEqualInt32() { LiftedToNull = true });
+                case TypeCode.Int64: return _Int64Lifted ?? (_Int64Lifted = new NotEqualInt64() { LiftedToNull = true });
+
+                case TypeCode.UInt16: return _UInt16Lifted ?? (_UInt16Lifted = new NotEqualInt16() { LiftedToNull = true });
+                case TypeCode.UInt32: return _UInt32Lifted ?? (_UInt32Lifted = new NotEqualInt32() { LiftedToNull = true });
+                case TypeCode.UInt64: return _UInt64Lifted ?? (_UInt64Lifted = new NotEqualInt64() { LiftedToNull = true });
+
+                case TypeCode.Single: return _SingleLifted ?? (_SingleLifted = new NotEqualSingle() { LiftedToNull = true });
+                case TypeCode.Double: return _DoubleLifted ?? (_DoubleLifted = new NotEqualDouble() { LiftedToNull = true });
+
+                default:
+                    throw Assert.Unreachable;
+            }
+        }
+
         public override string ToString() {
             return "NotEqual()";
         }
index 3cfce546518ad4e688e9c36377cad3874d29f709..e1eb3d8bd11af661244efd355198ef5d937ce09f 100644 (file)
@@ -34,6 +34,7 @@ using Microsoft.Scripting.Utils;
 namespace Microsoft.Scripting.Interpreter {
     internal abstract class NotInstruction : Instruction {
         private static Instruction _Int16, _Int32, _Int64, _UInt16, _UInt32, _UInt64, _Boolean;
+        private static Instruction _Int16Lifted, _Int32Lifted, _Int64Lifted, _UInt16Lifted, _UInt32Lifted, _UInt64Lifted, _BooleanLifted;
 
         public override int ConsumedStack { get { return 1; } }
         public override int ProducedStack { get { return 1; } }
@@ -50,48 +51,104 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class NotInt32 : NotInstruction {
             public override int Run(InterpretedFrame frame) {
-                object v = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 1] = ScriptingRuntimeHelpers.Int32ToObject(~(Int32)v);
+                var v = (Int32)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = ScriptingRuntimeHelpers.Int32ToObject(~v);
                 return 1;
             }
         }
 
         internal sealed class NotInt16 : NotInstruction {
             public override int Run(InterpretedFrame frame) {
-                object v = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 1] = (Int16)(~(Int16)v);
+                var v = (Int16)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Int16)(~v);
                 return 1;
             }
         }
 
         internal sealed class NotInt64 : NotInstruction {
             public override int Run(InterpretedFrame frame) {
-                object v = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 1] = (Int64)(~(Int64)v);
+                var v = (Int64)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Int64)(~v);
                 return 1;
             }
         }
 
         internal sealed class NotUInt16 : NotInstruction {
             public override int Run(InterpretedFrame frame) {
-                object v = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 1] = (UInt64)(~(UInt64)v);
+                var v = (UInt64)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (UInt64)(~v);
                 return 1;
             }
         }
 
         internal sealed class NotUInt32 : NotInstruction {
             public override int Run(InterpretedFrame frame) {
-                object v = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 1] = (UInt32)(~(UInt32)v);
+                var v = (UInt32)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (UInt32)(~v);
                 return 1;
             }
         }
 
         internal sealed class NotUInt64 : NotInstruction {
             public override int Run(InterpretedFrame frame) {
-                object v = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 1] = (UInt64)(~(UInt64)v);
+                var v = (UInt64)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (UInt64)(~v);
+                return 1;
+            }
+        }
+
+        internal sealed class NotBooleanLifted : NotInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var v = (Boolean?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Boolean?)(!v);
+                return 1;
+            }
+        }
+
+        internal sealed class NotInt32Lifted : NotInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var v = (Int32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Int32?)(~v);
+                return 1;
+            }
+        }
+
+        internal sealed class NotInt16Lifted : NotInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var v = (Int16?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Int16?)(~v);
+                return 1;
+            }
+        }
+
+        internal sealed class NotInt64Lifted : NotInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var v = (Int64?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (Int64?)(~v);
+                return 1;
+            }
+        }
+
+        internal sealed class NotUInt16Lifted : NotInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var v = (UInt64?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (UInt64?)(~v);
+                return 1;
+            }
+        }
+
+        internal sealed class NotUInt32Lifted : NotInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var v = (UInt32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (UInt32?)(~v);
+                return 1;
+            }
+        }
+
+        internal sealed class NotUInt64Lifted : NotInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var v = (UInt64?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 1] = (UInt64?)(~v);
                 return 1;
             }
         }
@@ -112,6 +169,21 @@ namespace Microsoft.Scripting.Interpreter {
             }
         }
 
+        public static Instruction CreateLifted(Type type) {
+            Debug.Assert(!type.IsEnum());
+            switch (type.GetTypeCode()) {
+                case TypeCode.Int16: return _Int16Lifted ?? (_Int16Lifted = new NotInt16Lifted());
+                case TypeCode.Int32: return _Int32Lifted ?? (_Int32Lifted = new NotInt32Lifted());
+                case TypeCode.Int64: return _Int64Lifted ?? (_Int64Lifted = new NotInt64Lifted());
+                case TypeCode.UInt16: return _UInt16Lifted ?? (_UInt16Lifted = new NotUInt16Lifted());
+                case TypeCode.UInt32: return _UInt32Lifted ?? (_UInt32Lifted = new NotUInt32Lifted());
+                case TypeCode.UInt64: return _UInt64Lifted ?? (_UInt64Lifted = new NotUInt64Lifted());
+                case TypeCode.Boolean: return _BooleanLifted ?? (_BooleanLifted = new NotBooleanLifted());
+
+                default:
+                    throw Assert.Unreachable;
+            }
+        }
         public override string ToString() {
             return "Not()";
         }
index b183b689042d5cef24f6b47ea4fc29d9f26489e7..baaad40fb7079ccc38bd0962e29607e853f1a141 100644 (file)
@@ -34,6 +34,7 @@ using Microsoft.Scripting.Utils;
 namespace Microsoft.Scripting.Interpreter {
     internal abstract class OrInstruction : Instruction {
         private static Instruction _Int16, _Int32, _Int64, _UInt16, _UInt32, _UInt64, _Boolean;
+        private static Instruction _Int16Lifted, _Int32Lifted, _Int64Lifted, _UInt16Lifted, _UInt32Lifted, _UInt64Lifted, _BooleanLifted;
 
         public override int ConsumedStack { get { return 2; } }
         public override int ProducedStack { get { return 1; } }
@@ -43,8 +44,8 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class OrInt32 : OrInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
+                var l = frame.Data[frame.StackIndex - 2];
+                var r = frame.Data[frame.StackIndex - 1];
                 frame.Data[frame.StackIndex - 2] = ScriptingRuntimeHelpers.Int32ToObject((Int32)l | (Int32)r);
                 frame.StackIndex--;
                 return 1;
@@ -53,8 +54,8 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class OrInt16 : OrInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
+                var l = frame.Data[frame.StackIndex - 2];
+                var r = frame.Data[frame.StackIndex - 1];
                 frame.Data[frame.StackIndex - 2] = (Int16)((Int16)l | (Int16)r);
                 frame.StackIndex--;
                 return 1;
@@ -63,8 +64,8 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class OrInt64 : OrInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
+                var l = frame.Data[frame.StackIndex - 2];
+                var r = frame.Data[frame.StackIndex - 1];
                 frame.Data[frame.StackIndex - 2] = (Int64)((Int64)l | (Int64)r);
                 frame.StackIndex--;
                 return 1;
@@ -73,8 +74,8 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class OrUInt16 : OrInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
+                var l = frame.Data[frame.StackIndex - 2];
+                var r = frame.Data[frame.StackIndex - 1];
                 frame.Data[frame.StackIndex - 2] = (UInt16)((UInt16)l | (UInt16)r);
                 frame.StackIndex--;
                 return 1;
@@ -83,8 +84,8 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class OrUInt32 : OrInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
+                var l = frame.Data[frame.StackIndex - 2];
+                var r = frame.Data[frame.StackIndex - 1];
                 frame.Data[frame.StackIndex - 2] = (UInt32)((UInt32)l | (UInt32)r);
                 frame.StackIndex--;
                 return 1;
@@ -93,8 +94,8 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class OrUInt64 : OrInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
+                var l = frame.Data[frame.StackIndex - 2];
+                var r = frame.Data[frame.StackIndex - 1];
                 frame.Data[frame.StackIndex - 2] = (UInt64)((UInt64)l | (UInt64)r);
                 frame.StackIndex--;
                 return 1;
@@ -103,14 +104,84 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class OrBoolean : OrInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
+                var l = frame.Data[frame.StackIndex - 2];
+                var r = frame.Data[frame.StackIndex - 1];
                 frame.Data[frame.StackIndex - 2] = (Boolean)((Boolean)l | (Boolean)r);
                 frame.StackIndex--;
                 return 1;
             }
         }
 
+        internal sealed class OrInt32Lifted : OrInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Int32?)frame.Data[frame.StackIndex - 2];
+                var r = (Int32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int32?)(l | r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class OrInt16Lifted : OrInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Int16?)frame.Data[frame.StackIndex - 2];
+                var r = (Int16?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int16?)(l | r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class OrInt64Lifted : OrInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Int64?)frame.Data[frame.StackIndex - 2];
+                var r = (Int64?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int64?)(l | r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class OrUInt16Lifted : OrInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (UInt16?)frame.Data[frame.StackIndex - 2];
+                var r = (UInt16?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt16?)(l | r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class OrUInt32Lifted : OrInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (UInt32?)frame.Data[frame.StackIndex - 2];
+                var r = (UInt32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt32?)(l | r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class OrUInt64Lifted : OrInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (UInt64?)frame.Data[frame.StackIndex - 2];
+                var r = (UInt64?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt64?)(l | r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class OrBooleanLifted : OrInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Boolean?)frame.Data[frame.StackIndex - 2];
+                var r = (Boolean?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Boolean?)(l | r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
         public static Instruction Create(Type type) {
             Debug.Assert(!type.IsEnum());
             switch (type.GetTypeCode()) {
@@ -127,6 +198,22 @@ namespace Microsoft.Scripting.Interpreter {
             }
         }
 
+        public static Instruction CreateLifted(Type type) {
+            Debug.Assert(!type.IsEnum());
+            switch (type.GetTypeCode()) {
+                case TypeCode.Int16: return _Int16Lifted ?? (_Int16Lifted = new OrInt16Lifted());
+                case TypeCode.Int32: return _Int32Lifted ?? (_Int32Lifted = new OrInt32Lifted());
+                case TypeCode.Int64: return _Int64Lifted ?? (_Int64Lifted = new OrInt64Lifted());
+                case TypeCode.UInt16: return _UInt16Lifted ?? (_UInt16Lifted = new OrUInt16Lifted());
+                case TypeCode.UInt32: return _UInt32Lifted ?? (_UInt32Lifted = new OrUInt32Lifted());
+                case TypeCode.UInt64: return _UInt64Lifted ?? (_UInt64Lifted = new OrUInt64Lifted());
+                case TypeCode.Boolean: return _BooleanLifted ?? (_BooleanLifted = new OrBooleanLifted());
+
+                default:
+                    throw Assert.Unreachable;
+            }
+        }
+
         public override string ToString() {
             return "Or()";
         }
index 4db455315abf0f6c336b1b7bf68b68664c5c9a66..5406dd01b0096b7deab584e3a4ee4bf6623d1388 100644 (file)
@@ -34,6 +34,7 @@ using Microsoft.Scripting.Utils;
 namespace Microsoft.Scripting.Interpreter {
     internal abstract class ShlInstruction : Instruction {
         private static Instruction _Int16, _Int32, _Int64, _UInt16, _UInt32, _UInt64;
+        private static Instruction _Int16Lifted, _Int32Lifted, _Int64Lifted, _UInt16Lifted, _UInt32Lifted, _UInt64Lifted;
 
         public override int ConsumedStack { get { return 2; } }
         public override int ProducedStack { get { return 1; } }
@@ -101,6 +102,66 @@ namespace Microsoft.Scripting.Interpreter {
             }
         }
 
+        internal sealed class ShlInt32Lifted : ShlInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Int32?)frame.Data[frame.StackIndex - 2];
+                var r = (Int32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int32?)(l << r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class ShlInt16Lifted : ShlInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Int16?)frame.Data[frame.StackIndex - 2];
+                var r = (Int32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int32)(l << r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class ShlInt64Lifted : ShlInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Int64?)frame.Data[frame.StackIndex - 2];
+                var r = (Int32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int64?)(l << r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class ShlUInt16Lifted : ShlInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (UInt16?)frame.Data[frame.StackIndex - 2];
+                var r = (Int32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int32?)(l << r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class ShlUInt32Lifted : ShlInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (UInt32?)frame.Data[frame.StackIndex - 2];
+                var r = (Int32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt32?)(l << r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class ShlUInt64Lifted : ShlInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (UInt64?)frame.Data[frame.StackIndex - 2];
+                var r = (Int32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt64?)(l << r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
         public static Instruction Create(Type type) {
             Debug.Assert(!type.IsEnum());
             switch (type.GetTypeCode()) {
@@ -116,6 +177,21 @@ namespace Microsoft.Scripting.Interpreter {
             }
         }
 
+        public static Instruction CreateLifted(Type type) {
+            Debug.Assert(!type.IsEnum());
+            switch (type.GetTypeCode()) {
+                case TypeCode.Int16: return _Int16Lifted ?? (_Int16Lifted = new ShlInt16Lifted());
+                case TypeCode.Int32: return _Int32Lifted ?? (_Int32Lifted = new ShlInt32Lifted());
+                case TypeCode.Int64: return _Int64Lifted ?? (_Int64Lifted = new ShlInt64Lifted());
+                case TypeCode.UInt16: return _UInt16Lifted ?? (_UInt16Lifted = new ShlUInt16Lifted());
+                case TypeCode.UInt32: return _UInt32Lifted ?? (_UInt32Lifted = new ShlUInt32Lifted());
+                case TypeCode.UInt64: return _UInt64Lifted ?? (_UInt64Lifted = new ShlUInt64Lifted());
+
+                default:
+                    throw Assert.Unreachable;
+            }
+        }
+
         public override string ToString() {
             return "Shl()";
         }
index cefb800f17bb81eb5ca20fb55daf43f0680d1a6d..5099a41c18b491a74f5827eb8b3a5827b5275273 100644 (file)
@@ -34,6 +34,7 @@ using Microsoft.Scripting.Utils;
 namespace Microsoft.Scripting.Interpreter {
     internal abstract class ShrInstruction : Instruction {
         private static Instruction _Int16, _Int32, _Int64, _UInt16, _UInt32, _UInt64;
+        private static Instruction _Int16Lifted, _Int32Lifted, _Int64Lifted, _UInt16Lifted, _UInt32Lifted, _UInt64Lifted;
 
         public override int ConsumedStack { get { return 2; } }
         public override int ProducedStack { get { return 1; } }
@@ -101,6 +102,66 @@ namespace Microsoft.Scripting.Interpreter {
             }
         }
 
+        internal sealed class ShrInt32Lifted : ShrInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Int32?)frame.Data[frame.StackIndex - 2];
+                var r = (Int32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int32?)(l >> r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class ShrInt16Lifted : ShrInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Int16?)frame.Data[frame.StackIndex - 2];
+                var r = (Int32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int32)(l >> r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class ShrInt64Lifted : ShrInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Int64?)frame.Data[frame.StackIndex - 2];
+                var r = (Int32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int64?)(l >> r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class ShrUInt16Lifted : ShrInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (UInt16?)frame.Data[frame.StackIndex - 2];
+                var r = (Int32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int32?)(l >> r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class ShrUInt32Lifted : ShrInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (UInt32?)frame.Data[frame.StackIndex - 2];
+                var r = (Int32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt32?)(l >> r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class ShrUInt64Lifted : ShrInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (UInt64?)frame.Data[frame.StackIndex - 2];
+                var r = (Int32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt64?)(l >> r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
         public static Instruction Create(Type type) {
             Debug.Assert(!type.IsEnum());
             switch (type.GetTypeCode()) {
@@ -116,6 +177,21 @@ namespace Microsoft.Scripting.Interpreter {
             }
         }
 
+        public static Instruction CreateLifted(Type type) {
+            Debug.Assert(!type.IsEnum());
+            switch (type.GetTypeCode()) {
+                case TypeCode.Int16: return _Int16Lifted ?? (_Int16Lifted = new ShrInt16Lifted());
+                case TypeCode.Int32: return _Int32Lifted ?? (_Int32Lifted = new ShrInt32Lifted());
+                case TypeCode.Int64: return _Int64Lifted ?? (_Int64Lifted = new ShrInt64Lifted());
+                case TypeCode.UInt16: return _UInt16Lifted ?? (_UInt16Lifted = new ShrUInt16Lifted());
+                case TypeCode.UInt32: return _UInt32Lifted ?? (_UInt32Lifted = new ShrUInt32Lifted());
+                case TypeCode.UInt64: return _UInt64Lifted ?? (_UInt64Lifted = new ShrUInt64Lifted());
+
+                default:
+                    throw Assert.Unreachable;
+            }
+        }
+
         public override string ToString() {
             return "Shr()";
         }
index e2c9e7d1ab7141f1d2ee9ef8e7bba6871e2aa142..6cff464f0aac63c812880e954c8a576d6080e66d 100644 (file)
@@ -106,7 +106,8 @@ namespace Microsoft.Scripting.Interpreter {
         public override int ProducedStack { get { return 1; } }
 
         public override int Run(InterpretedFrame frame) {
-            frame.Data[frame.StackIndex++] = frame.Peek();
+            frame.Data[frame.StackIndex] = frame.Peek();
+                       frame.StackIndex++;
             return +1;
         }
 
index 4571e4f930e0e811144418142b064171144066ae..8ca97e97f7eea15a89a158bcffba1d5b95d1cd58 100644 (file)
@@ -166,7 +166,7 @@ namespace Microsoft.Scripting.Interpreter {
             public override int Run(InterpretedFrame frame) {
                 object l = frame.Data[frame.StackIndex - 2];
                 object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (Int16)checked((Int16)l - (Int16)r);
+                frame.Data[frame.StackIndex - 2] = checked((Int16)((Int16)l - (Int16)r));
                 frame.StackIndex--;
                 return +1;
             }
@@ -176,7 +176,7 @@ namespace Microsoft.Scripting.Interpreter {
             public override int Run(InterpretedFrame frame) {
                 object l = frame.Data[frame.StackIndex - 2];
                 object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (Int64)checked((Int64)l - (Int64)r);
+                frame.Data[frame.StackIndex - 2] = checked((Int64)((Int64)l - (Int64)r));
                 frame.StackIndex--;
                 return +1;
             }
@@ -186,7 +186,7 @@ namespace Microsoft.Scripting.Interpreter {
             public override int Run(InterpretedFrame frame) {
                 object l = frame.Data[frame.StackIndex - 2];
                 object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (UInt16)checked((UInt16)l - (UInt16)r);
+                frame.Data[frame.StackIndex - 2] = checked((UInt16)((UInt16)l - (UInt16)r));
                 frame.StackIndex--;
                 return +1;
             }
@@ -196,7 +196,7 @@ namespace Microsoft.Scripting.Interpreter {
             public override int Run(InterpretedFrame frame) {
                 object l = frame.Data[frame.StackIndex - 2];
                 object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (UInt32)checked((UInt32)l - (UInt32)r);
+                frame.Data[frame.StackIndex - 2] = checked((UInt32)((UInt32)l - (UInt32)r));
                 frame.StackIndex--;
                 return +1;
             }
@@ -206,7 +206,7 @@ namespace Microsoft.Scripting.Interpreter {
             public override int Run(InterpretedFrame frame) {
                 object l = frame.Data[frame.StackIndex - 2];
                 object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (UInt64)checked((UInt64)l - (UInt64)r);
+                frame.Data[frame.StackIndex - 2] = checked((UInt64)((UInt64)l - (UInt64)r));
                 frame.StackIndex--;
                 return +1;
             }
index 320deb5b3a612579890b8c64a7e4ab909f6155ec..44354f7f41bc2db605af268ede01fce6692db898 100644 (file)
@@ -20,6 +20,7 @@ using System.Reflection;
 using System.Runtime.CompilerServices;
 using Microsoft.Scripting.Runtime;
 using Microsoft.Scripting.Utils;
+using System.Linq;
 
 namespace Microsoft.Scripting.Interpreter {
     internal sealed class CreateDelegateInstruction : Instruction {
@@ -160,4 +161,33 @@ namespace Microsoft.Scripting.Interpreter {
             get { return "TypeEquals()"; }
         }
     }
+
+    internal sealed class WrapToNullableInstruction<T> : Instruction {
+
+        readonly Type elementType;
+        ConstructorInfo ctor;
+
+        public override int ConsumedStack { get { return 1; } }
+        public override int ProducedStack { get { return 1; } }
+
+        internal WrapToNullableInstruction(Type elementType) {
+            this.elementType = elementType;
+        }
+
+        public override int Run(InterpretedFrame frame) {
+            var r = frame.Data[frame.StackIndex - 1];
+
+            // Don't need to wrap null values
+            if (r == null)
+                return 1;
+
+            ctor = typeof (Nullable<>).MakeGenericType (elementType).GetDeclaredConstructors ().First ();
+            frame.Data[frame.StackIndex - 1] = ctor.Invoke (new [] { r });
+            return 1;
+        }
+
+        public override string InstructionName {
+            get { return "WrapTo " + typeof(T) + "?"; }
+        }
+    }
 }
index 37360a8beed20efa67f2631f441dcf7a2dddfc09..21f285c02e68f71fd37d7b013133ac3d0bb0ff0f 100644 (file)
@@ -1,5 +1,5 @@
 ï»¿// 
-// AndbInstruction.cs:
+// XorInstruction.cs:
 //
 // Authors: Marek Safar (marek.safar@gmail.com)
 //     
@@ -34,6 +34,7 @@ using Microsoft.Scripting.Utils;
 namespace Microsoft.Scripting.Interpreter {
     internal abstract class XorInstruction : Instruction {
         private static Instruction _Int16, _Int32, _Int64, _UInt16, _UInt32, _UInt64, _Boolean;
+        private static Instruction _Int16Lifted, _Int32Lifted, _Int64Lifted, _UInt16Lifted, _UInt32Lifted, _UInt64Lifted, _BooleanLifted;
 
         public override int ConsumedStack { get { return 2; } }
         public override int ProducedStack { get { return 1; } }
@@ -43,9 +44,9 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class XorInt32 : XorInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = ScriptingRuntimeHelpers.Int32ToObject((Int32)l ^ (Int32)r);
+                var l = (Int32)frame.Data[frame.StackIndex - 2];
+                var r = (Int32)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = ScriptingRuntimeHelpers.Int32ToObject(l ^ r);
                 frame.StackIndex--;
                 return 1;
             }
@@ -53,9 +54,9 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class XorInt16 : XorInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (Int16)((Int16)l ^ (Int16)r);
+                var l = (Int16)frame.Data[frame.StackIndex - 2];
+                var r = (Int16)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int16)(l ^ r);
                 frame.StackIndex--;
                 return 1;
             }
@@ -63,9 +64,9 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class XorInt64 : XorInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (Int64)((Int64)l ^ (Int64)r);
+                var l = (Int64)frame.Data[frame.StackIndex - 2];
+                var r = (Int64)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int64)(l ^ r);
                 frame.StackIndex--;
                 return 1;
             }
@@ -73,9 +74,9 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class XorUInt16 : XorInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (UInt16)((UInt16)l ^ (UInt16)r);
+                var l = (UInt16)frame.Data[frame.StackIndex - 2];
+                var r = (UInt16)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt16)(l ^ r);
                 frame.StackIndex--;
                 return 1;
             }
@@ -83,9 +84,9 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class XorUInt32 : XorInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (UInt32)((UInt32)l ^ (UInt32)r);
+                var l = (UInt32)frame.Data[frame.StackIndex - 2];
+                var r = (UInt32)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt32)(l ^ r);
                 frame.StackIndex--;
                 return 1;
             }
@@ -93,9 +94,9 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class XorUInt64 : XorInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (UInt64)((UInt64)l ^ (UInt64)r);
+                var l = (UInt64)frame.Data[frame.StackIndex - 2];
+                var r = (UInt64)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt64)(l ^ r);
                 frame.StackIndex--;
                 return 1;
             }
@@ -103,9 +104,79 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class XorBoolean : XorInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (Boolean)((Boolean)l ^ (Boolean)r);
+                var l = (Boolean)frame.Data[frame.StackIndex - 2];
+                var r = (Boolean)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Boolean)(l ^ r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class XorInt32Lifted : XorInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Int32?)frame.Data[frame.StackIndex - 2];
+                var r = (Int32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int32?)(l ^ r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class XorInt16Lifted : XorInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Int16?)frame.Data[frame.StackIndex - 2];
+                var r = (Int16?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int16?)(l ^ r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class XorInt64Lifted : XorInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Int64?)frame.Data[frame.StackIndex - 2];
+                var r = (Int64?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int64?)(l ^ r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class XorUInt16Lifted : XorInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (UInt16?)frame.Data[frame.StackIndex - 2];
+                var r = (UInt16?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt16?)(l ^ r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class XorUInt32Lifted : XorInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (UInt32?)frame.Data[frame.StackIndex - 2];
+                var r = (UInt32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt32?)(l ^ r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class XorUInt64Lifted : XorInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (UInt64?)frame.Data[frame.StackIndex - 2];
+                var r = (UInt64?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt64?)(l ^ r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class XorBooleanLifted : XorInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Boolean?)frame.Data[frame.StackIndex - 2];
+                var r = (Boolean?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Boolean?)(l ^ r);
                 frame.StackIndex--;
                 return 1;
             }
@@ -127,6 +198,22 @@ namespace Microsoft.Scripting.Interpreter {
             }
         }
 
+        public static Instruction CreateLifted(Type type) {
+            Debug.Assert(!type.IsEnum());
+            switch (type.GetTypeCode()) {
+                case TypeCode.Int16: return _Int16Lifted ?? (_Int16Lifted = new XorInt16Lifted());
+                case TypeCode.Int32: return _Int32Lifted ?? (_Int32Lifted = new XorInt32Lifted());
+                case TypeCode.Int64: return _Int64Lifted ?? (_Int64Lifted = new XorInt64Lifted());
+                case TypeCode.UInt16: return _UInt16Lifted ?? (_UInt16Lifted = new XorUInt16Lifted());
+                case TypeCode.UInt32: return _UInt32Lifted ?? (_UInt32Lifted = new XorUInt32Lifted());
+                case TypeCode.UInt64: return _UInt64Lifted ?? (_UInt64Lifted = new XorUInt64Lifted());
+                case TypeCode.Boolean: return _BooleanLifted ?? (_BooleanLifted = new XorBooleanLifted());
+
+                default:
+                    throw Assert.Unreachable;
+            }
+        }
+
         public override string ToString() {
             return "Xor()";
         }
index fa98324b65449921682352b75edccc37d323ffda..32a1bd4e91e50172962eab8ba399da892d8b7659 100644 (file)
@@ -566,29 +566,29 @@ namespace Microsoft.Scripting.Interpreter {
                         return;
 
                     case ExpressionType.Equal:
-                        CompileEqual(node.Left, node.Right);
+                        CompileEqual(node.Left, node.Right, node.IsLiftedToNull);
                         return;
 
                     case ExpressionType.NotEqual:
-                        CompileNotEqual(node.Left, node.Right);
+                        CompileNotEqual(node.Left, node.Right, node.IsLiftedToNull);
                         return;
 
                     case ExpressionType.LessThan:
                     case ExpressionType.LessThanOrEqual:
                     case ExpressionType.GreaterThan:
                     case ExpressionType.GreaterThanOrEqual:
-                        CompileComparison(node.NodeType, node.Left, node.Right);
+                                               CompileComparison(node.NodeType, node.Left, node.Right, node.IsLiftedToNull);
                         return;
 
                     case ExpressionType.LeftShift:
                     case ExpressionType.RightShift:
-                        CompileShift(node.NodeType, node.Left, node.Right);
+                        CompileShift(node.NodeType, node.Left, node.Right, node.IsLifted);
                         return;
 
                     case ExpressionType.And:
                     case ExpressionType.Or:
                     case ExpressionType.ExclusiveOr:
-                        CompileLogical(node.NodeType, node.Left, node.Right);
+                        CompileLogical(node.NodeType, node.Left, node.Right, node.IsLifted);
                         return;
 
                     default:
@@ -597,34 +597,31 @@ namespace Microsoft.Scripting.Interpreter {
             }
         }
 
-        private void CompileEqual(Expression left, Expression right) {
+        private void CompileEqual(Expression left, Expression right, bool liftedResult) {
             Debug.Assert(left.Type == right.Type || !left.Type.IsValueType() && !right.Type.IsValueType());
             Compile(left);
             Compile(right);
-            _instructions.EmitEqual(left.Type);
+            _instructions.EmitEqual(left.Type, liftedResult);
         }
 
-        private void CompileNotEqual(Expression left, Expression right) {
+        private void CompileNotEqual(Expression left, Expression right, bool liftedResult) {
             Debug.Assert(left.Type == right.Type || !left.Type.IsValueType() && !right.Type.IsValueType());
             Compile(left);
             Compile(right);
-            _instructions.EmitNotEqual(left.Type);
+            _instructions.EmitNotEqual(left.Type, liftedResult);
         }
 
-        private void CompileComparison(ExpressionType nodeType, Expression left, Expression right) {
+               private void CompileComparison(ExpressionType nodeType, Expression left, Expression right, bool liftedResult) {
             Debug.Assert(left.Type == right.Type && TypeUtils.IsNumeric(left.Type));
 
-            // TODO:
-            // if (TypeUtils.IsNullableType(left.Type) && liftToNull) ...
-
             Compile(left);
             Compile(right);
             
             switch (nodeType) {
-                case ExpressionType.LessThan: _instructions.EmitLessThan(left.Type); break;
-                case ExpressionType.LessThanOrEqual: _instructions.EmitLessThanOrEqual(left.Type); break;
-                case ExpressionType.GreaterThan: _instructions.EmitGreaterThan(left.Type); break;
-                case ExpressionType.GreaterThanOrEqual: _instructions.EmitGreaterThanOrEqual(left.Type); break;
+                case ExpressionType.LessThan: _instructions.EmitLessThan(left.Type, liftedResult); break;
+                case ExpressionType.LessThanOrEqual: _instructions.EmitLessThanOrEqual(left.Type, liftedResult); break;
+                case ExpressionType.GreaterThan: _instructions.EmitGreaterThan(left.Type, liftedResult); break;
+                case ExpressionType.GreaterThanOrEqual: _instructions.EmitGreaterThanOrEqual(left.Type, liftedResult); break;
                 default: throw Assert.Unreachable;
             }
         }
@@ -646,25 +643,25 @@ namespace Microsoft.Scripting.Interpreter {
             }
         }
 
-        private void CompileShift(ExpressionType nodeType, Expression left, Expression right) {
-            Debug.Assert(right.Type == typeof (int));
+        private void CompileShift(ExpressionType nodeType, Expression left, Expression right, bool lifted) {
+            Debug.Assert(right.Type == typeof (int) || right.Type == typeof (int?));
             Compile(left);
             Compile(right);
             switch (nodeType) {
-                case ExpressionType.LeftShift: _instructions.EmitShl(left.Type); break;
-                case ExpressionType.RightShift: _instructions.EmitShr(left.Type); break;
+                case ExpressionType.LeftShift: _instructions.EmitShl(TypeUtils.GetNonNullableType (left.Type), lifted); break;
+                case ExpressionType.RightShift: _instructions.EmitShr(TypeUtils.GetNonNullableType (left.Type), lifted); break;
                 default: throw Assert.Unreachable;
             }
         }
 
-        private void CompileLogical(ExpressionType nodeType, Expression left, Expression right) {
-            Debug.Assert(left.Type == right.Type && TypeUtils.IsIntegerOrBool(left.Type));
+        private void CompileLogical(ExpressionType nodeType, Expression left, Expression right, bool lifted) {
+            Debug.Assert(left.Type == right.Type); // && TypeUtils.IsIntegerOrBool(left.Type));
             Compile(left);
             Compile(right);
             switch (nodeType) {
-                case ExpressionType.And: _instructions.EmitAnd(left.Type); break;
-                case ExpressionType.Or: _instructions.EmitOr(left.Type); break;
-                case ExpressionType.ExclusiveOr: _instructions.EmitExclusiveOr(left.Type); break;
+                case ExpressionType.And: _instructions.EmitAnd(TypeUtils.GetNonNullableType (left.Type), lifted); break;
+                case ExpressionType.Or: _instructions.EmitOr(TypeUtils.GetNonNullableType (left.Type), lifted); break;
+                case ExpressionType.ExclusiveOr: _instructions.EmitExclusiveOr(TypeUtils.GetNonNullableType (left.Type), lifted); break;
                 default: throw Assert.Unreachable;
             }
         }
@@ -674,6 +671,9 @@ namespace Microsoft.Scripting.Interpreter {
             if (node.Method != null) {
                 Compile(node.Operand);
 
+                               if (node.IsLifted)
+                                       throw new NotImplementedException ();
+
                 // We should be able to ignore Int32ToObject
                 if (node.Method != Runtime.ScriptingRuntimeHelpers.Int32ToObjectMethod) {
                     EmitCall(node.Method);
@@ -693,6 +693,32 @@ namespace Microsoft.Scripting.Interpreter {
                 return;
             }
 
+            if (TypeUtils.IsNullableType (typeTo)) {
+                typeFrom = TypeUtils.GetNonNullableType (typeFrom);
+                typeTo = TypeUtils.GetNonNullableType (typeTo);
+
+                var nullValue = _instructions.MakeLabel();
+                var end = _instructions.MakeLabel();
+
+                _instructions.EmitDup ();
+                _instructions.EmitBranchNull(nullValue);
+                CompileConvertToType (typeFrom, typeTo, isChecked);
+                _instructions.EmitWrap (typeTo);
+                _instructions.EmitBranch (end);                
+                _instructions.MarkLabel(nullValue);
+                _instructions.EmitDup (); // Keep null on the stack
+                _instructions.MarkLabel(end);
+                return;
+            }
+
+            if (TypeUtils.IsNullableType (typeFrom)) {
+                if (typeTo.IsClass)
+                    return;
+
+                // TODO: should throw same exception as (int)(int?)null
+                throw new NotImplementedException ();
+            }
+
             TypeCode from = typeFrom.GetTypeCode();
             TypeCode to = typeTo.GetTypeCode();
             if (TypeUtils.IsNumeric(from) && TypeUtils.IsNumeric(to)) {
@@ -709,14 +735,14 @@ namespace Microsoft.Scripting.Interpreter {
             return;
         }
 
-        private void CompileNegateExpression(UnaryExpression node, bool @checked) {
+        private void CompileNegateExpression(UnaryExpression node, bool @checked, bool lifted) {
             Compile(node.Operand);
-            _instructions.EmitNegate(node.Type, @checked);
+            _instructions.EmitNegate(TypeUtils.GetNonNullableType (node.Type), @checked, lifted);
         }
 
-        private void CompileNotExpression(UnaryExpression node) {
+        private void CompileNotExpression(UnaryExpression node, bool lifted) {
             Compile(node.Operand);
-            _instructions.EmitNot(node.Type);
+            _instructions.EmitNot(TypeUtils.GetNonNullableType (node.Type), lifted);
         }
 
         private void CompileUnaryExpression(Expression expr) {
@@ -732,13 +758,13 @@ namespace Microsoft.Scripting.Interpreter {
                         _instructions.EmitGetArrayLength (node.Type);
                         return;
                     case ExpressionType.Negate:
-                        CompileNegateExpression(node, false);
+                        CompileNegateExpression(node, false, node.IsLifted);
                         return;
                     case ExpressionType.NegateChecked:
-                        CompileNegateExpression(node, true);
+                        CompileNegateExpression(node, true, node.IsLifted);
                         return;                    
                     case ExpressionType.Not:
-                        CompileNotExpression(node);
+                        CompileNotExpression(node, node.IsLifted);
                         return;
                     case ExpressionType.UnaryPlus:
                         // unary plus is a nop:
@@ -1535,6 +1561,10 @@ namespace Microsoft.Scripting.Interpreter {
             var node = (TypeBinaryExpression)expr;
 
             Compile(node.Expression);
+            if (node.Expression.Type == typeof (void)) {
+                _instructions.Emit (InstructionFactory<bool>.Factory.DefaultValue ());
+                return;
+            }
 
             // use TypeEqual for sealed types:
             if (node.TypeOperand.IsSealed()) {