1 /* ****************************************************************************
3 * Copyright (c) Microsoft Corporation.
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.
11 * You must not remove this notice, or any other, from this software.
14 * ***************************************************************************/
17 using System.Diagnostics;
18 using Microsoft.Scripting.Runtime;
19 using Microsoft.Scripting.Utils;
21 namespace Microsoft.Scripting.Interpreter {
22 internal abstract class AddInstruction : Instruction {
23 private static Instruction _Int16, _Int32, _Int64, _UInt16, _UInt32, _UInt64, _Single, _Double;
25 public override int ConsumedStack { get { return 2; } }
26 public override int ProducedStack { get { return 1; } }
28 private AddInstruction() {
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));
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);
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);
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);
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);
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);
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);
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;
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());
124 throw Assert.Unreachable;
128 public override string ToString() {
133 internal abstract class AddOvfInstruction : Instruction {
134 private static Instruction _Int16, _Int32, _Int64, _UInt16, _UInt32, _UInt64, _Single, _Double;
136 public override int ConsumedStack { get { return 2; } }
137 public override int ProducedStack { get { return 1; } }
139 private AddOvfInstruction() {
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));
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));
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));
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));
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));
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));
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);
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;
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());
235 throw Assert.Unreachable;
239 public override string ToString() {