/IronPython_Main/Runtime/Microsoft.Dynamic/Interpreter/Instructions/NumericConvertInstruction.cs

# · C# · 254 lines · 219 code · 21 blank · 14 comment · 10 complexity · 17b8e65d63fe23fc14c3f3f08d98afe1 MD5 · raw file

  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. using System;
  16. using System.Collections.Generic;
  17. using System.Diagnostics;
  18. using System.Reflection;
  19. using System.Runtime.CompilerServices;
  20. using Microsoft.Scripting.Runtime;
  21. using Microsoft.Scripting.Utils;
  22. namespace Microsoft.Scripting.Interpreter {
  23. internal abstract class NumericConvertInstruction : Instruction {
  24. internal readonly TypeCode _from, _to;
  25. protected NumericConvertInstruction(TypeCode from, TypeCode to) {
  26. _from = from;
  27. _to = to;
  28. }
  29. public override int ConsumedStack { get { return 1; } }
  30. public override int ProducedStack { get { return 1; } }
  31. public override string ToString() {
  32. return InstructionName + "(" + _from + "->" + _to + ")";
  33. }
  34. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
  35. public sealed class Unchecked : NumericConvertInstruction {
  36. public override string InstructionName { get { return "UncheckedConvert"; } }
  37. public Unchecked(TypeCode from, TypeCode to)
  38. : base(from, to) {
  39. }
  40. public override int Run(InterpretedFrame frame) {
  41. frame.Push(Convert(frame.Pop()));
  42. return +1;
  43. }
  44. private object Convert(object obj) {
  45. switch (_from) {
  46. case TypeCode.Byte: return ConvertInt32((Byte)obj);
  47. case TypeCode.SByte: return ConvertInt32((SByte)obj);
  48. case TypeCode.Int16: return ConvertInt32((Int16)obj);
  49. case TypeCode.Char: return ConvertInt32((Char)obj);
  50. case TypeCode.Int32: return ConvertInt32((Int32)obj);
  51. case TypeCode.Int64: return ConvertInt64((Int64)obj);
  52. case TypeCode.UInt16: return ConvertInt32((UInt16)obj);
  53. case TypeCode.UInt32: return ConvertInt64((UInt32)obj);
  54. case TypeCode.UInt64: return ConvertUInt64((UInt64)obj);
  55. case TypeCode.Single: return ConvertDouble((Single)obj);
  56. case TypeCode.Double: return ConvertDouble((Double)obj);
  57. default: throw Assert.Unreachable;
  58. }
  59. }
  60. private object ConvertInt32(int obj) {
  61. unchecked {
  62. switch (_to) {
  63. case TypeCode.Byte: return (Byte)obj;
  64. case TypeCode.SByte: return (SByte)obj;
  65. case TypeCode.Int16: return (Int16)obj;
  66. case TypeCode.Char: return (Char)obj;
  67. case TypeCode.Int32: return (Int32)obj;
  68. case TypeCode.Int64: return (Int64)obj;
  69. case TypeCode.UInt16: return (UInt16)obj;
  70. case TypeCode.UInt32: return (UInt32)obj;
  71. case TypeCode.UInt64: return (UInt64)obj;
  72. case TypeCode.Single: return (Single)obj;
  73. case TypeCode.Double: return (Double)obj;
  74. default: throw Assert.Unreachable;
  75. }
  76. }
  77. }
  78. private object ConvertInt64(Int64 obj) {
  79. unchecked {
  80. switch (_to) {
  81. case TypeCode.Byte: return (Byte)obj;
  82. case TypeCode.SByte: return (SByte)obj;
  83. case TypeCode.Int16: return (Int16)obj;
  84. case TypeCode.Char: return (Char)obj;
  85. case TypeCode.Int32: return (Int32)obj;
  86. case TypeCode.Int64: return (Int64)obj;
  87. case TypeCode.UInt16: return (UInt16)obj;
  88. case TypeCode.UInt32: return (UInt32)obj;
  89. case TypeCode.UInt64: return (UInt64)obj;
  90. case TypeCode.Single: return (Single)obj;
  91. case TypeCode.Double: return (Double)obj;
  92. default: throw Assert.Unreachable;
  93. }
  94. }
  95. }
  96. private object ConvertUInt64(UInt64 obj) {
  97. unchecked {
  98. switch (_to) {
  99. case TypeCode.Byte: return (Byte)obj;
  100. case TypeCode.SByte: return (SByte)obj;
  101. case TypeCode.Int16: return (Int16)obj;
  102. case TypeCode.Char: return (Char)obj;
  103. case TypeCode.Int32: return (Int32)obj;
  104. case TypeCode.Int64: return (Int64)obj;
  105. case TypeCode.UInt16: return (UInt16)obj;
  106. case TypeCode.UInt32: return (UInt32)obj;
  107. case TypeCode.UInt64: return (UInt64)obj;
  108. case TypeCode.Single: return (Single)obj;
  109. case TypeCode.Double: return (Double)obj;
  110. default: throw Assert.Unreachable;
  111. }
  112. }
  113. }
  114. private object ConvertDouble(Double obj) {
  115. unchecked {
  116. switch (_to) {
  117. case TypeCode.Byte: return (Byte)obj;
  118. case TypeCode.SByte: return (SByte)obj;
  119. case TypeCode.Int16: return (Int16)obj;
  120. case TypeCode.Char: return (Char)obj;
  121. case TypeCode.Int32: return (Int32)obj;
  122. case TypeCode.Int64: return (Int64)obj;
  123. case TypeCode.UInt16: return (UInt16)obj;
  124. case TypeCode.UInt32: return (UInt32)obj;
  125. case TypeCode.UInt64: return (UInt64)obj;
  126. case TypeCode.Single: return (Single)obj;
  127. case TypeCode.Double: return (Double)obj;
  128. default: throw Assert.Unreachable;
  129. }
  130. }
  131. }
  132. }
  133. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1034:NestedTypesShouldNotBeVisible")]
  134. public sealed class Checked : NumericConvertInstruction {
  135. public override string InstructionName { get { return "CheckedConvert"; } }
  136. public Checked(TypeCode from, TypeCode to)
  137. : base(from, to) {
  138. }
  139. public override int Run(InterpretedFrame frame) {
  140. frame.Push(Convert(frame.Pop()));
  141. return +1;
  142. }
  143. private object Convert(object obj) {
  144. switch (_from) {
  145. case TypeCode.Byte: return ConvertInt32((Byte)obj);
  146. case TypeCode.SByte: return ConvertInt32((SByte)obj);
  147. case TypeCode.Int16: return ConvertInt32((Int16)obj);
  148. case TypeCode.Char: return ConvertInt32((Char)obj);
  149. case TypeCode.Int32: return ConvertInt32((Int32)obj);
  150. case TypeCode.Int64: return ConvertInt64((Int64)obj);
  151. case TypeCode.UInt16: return ConvertInt32((UInt16)obj);
  152. case TypeCode.UInt32: return ConvertInt64((UInt32)obj);
  153. case TypeCode.UInt64: return ConvertUInt64((UInt64)obj);
  154. case TypeCode.Single: return ConvertDouble((Single)obj);
  155. case TypeCode.Double: return ConvertDouble((Double)obj);
  156. default: throw Assert.Unreachable;
  157. }
  158. }
  159. private object ConvertInt32(int obj) {
  160. checked {
  161. switch (_to) {
  162. case TypeCode.Byte: return (Byte)obj;
  163. case TypeCode.SByte: return (SByte)obj;
  164. case TypeCode.Int16: return (Int16)obj;
  165. case TypeCode.Char: return (Char)obj;
  166. case TypeCode.Int32: return (Int32)obj;
  167. case TypeCode.Int64: return (Int64)obj;
  168. case TypeCode.UInt16: return (UInt16)obj;
  169. case TypeCode.UInt32: return (UInt32)obj;
  170. case TypeCode.UInt64: return (UInt64)obj;
  171. case TypeCode.Single: return (Single)obj;
  172. case TypeCode.Double: return (Double)obj;
  173. default: throw Assert.Unreachable;
  174. }
  175. }
  176. }
  177. private object ConvertInt64(Int64 obj) {
  178. checked {
  179. switch (_to) {
  180. case TypeCode.Byte: return (Byte)obj;
  181. case TypeCode.SByte: return (SByte)obj;
  182. case TypeCode.Int16: return (Int16)obj;
  183. case TypeCode.Char: return (Char)obj;
  184. case TypeCode.Int32: return (Int32)obj;
  185. case TypeCode.Int64: return (Int64)obj;
  186. case TypeCode.UInt16: return (UInt16)obj;
  187. case TypeCode.UInt32: return (UInt32)obj;
  188. case TypeCode.UInt64: return (UInt64)obj;
  189. case TypeCode.Single: return (Single)obj;
  190. case TypeCode.Double: return (Double)obj;
  191. default: throw Assert.Unreachable;
  192. }
  193. }
  194. }
  195. private object ConvertUInt64(UInt64 obj) {
  196. checked {
  197. switch (_to) {
  198. case TypeCode.Byte: return (Byte)obj;
  199. case TypeCode.SByte: return (SByte)obj;
  200. case TypeCode.Int16: return (Int16)obj;
  201. case TypeCode.Char: return (Char)obj;
  202. case TypeCode.Int32: return (Int32)obj;
  203. case TypeCode.Int64: return (Int64)obj;
  204. case TypeCode.UInt16: return (UInt16)obj;
  205. case TypeCode.UInt32: return (UInt32)obj;
  206. case TypeCode.UInt64: return (UInt64)obj;
  207. case TypeCode.Single: return (Single)obj;
  208. case TypeCode.Double: return (Double)obj;
  209. default: throw Assert.Unreachable;
  210. }
  211. }
  212. }
  213. private object ConvertDouble(Double obj) {
  214. checked {
  215. switch (_to) {
  216. case TypeCode.Byte: return (Byte)obj;
  217. case TypeCode.SByte: return (SByte)obj;
  218. case TypeCode.Int16: return (Int16)obj;
  219. case TypeCode.Char: return (Char)obj;
  220. case TypeCode.Int32: return (Int32)obj;
  221. case TypeCode.Int64: return (Int64)obj;
  222. case TypeCode.UInt16: return (UInt16)obj;
  223. case TypeCode.UInt32: return (UInt32)obj;
  224. case TypeCode.UInt64: return (UInt64)obj;
  225. case TypeCode.Single: return (Single)obj;
  226. case TypeCode.Double: return (Double)obj;
  227. default: throw Assert.Unreachable;
  228. }
  229. }
  230. }
  231. }
  232. }
  233. }