[dlr] Handle more expressions in interpreter
[mono.git] / mcs / class / dlr / Runtime / Microsoft.Dynamic / Interpreter / Instructions / AndInstruction.cs
index 09ec87df22ac85bb5fe47576280a0eac3c6c7d50..2b423f581f0d3f421958d380fb7bea6a893bc6d8 100644 (file)
@@ -34,6 +34,7 @@ using Microsoft.Scripting.Utils;
 namespace Microsoft.Scripting.Interpreter {
     internal abstract class AndInstruction : Instruction {
         private static Instruction _Int16, _Int32, _Int64, _UInt16, _UInt32, _UInt64, _Boolean;
+        private static Instruction _Int16Lifted, _Int32Lifted, _Int64Lifted, _UInt16Lifted, _UInt32Lifted, _UInt64Lifted, _BooleanLifted;
 
         public override int ConsumedStack { get { return 2; } }
         public override int ProducedStack { get { return 1; } }
@@ -43,9 +44,9 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class AndInt32 : AndInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = ScriptingRuntimeHelpers.Int32ToObject((Int32)l & (Int32)r);
+                var l = (Int32)frame.Data[frame.StackIndex - 2];
+                var r = (Int32)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = ScriptingRuntimeHelpers.Int32ToObject(l & r);
                 frame.StackIndex--;
                 return 1;
             }
@@ -53,9 +54,9 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class AndInt16 : AndInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (Int16)((Int16)l & (Int16)r);
+                var l = (Int16)frame.Data[frame.StackIndex - 2];
+                var r = (Int16)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int16)(l & r);
                 frame.StackIndex--;
                 return 1;
             }
@@ -63,9 +64,9 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class AndInt64 : AndInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (Int64)((Int64)l & (Int64)r);
+                var l = (Int64)frame.Data[frame.StackIndex - 2];
+                var r = (Int64)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int64)(l & r);
                 frame.StackIndex--;
                 return 1;
             }
@@ -73,9 +74,9 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class AndUInt16 : AndInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (UInt16)((UInt16)l & (UInt16)r);
+                var l = (UInt16)frame.Data[frame.StackIndex - 2];
+                var r = (UInt16)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt16)(l & r);
                 frame.StackIndex--;
                 return 1;
             }
@@ -83,9 +84,9 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class AndUInt32 : AndInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (UInt32)((UInt32)l & (UInt32)r);
+                var l = (UInt32)frame.Data[frame.StackIndex - 2];
+                var r = (UInt32)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt32)(l & r);
                 frame.StackIndex--;
                 return 1;
             }
@@ -93,9 +94,9 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class AndUInt64 : AndInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (UInt64)((UInt64)l & (UInt64)r);
+                var l = (UInt64)frame.Data[frame.StackIndex - 2];
+                var r = (UInt64)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt64)(l & r);
                 frame.StackIndex--;
                 return 1;
             }
@@ -103,9 +104,79 @@ namespace Microsoft.Scripting.Interpreter {
 
         internal sealed class AndBoolean : AndInstruction {
             public override int Run(InterpretedFrame frame) {
-                object l = frame.Data[frame.StackIndex - 2];
-                object r = frame.Data[frame.StackIndex - 1];
-                frame.Data[frame.StackIndex - 2] = (Boolean)((Boolean)l & (Boolean)r);
+                var l = (Boolean)frame.Data[frame.StackIndex - 2];
+                var r = (Boolean)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Boolean)(l & r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class AndInt32Lifted : AndInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Int32?)frame.Data[frame.StackIndex - 2];
+                var r = (Int32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int32?)(l & r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class AndInt16Lifted : AndInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Int16?)frame.Data[frame.StackIndex - 2];
+                var r = (Int16?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int16?)(l & r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class AndInt64Lifted : AndInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Int64?)frame.Data[frame.StackIndex - 2];
+                var r = (Int64?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Int64?)(l & r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class AndUInt16Lifted : AndInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (UInt16?)frame.Data[frame.StackIndex - 2];
+                var r = (UInt16?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt16?)(l & r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class AndUInt32Lifted : AndInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (UInt32?)frame.Data[frame.StackIndex - 2];
+                var r = (UInt32?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt32?)(l & r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class AndUInt64Lifted : AndInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (UInt64?)frame.Data[frame.StackIndex - 2];
+                var r = (UInt64?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (UInt64?)(l & r);
+                frame.StackIndex--;
+                return 1;
+            }
+        }
+
+        internal sealed class AndBooleanLifted : AndInstruction {
+            public override int Run(InterpretedFrame frame) {
+                var l = (Boolean?)frame.Data[frame.StackIndex - 2];
+                var r = (Boolean?)frame.Data[frame.StackIndex - 1];
+                frame.Data[frame.StackIndex - 2] = (Boolean?)(l & r);
                 frame.StackIndex--;
                 return 1;
             }
@@ -127,6 +198,22 @@ namespace Microsoft.Scripting.Interpreter {
             }
         }
 
+        public static Instruction CreateLifted(Type type) {
+            Debug.Assert(!type.IsEnum());
+            switch (type.GetTypeCode()) {
+                case TypeCode.Int16: return _Int16Lifted ?? (_Int16Lifted = new AndInt16Lifted());
+                case TypeCode.Int32: return _Int32Lifted ?? (_Int32Lifted = new AndInt32Lifted());
+                case TypeCode.Int64: return _Int64Lifted ?? (_Int64Lifted = new AndInt64Lifted());
+                case TypeCode.UInt16: return _UInt16Lifted ?? (_UInt16Lifted = new AndUInt16Lifted());
+                case TypeCode.UInt32: return _UInt32Lifted ?? (_UInt32Lifted = new AndUInt32Lifted());
+                case TypeCode.UInt64: return _UInt64Lifted ?? (_UInt64Lifted = new AndUInt64Lifted());
+                case TypeCode.Boolean: return _BooleanLifted ?? (_BooleanLifted = new AndBooleanLifted());
+
+                default:
+                    throw Assert.Unreachable;
+            }
+        }
+
         public override string ToString() {
             return "And()";
         }