Welcome to mirror list, hosted at ThFree Co, Russian Federation.

github.com/mono/mono.git - Unnamed repository; edit this file 'description' to name the repository.
summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorMarek Safar <marek.safar@gmail.com>2014-01-26 14:34:00 +0400
committerMarek Safar <marek.safar@gmail.com>2014-01-26 14:35:09 +0400
commitf2eab9919dd6ab4548675197e4a7eaffd9816a6a (patch)
treed5318770896b3c3847405e1c395c2d9dea6b12aa /mcs/class/dlr
parent280f85db70b76e0f80605c9574a3bb3e17101a99 (diff)
[dlr] Handle more expressions in interpreter
Diffstat (limited to 'mcs/class/dlr')
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/AddInstruction.cs10
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/AndInstruction.cs129
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/ControlFlowInstructions.cs28
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/EqualInstruction.cs138
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/GreaterThanInstruction.cs176
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/GreaterThanOrEqualInstruction.cs248
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/InstructionFactory.cs6
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/InstructionList.cs81
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/LessThanInstruction.cs174
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/LessThanOrEqualInstruction.cs248
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/MulInstruction.cs10
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NegateInstruction.cs208
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NotEqualInstruction.cs138
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NotInstruction.cs96
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/OrInstruction.cs115
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/ShlInstruction.cs76
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/ShrInstruction.cs76
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/StackOperations.cs3
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/SubInstruction.cs10
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/TypeOperations.cs30
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/XorInstruction.cs131
-rw-r--r--mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/LightCompiler.cs96
22 files changed, 1952 insertions, 275 deletions
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/AddInstruction.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/AddInstruction.cs
index 1f1775c180f..3846e4d215f 100644
--- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/AddInstruction.cs
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/AddInstruction.cs
@@ -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;
}
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/AndInstruction.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/AndInstruction.cs
index 09ec87df22a..2b423f581f0 100644
--- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/AndInstruction.cs
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/AndInstruction.cs
@@ -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()";
}
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/ControlFlowInstructions.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/ControlFlowInstructions.cs
index 376488e08f9..b7549ee4b77 100644
--- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/ControlFlowInstructions.cs
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/ControlFlowInstructions.cs
@@ -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;
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/EqualInstruction.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/EqualInstruction.cs
index e4edde9bab2..38e904d3eae 100644
--- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/EqualInstruction.cs
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/EqualInstruction.cs
@@ -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()";
}
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/GreaterThanInstruction.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/GreaterThanInstruction.cs
index a35f16b0e34..8849613fd51 100644
--- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/GreaterThanInstruction.cs
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/GreaterThanInstruction.cs
@@ -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
index 00000000000..de2da8fd965
--- /dev/null
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/GreaterThanOrEqualInstruction.cs
@@ -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()";
+ }
+ }
+}
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/InstructionFactory.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/InstructionFactory.cs
index ca0be0924d3..5f916ce64b6 100644
--- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/InstructionFactory.cs
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/InstructionFactory.cs
@@ -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));
+ }
}
}
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/InstructionList.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/InstructionList.cs
index 3fa74e9b967..28746e65c6b 100644
--- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/InstructionList.cs
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/InstructionList.cs
@@ -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);
}
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/LessThanInstruction.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/LessThanInstruction.cs
index 2875e8bf9cd..3bde7a4ee8f 100644
--- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/LessThanInstruction.cs
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/LessThanInstruction.cs
@@ -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
index 00000000000..6c120f59349
--- /dev/null
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/LessThanOrEqualInstruction.cs
@@ -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()";
+ }
+ }
+}
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/MulInstruction.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/MulInstruction.cs
index 4529adc4512..745e1a0bcad 100644
--- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/MulInstruction.cs
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/MulInstruction.cs
@@ -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;
}
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NegateInstruction.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NegateInstruction.cs
index 58c60f6803b..5652f5bc78b 100644
--- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NegateInstruction.cs
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NegateInstruction.cs
@@ -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()";
}
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NotEqualInstruction.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NotEqualInstruction.cs
index f7da9f46dd3..2bd1224374f 100644
--- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NotEqualInstruction.cs
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NotEqualInstruction.cs
@@ -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()";
}
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NotInstruction.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NotInstruction.cs
index 3cfce546518..e1eb3d8bd11 100644
--- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NotInstruction.cs
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NotInstruction.cs
@@ -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()";
}
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/OrInstruction.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/OrInstruction.cs
index b183b689042..baaad40fb70 100644
--- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/OrInstruction.cs
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/OrInstruction.cs
@@ -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()";
}
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/ShlInstruction.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/ShlInstruction.cs
index 4db455315ab..5406dd01b00 100644
--- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/ShlInstruction.cs
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/ShlInstruction.cs
@@ -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()";
}
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/ShrInstruction.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/ShrInstruction.cs
index cefb800f17b..5099a41c18b 100644
--- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/ShrInstruction.cs
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/ShrInstruction.cs
@@ -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()";
}
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/StackOperations.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/StackOperations.cs
index e2c9e7d1ab7..6cff464f0aa 100644
--- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/StackOperations.cs
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/StackOperations.cs
@@ -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;
}
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/SubInstruction.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/SubInstruction.cs
index 4571e4f930e..8ca97e97f7e 100644
--- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/SubInstruction.cs
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/SubInstruction.cs
@@ -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;
}
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/TypeOperations.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/TypeOperations.cs
index 320deb5b3a6..44354f7f41b 100644
--- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/TypeOperations.cs
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/TypeOperations.cs
@@ -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) + "?"; }
+ }
+ }
}
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/XorInstruction.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/XorInstruction.cs
index 37360a8beed..21f285c02e6 100644
--- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/XorInstruction.cs
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/Instructions/XorInstruction.cs
@@ -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()";
}
diff --git a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/LightCompiler.cs b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/LightCompiler.cs
index fa98324b654..32a1bd4e91e 100644
--- a/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/LightCompiler.cs
+++ b/mcs/class/dlr/Runtime/Microsoft.Dynamic/Interpreter/LightCompiler.cs
@@ -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()) {