/Runtime/Microsoft.Dynamic/Interpreter/Instructions/LocalAccess.cs

https://github.com/kumaryu/IronLanguages-main · C# · 374 lines · 277 code · 79 blank · 18 comment · 10 complexity · c4c6de3f72f38d6898e249503e7c8029 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. #if FEATURE_CORE_DLR
  16. using System.Linq.Expressions;
  17. #else
  18. using Microsoft.Scripting.Ast;
  19. #endif
  20. using System;
  21. using System.Reflection;
  22. using System.Runtime.CompilerServices;
  23. using Microsoft.Scripting.Runtime;
  24. using System.Collections.Generic;
  25. using Microsoft.Scripting.Utils;
  26. namespace Microsoft.Scripting.Interpreter {
  27. internal interface IBoxableInstruction {
  28. Instruction BoxIfIndexMatches(int index);
  29. }
  30. internal abstract class LocalAccessInstruction : Instruction {
  31. internal readonly int _index;
  32. protected LocalAccessInstruction(int index) {
  33. _index = index;
  34. }
  35. public override string ToDebugString(int instructionIndex, object cookie, Func<int, int> labelIndexer, IList<object> objects) {
  36. return cookie == null ?
  37. InstructionName + "(" + _index + ")" :
  38. InstructionName + "(" + cookie + ": " + _index + ")";
  39. }
  40. }
  41. #region Load
  42. internal sealed class LoadLocalInstruction : LocalAccessInstruction, IBoxableInstruction {
  43. internal LoadLocalInstruction(int index)
  44. : base(index) {
  45. }
  46. public override int ProducedStack { get { return 1; } }
  47. public override int Run(InterpretedFrame frame) {
  48. frame.Data[frame.StackIndex++] = frame.Data[_index];
  49. //frame.Push(frame.Data[_index]);
  50. return +1;
  51. }
  52. public Instruction BoxIfIndexMatches(int index) {
  53. return (index == _index) ? InstructionList.LoadLocalBoxed(index) : null;
  54. }
  55. }
  56. internal sealed class LoadLocalBoxedInstruction : LocalAccessInstruction {
  57. internal LoadLocalBoxedInstruction(int index)
  58. : base(index) {
  59. }
  60. public override int ProducedStack { get { return 1; } }
  61. public override int Run(InterpretedFrame frame) {
  62. var box = (StrongBox<object>)frame.Data[_index];
  63. frame.Data[frame.StackIndex++] = box.Value;
  64. return +1;
  65. }
  66. }
  67. internal sealed class LoadLocalFromClosureInstruction : LocalAccessInstruction {
  68. internal LoadLocalFromClosureInstruction(int index)
  69. : base(index) {
  70. }
  71. public override int ProducedStack { get { return 1; } }
  72. public override int Run(InterpretedFrame frame) {
  73. var box = frame.Closure[_index];
  74. frame.Data[frame.StackIndex++] = box.Value;
  75. return +1;
  76. }
  77. }
  78. internal sealed class LoadLocalFromClosureBoxedInstruction : LocalAccessInstruction {
  79. internal LoadLocalFromClosureBoxedInstruction(int index)
  80. : base(index) {
  81. }
  82. public override int ProducedStack { get { return 1; } }
  83. public override int Run(InterpretedFrame frame) {
  84. var box = frame.Closure[_index];
  85. frame.Data[frame.StackIndex++] = box;
  86. return +1;
  87. }
  88. }
  89. #endregion
  90. #region Store, Assign
  91. internal sealed class AssignLocalInstruction : LocalAccessInstruction, IBoxableInstruction {
  92. internal AssignLocalInstruction(int index)
  93. : base(index) {
  94. }
  95. public override int ConsumedStack { get { return 1; } }
  96. public override int ProducedStack { get { return 1; } }
  97. public override int Run(InterpretedFrame frame) {
  98. frame.Data[_index] = frame.Peek();
  99. return +1;
  100. }
  101. public Instruction BoxIfIndexMatches(int index) {
  102. return (index == _index) ? InstructionList.AssignLocalBoxed(index) : null;
  103. }
  104. }
  105. internal sealed class StoreLocalInstruction : LocalAccessInstruction, IBoxableInstruction {
  106. internal StoreLocalInstruction(int index)
  107. : base(index) {
  108. }
  109. public override int ConsumedStack { get { return 1; } }
  110. public override int Run(InterpretedFrame frame) {
  111. frame.Data[_index] = frame.Data[--frame.StackIndex];
  112. //frame.Data[_index] = frame.Pop();
  113. return +1;
  114. }
  115. public Instruction BoxIfIndexMatches(int index) {
  116. return (index == _index) ? InstructionList.StoreLocalBoxed(index) : null;
  117. }
  118. }
  119. internal sealed class AssignLocalBoxedInstruction : LocalAccessInstruction {
  120. internal AssignLocalBoxedInstruction(int index)
  121. : base(index) {
  122. }
  123. public override int ConsumedStack { get { return 1; } }
  124. public override int ProducedStack { get { return 1; } }
  125. public override int Run(InterpretedFrame frame) {
  126. var box = (StrongBox<object>)frame.Data[_index];
  127. box.Value = frame.Peek();
  128. return +1;
  129. }
  130. }
  131. internal sealed class StoreLocalBoxedInstruction : LocalAccessInstruction {
  132. internal StoreLocalBoxedInstruction(int index)
  133. : base(index) {
  134. }
  135. public override int ConsumedStack { get { return 1; } }
  136. public override int ProducedStack { get { return 0; } }
  137. public override int Run(InterpretedFrame frame) {
  138. var box = (StrongBox<object>)frame.Data[_index];
  139. box.Value = frame.Data[--frame.StackIndex];
  140. return +1;
  141. }
  142. }
  143. internal sealed class AssignLocalToClosureInstruction : LocalAccessInstruction {
  144. internal AssignLocalToClosureInstruction(int index)
  145. : base(index) {
  146. }
  147. public override int ConsumedStack { get { return 1; } }
  148. public override int ProducedStack { get { return 1; } }
  149. public override int Run(InterpretedFrame frame) {
  150. var box = frame.Closure[_index];
  151. box.Value = frame.Peek();
  152. return +1;
  153. }
  154. }
  155. #endregion
  156. #region Initialize
  157. [System.Diagnostics.CodeAnalysis.SuppressMessage("Microsoft.Design", "CA1012:AbstractTypesShouldNotHaveConstructors")]
  158. internal abstract class InitializeLocalInstruction : LocalAccessInstruction {
  159. internal InitializeLocalInstruction(int index)
  160. : base(index) {
  161. }
  162. internal sealed class Reference : InitializeLocalInstruction, IBoxableInstruction {
  163. internal Reference(int index)
  164. : base(index) {
  165. }
  166. public override int Run(InterpretedFrame frame) {
  167. frame.Data[_index] = null;
  168. return 1;
  169. }
  170. public Instruction BoxIfIndexMatches(int index) {
  171. return (index == _index) ? InstructionList.InitImmutableRefBox(index) : null;
  172. }
  173. public override string InstructionName {
  174. get { return "InitRef"; }
  175. }
  176. }
  177. internal sealed class ImmutableValue : InitializeLocalInstruction, IBoxableInstruction {
  178. private readonly object _defaultValue;
  179. internal ImmutableValue(int index, object defaultValue)
  180. : base(index) {
  181. _defaultValue = defaultValue;
  182. }
  183. public override int Run(InterpretedFrame frame) {
  184. frame.Data[_index] = _defaultValue;
  185. return 1;
  186. }
  187. public Instruction BoxIfIndexMatches(int index) {
  188. return (index == _index) ? new ImmutableBox(index, _defaultValue) : null;
  189. }
  190. public override string InstructionName {
  191. get { return "InitImmutableValue"; }
  192. }
  193. }
  194. internal sealed class ImmutableBox : InitializeLocalInstruction {
  195. // immutable value:
  196. private readonly object _defaultValue;
  197. internal ImmutableBox(int index, object defaultValue)
  198. : base(index) {
  199. _defaultValue = defaultValue;
  200. }
  201. public override int Run(InterpretedFrame frame) {
  202. frame.Data[_index] = new StrongBox<object>(_defaultValue);
  203. return 1;
  204. }
  205. public override string InstructionName {
  206. get { return "InitImmutableBox"; }
  207. }
  208. }
  209. internal sealed class ParameterBox : InitializeLocalInstruction {
  210. public ParameterBox(int index)
  211. : base(index) {
  212. }
  213. public override int Run(InterpretedFrame frame) {
  214. frame.Data[_index] = new StrongBox<object>(frame.Data[_index]);
  215. return 1;
  216. }
  217. }
  218. internal sealed class Parameter : InitializeLocalInstruction, IBoxableInstruction {
  219. internal Parameter(int index)
  220. : base(index) {
  221. }
  222. public override int Run(InterpretedFrame frame) {
  223. // nop
  224. return 1;
  225. }
  226. public Instruction BoxIfIndexMatches(int index) {
  227. if (index == _index) {
  228. return InstructionList.ParameterBox(index);
  229. }
  230. return null;
  231. }
  232. public override string InstructionName {
  233. get { return "InitParameter"; }
  234. }
  235. }
  236. internal sealed class MutableValue : InitializeLocalInstruction, IBoxableInstruction {
  237. private readonly Type _type;
  238. internal MutableValue(int index, Type type)
  239. : base(index) {
  240. _type = type;
  241. }
  242. public override int Run(InterpretedFrame frame) {
  243. try {
  244. frame.Data[_index] = Activator.CreateInstance(_type);
  245. } catch (TargetInvocationException e) {
  246. ExceptionHelpers.UpdateForRethrow(e.InnerException);
  247. throw e.InnerException;
  248. }
  249. return 1;
  250. }
  251. public Instruction BoxIfIndexMatches(int index) {
  252. return (index == _index) ? new MutableBox(index, _type) : null;
  253. }
  254. public override string InstructionName {
  255. get { return "InitMutableValue"; }
  256. }
  257. }
  258. internal sealed class MutableBox : InitializeLocalInstruction {
  259. private readonly Type _type;
  260. internal MutableBox(int index, Type type)
  261. : base(index) {
  262. _type = type;
  263. }
  264. public override int Run(InterpretedFrame frame) {
  265. frame.Data[_index] = new StrongBox<object>(Activator.CreateInstance(_type));
  266. return 1;
  267. }
  268. public override string InstructionName {
  269. get { return "InitMutableBox"; }
  270. }
  271. }
  272. }
  273. #endregion
  274. #region RuntimeVariables
  275. internal sealed class RuntimeVariablesInstruction : Instruction {
  276. private readonly int _count;
  277. public RuntimeVariablesInstruction(int count) {
  278. _count = count;
  279. }
  280. public override int ProducedStack { get { return 1; } }
  281. public override int ConsumedStack { get { return _count; } }
  282. public override int Run(InterpretedFrame frame) {
  283. var ret = new IStrongBox[_count];
  284. for (int i = ret.Length - 1; i >= 0; i--) {
  285. ret[i] = (IStrongBox)frame.Pop();
  286. }
  287. frame.Push(RuntimeVariables.Create(ret));
  288. return +1;
  289. }
  290. public override string ToString() {
  291. return "GetRuntimeVariables()";
  292. }
  293. }
  294. #endregion
  295. }