Merge pull request #901 from Blewzman/FixAggregateExceptionGetBaseException
[mono.git] / mcs / class / dlr / Runtime / Microsoft.Dynamic / Interpreter / Instructions / NotInstruction.cs
1 // 
2 // NotInstruction.cs:
3 //
4 // Authors: Marek Safar (marek.safar@gmail.com)
5 //     
6 // Copyright 2014 Xamarin Inc
7 //
8 // Permission is hereby granted, free of charge, to any person obtaining
9 // a copy of this software and associated documentation files (the
10 // "Software"), to deal in the Software without restriction, including
11 // without limitation the rights to use, copy, modify, merge, publish,
12 // distribute, sublicense, and/or sell copies of the Software, and to
13 // permit persons to whom the Software is furnished to do so, subject to
14 // the following conditions:
15 // 
16 // The above copyright notice and this permission notice shall be
17 // included in all copies or substantial portions of the Software.
18 // 
19 // THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND,
20 // EXPRESS OR IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF
21 // MERCHANTABILITY, FITNESS FOR A PARTICULAR PURPOSE AND
22 // NONINFRINGEMENT. IN NO EVENT SHALL THE AUTHORS OR COPYRIGHT HOLDERS BE
23 // LIABLE FOR ANY CLAIM, DAMAGES OR OTHER LIABILITY, WHETHER IN AN ACTION
24 // OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, OUT OF OR IN CONNECTION
25 // WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE SOFTWARE.
26 //
27 //
28
29 using System;
30 using System.Diagnostics;
31 using Microsoft.Scripting.Runtime;
32 using Microsoft.Scripting.Utils;
33
34 namespace Microsoft.Scripting.Interpreter {
35     internal abstract class NotInstruction : Instruction {
36         private static Instruction _Int16, _Int32, _Int64, _UInt16, _UInt32, _UInt64, _Boolean;
37         private static Instruction _Int16Lifted, _Int32Lifted, _Int64Lifted, _UInt16Lifted, _UInt32Lifted, _UInt64Lifted, _BooleanLifted;
38
39         public override int ConsumedStack { get { return 1; } }
40         public override int ProducedStack { get { return 1; } }
41
42         private NotInstruction() {
43         }
44
45         internal sealed class NotBoolean : NotInstruction {
46             public override int Run(InterpretedFrame frame) {
47                 frame.Push((bool)frame.Pop() ? ScriptingRuntimeHelpers.False : ScriptingRuntimeHelpers.True);
48                 return 1;
49             }
50         }
51
52         internal sealed class NotInt32 : NotInstruction {
53             public override int Run(InterpretedFrame frame) {
54                 var v = (Int32)frame.Data[frame.StackIndex - 1];
55                 frame.Data[frame.StackIndex - 1] = ScriptingRuntimeHelpers.Int32ToObject(~v);
56                 return 1;
57             }
58         }
59
60         internal sealed class NotInt16 : NotInstruction {
61             public override int Run(InterpretedFrame frame) {
62                 var v = (Int16)frame.Data[frame.StackIndex - 1];
63                 frame.Data[frame.StackIndex - 1] = (Int16)(~v);
64                 return 1;
65             }
66         }
67
68         internal sealed class NotInt64 : NotInstruction {
69             public override int Run(InterpretedFrame frame) {
70                 var v = (Int64)frame.Data[frame.StackIndex - 1];
71                 frame.Data[frame.StackIndex - 1] = (Int64)(~v);
72                 return 1;
73             }
74         }
75
76         internal sealed class NotUInt16 : NotInstruction {
77             public override int Run(InterpretedFrame frame) {
78                 var v = (UInt64)frame.Data[frame.StackIndex - 1];
79                 frame.Data[frame.StackIndex - 1] = (UInt64)(~v);
80                 return 1;
81             }
82         }
83
84         internal sealed class NotUInt32 : NotInstruction {
85             public override int Run(InterpretedFrame frame) {
86                 var v = (UInt32)frame.Data[frame.StackIndex - 1];
87                 frame.Data[frame.StackIndex - 1] = (UInt32)(~v);
88                 return 1;
89             }
90         }
91
92         internal sealed class NotUInt64 : NotInstruction {
93             public override int Run(InterpretedFrame frame) {
94                 var v = (UInt64)frame.Data[frame.StackIndex - 1];
95                 frame.Data[frame.StackIndex - 1] = (UInt64)(~v);
96                 return 1;
97             }
98         }
99
100         internal sealed class NotBooleanLifted : NotInstruction {
101             public override int Run(InterpretedFrame frame) {
102                 var v = (Boolean?)frame.Data[frame.StackIndex - 1];
103                 frame.Data[frame.StackIndex - 1] = (Boolean?)(!v);
104                 return 1;
105             }
106         }
107
108         internal sealed class NotInt32Lifted : NotInstruction {
109             public override int Run(InterpretedFrame frame) {
110                 var v = (Int32?)frame.Data[frame.StackIndex - 1];
111                 frame.Data[frame.StackIndex - 1] = (Int32?)(~v);
112                 return 1;
113             }
114         }
115
116         internal sealed class NotInt16Lifted : NotInstruction {
117             public override int Run(InterpretedFrame frame) {
118                 var v = (Int16?)frame.Data[frame.StackIndex - 1];
119                 frame.Data[frame.StackIndex - 1] = (Int16?)(~v);
120                 return 1;
121             }
122         }
123
124         internal sealed class NotInt64Lifted : NotInstruction {
125             public override int Run(InterpretedFrame frame) {
126                 var v = (Int64?)frame.Data[frame.StackIndex - 1];
127                 frame.Data[frame.StackIndex - 1] = (Int64?)(~v);
128                 return 1;
129             }
130         }
131
132         internal sealed class NotUInt16Lifted : NotInstruction {
133             public override int Run(InterpretedFrame frame) {
134                 var v = (UInt64?)frame.Data[frame.StackIndex - 1];
135                 frame.Data[frame.StackIndex - 1] = (UInt64?)(~v);
136                 return 1;
137             }
138         }
139
140         internal sealed class NotUInt32Lifted : NotInstruction {
141             public override int Run(InterpretedFrame frame) {
142                 var v = (UInt32?)frame.Data[frame.StackIndex - 1];
143                 frame.Data[frame.StackIndex - 1] = (UInt32?)(~v);
144                 return 1;
145             }
146         }
147
148         internal sealed class NotUInt64Lifted : NotInstruction {
149             public override int Run(InterpretedFrame frame) {
150                 var v = (UInt64?)frame.Data[frame.StackIndex - 1];
151                 frame.Data[frame.StackIndex - 1] = (UInt64?)(~v);
152                 return 1;
153             }
154         }
155
156         public static Instruction Create(Type type) {
157             Debug.Assert(!type.IsEnum());
158             switch (type.GetTypeCode()) {
159                 case TypeCode.Int16: return _Int16 ?? (_Int16 = new NotInt16());
160                 case TypeCode.Int32: return _Int32 ?? (_Int32 = new NotInt32());
161                 case TypeCode.Int64: return _Int64 ?? (_Int64 = new NotInt64());
162                 case TypeCode.UInt16: return _UInt16 ?? (_UInt16 = new NotUInt16());
163                 case TypeCode.UInt32: return _UInt32 ?? (_UInt32 = new NotUInt32());
164                 case TypeCode.UInt64: return _UInt64 ?? (_UInt64 = new NotUInt64());
165                 case TypeCode.Boolean: return _Boolean ?? (_Boolean = new NotBoolean());
166
167                 default:
168                     throw Assert.Unreachable;
169             }
170         }
171
172         public static Instruction CreateLifted(Type type) {
173             Debug.Assert(!type.IsEnum());
174             switch (type.GetTypeCode()) {
175                 case TypeCode.Int16: return _Int16Lifted ?? (_Int16Lifted = new NotInt16Lifted());
176                 case TypeCode.Int32: return _Int32Lifted ?? (_Int32Lifted = new NotInt32Lifted());
177                 case TypeCode.Int64: return _Int64Lifted ?? (_Int64Lifted = new NotInt64Lifted());
178                 case TypeCode.UInt16: return _UInt16Lifted ?? (_UInt16Lifted = new NotUInt16Lifted());
179                 case TypeCode.UInt32: return _UInt32Lifted ?? (_UInt32Lifted = new NotUInt32Lifted());
180                 case TypeCode.UInt64: return _UInt64Lifted ?? (_UInt64Lifted = new NotUInt64Lifted());
181                 case TypeCode.Boolean: return _BooleanLifted ?? (_BooleanLifted = new NotBooleanLifted());
182
183                 default:
184                     throw Assert.Unreachable;
185             }
186         }
187         public override string ToString() {
188             return "Not()";
189         }
190     }
191 }