Merge pull request #900 from Blewzman/FixAggregateExceptionGetBaseException
[mono.git] / mcs / class / dlr / Runtime / Microsoft.Dynamic / Interpreter / Instructions / AddInstruction.cs
1 /* ****************************************************************************
2  *
3  * Copyright (c) Microsoft Corporation. 
4  *
5  * This source code is subject to terms and conditions of the Apache License, Version 2.0. A 
6  * copy of the license can be found in the License.html file at the root of this distribution. If 
7  * you cannot locate the  Apache License, Version 2.0, please send an email to 
8  * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound 
9  * by the terms of the Apache License, Version 2.0.
10  *
11  * You must not remove this notice, or any other, from this software.
12  *
13  *
14  * ***************************************************************************/
15
16 using System;
17 using System.Diagnostics;
18 using Microsoft.Scripting.Runtime;
19 using Microsoft.Scripting.Utils;
20
21 namespace Microsoft.Scripting.Interpreter {
22     internal abstract class AddInstruction : Instruction {
23         private static Instruction _Int16, _Int32, _Int64, _UInt16, _UInt32, _UInt64, _Single, _Double;
24
25         public override int ConsumedStack { get { return 2; } }
26         public override int ProducedStack { get { return 1; } }
27
28         private AddInstruction() {
29         }
30
31         internal sealed class AddInt32 : AddInstruction {
32             public override int Run(InterpretedFrame frame) {
33                 object l = frame.Data[frame.StackIndex - 2];
34                 object r = frame.Data[frame.StackIndex - 1];
35                 frame.Data[frame.StackIndex - 2] = ScriptingRuntimeHelpers.Int32ToObject(unchecked((Int32)l + (Int32)r));
36                 frame.StackIndex--;
37                 return +1;
38             }
39         }
40
41         internal sealed class AddInt16 : AddInstruction {
42             public override int Run(InterpretedFrame frame) {
43                 object l = frame.Data[frame.StackIndex - 2];
44                 object r = frame.Data[frame.StackIndex - 1];
45                 frame.Data[frame.StackIndex - 2] = (Int16)unchecked((Int16)l + (Int16)r);
46                 frame.StackIndex--;
47                 return +1;
48             }
49         }
50
51         internal sealed class AddInt64 : AddInstruction {
52             public override int Run(InterpretedFrame frame) {
53                 object l = frame.Data[frame.StackIndex - 2];
54                 object r = frame.Data[frame.StackIndex - 1];
55                 frame.Data[frame.StackIndex - 2] = (Int64)unchecked((Int64)l + (Int64)r);
56                 frame.StackIndex--;
57                 return +1;
58             }
59         }
60
61         internal sealed class AddUInt16 : AddInstruction {
62             public override int Run(InterpretedFrame frame) {
63                 object l = frame.Data[frame.StackIndex - 2];
64                 object r = frame.Data[frame.StackIndex - 1];
65                 frame.Data[frame.StackIndex - 2] = (UInt16)unchecked((UInt16)l + (UInt16)r);
66                 frame.StackIndex--;
67                 return +1;
68             }
69         }
70
71         internal sealed class AddUInt32 : AddInstruction {
72             public override int Run(InterpretedFrame frame) {
73                 object l = frame.Data[frame.StackIndex - 2];
74                 object r = frame.Data[frame.StackIndex - 1];
75                 frame.Data[frame.StackIndex - 2] = (UInt32)unchecked((UInt32)l + (UInt32)r);
76                 frame.StackIndex--;
77                 return +1;
78             }
79         }
80
81         internal sealed class AddUInt64 : AddInstruction {
82             public override int Run(InterpretedFrame frame) {
83                 object l = frame.Data[frame.StackIndex - 2];
84                 object r = frame.Data[frame.StackIndex - 1];
85                 frame.Data[frame.StackIndex - 2] = (UInt64)unchecked((UInt64)l + (UInt64)r);
86                 frame.StackIndex--;
87                 return +1;
88             }
89         }
90
91         internal sealed class AddSingle : AddInstruction {
92             public override int Run(InterpretedFrame frame) {
93                 object l = frame.Data[frame.StackIndex - 2];
94                 object r = frame.Data[frame.StackIndex - 1];
95                 frame.Data[frame.StackIndex - 2] = (Single)((Single)l + (Single)r);
96                 frame.StackIndex--;
97                 return +1;
98             }
99         }
100
101         internal sealed class AddDouble : AddInstruction {
102             public override int Run(InterpretedFrame frame) {
103                 object l = frame.Data[frame.StackIndex - 2];
104                 object r = frame.Data[frame.StackIndex - 1];
105                 frame.Data[frame.StackIndex - 2] = (Double)l + (Double)r;
106                 frame.StackIndex--;
107                 return +1;
108             }
109         }
110
111         public static Instruction Create(Type type) {
112             Debug.Assert(!type.IsEnum());
113             switch (type.GetTypeCode()) {
114                 case TypeCode.Int16: return _Int16 ?? (_Int16 = new AddInt16());
115                 case TypeCode.Int32: return _Int32 ?? (_Int32 = new AddInt32());
116                 case TypeCode.Int64: return _Int64 ?? (_Int64 = new AddInt64());
117                 case TypeCode.UInt16: return _UInt16 ?? (_UInt16 = new AddUInt16());
118                 case TypeCode.UInt32: return _UInt32 ?? (_UInt32 = new AddUInt32());
119                 case TypeCode.UInt64: return _UInt64 ?? (_UInt64 = new AddUInt64());
120                 case TypeCode.Single: return _Single ?? (_Single = new AddSingle());
121                 case TypeCode.Double: return _Double ?? (_Double = new AddDouble());
122
123                 default:
124                     throw Assert.Unreachable;
125             }
126         }
127
128         public override string ToString() {
129             return "Add()";
130         }
131     }
132
133     internal abstract class AddOvfInstruction : Instruction {
134         private static Instruction _Int16, _Int32, _Int64, _UInt16, _UInt32, _UInt64, _Single, _Double;
135
136         public override int ConsumedStack { get { return 2; } }
137         public override int ProducedStack { get { return 1; } }
138
139         private AddOvfInstruction() {
140         }
141
142         internal sealed class AddOvfInt32 : AddOvfInstruction {
143             public override int Run(InterpretedFrame frame) {
144                 object l = frame.Data[frame.StackIndex - 2];
145                 object r = frame.Data[frame.StackIndex - 1];
146                 frame.Data[frame.StackIndex - 2] = ScriptingRuntimeHelpers.Int32ToObject(checked((Int32)l + (Int32)r));
147                 frame.StackIndex--;
148                 return +1;
149             }
150         }
151
152         internal sealed class AddOvfInt16 : AddOvfInstruction {
153             public override int Run(InterpretedFrame frame) {
154                 object l = frame.Data[frame.StackIndex - 2];
155                 object r = frame.Data[frame.StackIndex - 1];
156                 frame.Data[frame.StackIndex - 2] = checked((Int16)((Int16)l + (Int16)r));
157                 frame.StackIndex--;
158                 return +1;
159             }
160         }
161
162         internal sealed class AddOvfInt64 : AddOvfInstruction {
163             public override int Run(InterpretedFrame frame) {
164                 object l = frame.Data[frame.StackIndex - 2];
165                 object r = frame.Data[frame.StackIndex - 1];
166                 frame.Data[frame.StackIndex - 2] = checked((Int64)((Int64)l + (Int64)r));
167                 frame.StackIndex--;
168                 return +1;
169             }
170         }
171
172         internal sealed class AddOvfUInt16 : AddOvfInstruction {
173             public override int Run(InterpretedFrame frame) {
174                 object l = frame.Data[frame.StackIndex - 2];
175                 object r = frame.Data[frame.StackIndex - 1];
176                 frame.Data[frame.StackIndex - 2] = checked((UInt16)((UInt16)l + (UInt16)r));
177                 frame.StackIndex--;
178                 return +1;
179             }
180         }
181
182         internal sealed class AddOvfUInt32 : AddOvfInstruction {
183             public override int Run(InterpretedFrame frame) {
184                 object l = frame.Data[frame.StackIndex - 2];
185                 object r = frame.Data[frame.StackIndex - 1];
186                 frame.Data[frame.StackIndex - 2] = checked((UInt32)((UInt32)l + (UInt32)r));
187                 frame.StackIndex--;
188                 return +1;
189             }
190         }
191
192         internal sealed class AddOvfUInt64 : AddOvfInstruction {
193             public override int Run(InterpretedFrame frame) {
194                 object l = frame.Data[frame.StackIndex - 2];
195                 object r = frame.Data[frame.StackIndex - 1];
196                 frame.Data[frame.StackIndex - 2] = checked((UInt64)((UInt64)l + (UInt64)r));
197                 frame.StackIndex--;
198                 return +1;
199             }
200         }
201
202         internal sealed class AddOvfSingle : AddOvfInstruction {
203             public override int Run(InterpretedFrame frame) {
204                 object l = frame.Data[frame.StackIndex - 2];
205                 object r = frame.Data[frame.StackIndex - 1];
206                 frame.Data[frame.StackIndex - 2] = (Single)((Single)l + (Single)r);
207                 frame.StackIndex--;
208                 return +1;
209             }
210         }
211
212         internal sealed class AddOvfDouble : AddOvfInstruction {
213             public override int Run(InterpretedFrame frame) {
214                 object l = frame.Data[frame.StackIndex - 2];
215                 object r = frame.Data[frame.StackIndex - 1];
216                 frame.Data[frame.StackIndex - 2] = (Double)l + (Double)r;
217                 frame.StackIndex--;
218                 return +1;
219             }
220         }
221
222         public static Instruction Create(Type type) {
223             Debug.Assert(!type.IsEnum());
224             switch (type.GetTypeCode()) {
225                 case TypeCode.Int16: return _Int16 ?? (_Int16 = new AddOvfInt16());
226                 case TypeCode.Int32: return _Int32 ?? (_Int32 = new AddOvfInt32());
227                 case TypeCode.Int64: return _Int64 ?? (_Int64 = new AddOvfInt64());
228                 case TypeCode.UInt16: return _UInt16 ?? (_UInt16 = new AddOvfUInt16());
229                 case TypeCode.UInt32: return _UInt32 ?? (_UInt32 = new AddOvfUInt32());
230                 case TypeCode.UInt64: return _UInt64 ?? (_UInt64 = new AddOvfUInt64());
231                 case TypeCode.Single: return _Single ?? (_Single = new AddOvfSingle());
232                 case TypeCode.Double: return _Double ?? (_Double = new AddOvfDouble());
233
234                 default:
235                     throw Assert.Unreachable;
236             }
237         }
238
239         public override string ToString() {
240             return "AddOvf()";
241         }
242     }
243 }