PageRenderTime 40ms CodeModel.GetById 15ms RepoModel.GetById 1ms app.codeStats 0ms

/Microsoft.Scripting.Core/Compiler/RuntimeVariableList.cs

https://bitbucket.org/stefanrusek/xronos
C# | 128 lines | 67 code | 16 blank | 45 comment | 3 complexity | 7fd7fe72b46c21df04cf9c739a228f7b MD5 | raw file
  1. /* ****************************************************************************
  2. *
  3. * Copyright (c) Microsoft Corporation.
  4. *
  5. * This source code is subject to terms and conditions of the Microsoft Public License. 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 Microsoft Public License, 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 Microsoft Public License.
  10. *
  11. * You must not remove this notice, or any other, from this software.
  12. *
  13. *
  14. * ***************************************************************************/
  15. using System; using Microsoft;
  16. using System.ComponentModel;
  17. using System.Diagnostics;
  18. #if CODEPLEX_40
  19. using System.Linq.Expressions.Compiler;
  20. #else
  21. using Microsoft.Linq.Expressions.Compiler;
  22. #endif
  23. #if CODEPLEX_40
  24. namespace System.Runtime.CompilerServices {
  25. #else
  26. namespace Microsoft.Runtime.CompilerServices {
  27. #endif
  28. /// <summary>
  29. /// This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.
  30. /// Contains helper methods called from dynamically generated methods.
  31. /// </summary>
  32. [EditorBrowsable(EditorBrowsableState.Never), DebuggerStepThrough]
  33. public static partial class RuntimeOps {
  34. /// <summary>
  35. /// Creates an interface that can be used to modify closed over variables at runtime.
  36. /// </summary>
  37. /// <param name="data">The closure array.</param>
  38. /// <param name="indexes">An array of indicies into the closure array where variables are found.</param>
  39. /// <returns>An interface to access variables.</returns>
  40. [Obsolete("do not use this method", true), EditorBrowsable(EditorBrowsableState.Never)]
  41. public static IRuntimeVariables CreateRuntimeVariables(object[] data, long[] indexes) {
  42. return new RuntimeVariableList(data, indexes);
  43. }
  44. /// <summary>
  45. /// Creates an interface that can be used to modify closed over variables at runtime.
  46. /// </summary>
  47. /// <returns>An interface to access variables.</returns>
  48. [Obsolete("do not use this method", true), EditorBrowsable(EditorBrowsableState.Never)]
  49. public static IRuntimeVariables CreateRuntimeVariables() {
  50. return new EmptyRuntimeVariables();
  51. }
  52. private sealed class EmptyRuntimeVariables : IRuntimeVariables {
  53. int IRuntimeVariables.Count {
  54. get { return 0; }
  55. }
  56. object IRuntimeVariables.this[int index] {
  57. get {
  58. throw new ArgumentOutOfRangeException("index");
  59. }
  60. set {
  61. throw new ArgumentOutOfRangeException("index");
  62. }
  63. }
  64. }
  65. /// <summary>
  66. /// Provides a list of variables, supporing read/write of the values
  67. /// Exposed via RuntimeVariablesExpression
  68. /// </summary>
  69. private sealed class RuntimeVariableList : IRuntimeVariables {
  70. // The top level environment. It contains pointers to parent
  71. // environments, which are always in the first element
  72. private readonly object[] _data;
  73. // An array of (int, int) pairs, each representing how to find a
  74. // variable in the environment data struction.
  75. //
  76. // The first integer indicates the number of times to go up in the
  77. // closure chain, the second integer indicates the index into that
  78. // closure chain.
  79. private readonly long[] _indexes;
  80. internal RuntimeVariableList(object[] data, long[] indexes) {
  81. Debug.Assert(data != null);
  82. Debug.Assert(indexes != null);
  83. _data = data;
  84. _indexes = indexes;
  85. }
  86. public int Count {
  87. get { return _indexes.Length; }
  88. }
  89. public object this[int index] {
  90. get {
  91. return GetStrongBox(index).Value;
  92. }
  93. set {
  94. GetStrongBox(index).Value = value;
  95. }
  96. }
  97. private IStrongBox GetStrongBox(int index) {
  98. // We lookup the closure using two ints:
  99. // 1. The high dword is the number of parents to go up
  100. // 2. The low dword is the index into that array
  101. long closureKey = _indexes[index];
  102. // walk up the parent chain to find the real environment
  103. object[] result = _data;
  104. for (int parents = (int)(closureKey >> 32); parents > 0; parents--) {
  105. result = HoistedLocals.GetParent(result);
  106. }
  107. // Return the variable storage
  108. return (IStrongBox)result[(int)closureKey];
  109. }
  110. }
  111. }
  112. }