1 /* ****************************************************************************
3 * Copyright (c) Microsoft Corporation.
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.
11 * You must not remove this notice, or any other, from this software.
14 * ***************************************************************************/
15 using System; using Microsoft;
18 using System.ComponentModel;
19 using System.Diagnostics;
21 using System.Linq.Expressions.Compiler;
23 using Microsoft.Linq.Expressions.Compiler;
27 namespace System.Runtime.CompilerServices {
29 namespace Microsoft.Runtime.CompilerServices {
33 /// This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.
34 /// Contains helper methods called from dynamically generated methods.
36 [EditorBrowsable(EditorBrowsableState.Never), DebuggerStepThrough]
37 public static partial class RuntimeOps {
39 /// Creates an interface that can be used to modify closed over variables at runtime.
41 /// <param name="data">The closure array.</param>
42 /// <param name="indexes">An array of indicies into the closure array where variables are found.</param>
43 /// <returns>An interface to access variables.</returns>
44 [Obsolete("do not use this method", true), EditorBrowsable(EditorBrowsableState.Never)]
45 public static IRuntimeVariables CreateRuntimeVariables(object[] data, long[] indexes) {
46 return new RuntimeVariableList(data, indexes);
50 /// Creates an interface that can be used to modify closed over variables at runtime.
52 /// <returns>An interface to access variables.</returns>
53 [Obsolete("do not use this method", true), EditorBrowsable(EditorBrowsableState.Never)]
54 public static IRuntimeVariables CreateRuntimeVariables() {
55 return new EmptyRuntimeVariables();
58 private sealed class EmptyRuntimeVariables : IRuntimeVariables {
59 int IRuntimeVariables.Count {
63 object IRuntimeVariables.this[int index] {
65 throw new ArgumentOutOfRangeException("index");
68 throw new ArgumentOutOfRangeException("index");
74 /// Provides a list of variables, supporing read/write of the values
75 /// Exposed via RuntimeVariablesExpression
77 private sealed class RuntimeVariableList : IRuntimeVariables {
78 // The top level environment. It contains pointers to parent
79 // environments, which are always in the first element
80 private readonly object[] _data;
82 // An array of (int, int) pairs, each representing how to find a
83 // variable in the environment data struction.
85 // The first integer indicates the number of times to go up in the
86 // closure chain, the second integer indicates the index into that
88 private readonly long[] _indexes;
90 internal RuntimeVariableList(object[] data, long[] indexes) {
91 Debug.Assert(data != null);
92 Debug.Assert(indexes != null);
99 get { return _indexes.Length; }
102 public object this[int index] {
104 return GetStrongBox(index).Value;
107 GetStrongBox(index).Value = value;
111 private IStrongBox GetStrongBox(int index) {
112 // We lookup the closure using two ints:
113 // 1. The high dword is the number of parents to go up
114 // 2. The low dword is the index into that array
115 long closureKey = _indexes[index];
117 // walk up the parent chain to find the real environment
118 object[] result = _data;
119 for (int parents = (int)(closureKey >> 32); parents > 0; parents--) {
120 result = HoistedLocals.GetParent(result);
123 // Return the variable storage
124 return (IStrongBox)result[(int)closureKey];