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 Microsoft.Scripting.Ast.Compiler;
19 using System.Linq.Expressions.Compiler;
22 using System.ComponentModel;
23 using System.Diagnostics;
25 namespace System.Runtime.CompilerServices {
28 /// This API supports the .NET Framework infrastructure and is not intended to be used directly from your code.
29 /// Contains helper methods called from dynamically generated methods.
31 [EditorBrowsable(EditorBrowsableState.Never), DebuggerStepThrough]
32 public static partial class RuntimeOps {
34 /// Creates an interface that can be used to modify closed over variables at runtime.
36 /// <param name="data">The closure array.</param>
37 /// <param name="indexes">An array of indicies into the closure array where variables are found.</param>
38 /// <returns>An interface to access variables.</returns>
39 [Obsolete("do not use this method", true), EditorBrowsable(EditorBrowsableState.Never)]
40 public static IRuntimeVariables CreateRuntimeVariables(object[] data, long[] indexes) {
41 return new RuntimeVariableList(data, indexes);
45 /// Creates an interface that can be used to modify closed over variables at runtime.
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();
53 private sealed class EmptyRuntimeVariables : IRuntimeVariables {
54 int IRuntimeVariables.Count {
58 object IRuntimeVariables.this[int index] {
60 throw new ArgumentOutOfRangeException("index");
63 throw new ArgumentOutOfRangeException("index");
69 /// Provides a list of variables, supporing read/write of the values
70 /// Exposed via RuntimeVariablesExpression
72 private sealed class RuntimeVariableList : IRuntimeVariables {
73 // The top level environment. It contains pointers to parent
74 // environments, which are always in the first element
75 private readonly object[] _data;
77 // An array of (int, int) pairs, each representing how to find a
78 // variable in the environment data struction.
80 // The first integer indicates the number of times to go up in the
81 // closure chain, the second integer indicates the index into that
83 private readonly long[] _indexes;
85 internal RuntimeVariableList(object[] data, long[] indexes) {
86 Debug.Assert(data != null);
87 Debug.Assert(indexes != null);
94 get { return _indexes.Length; }
97 public object this[int index] {
99 return GetStrongBox(index).Value;
102 GetStrongBox(index).Value = value;
106 private IStrongBox GetStrongBox(int index) {
107 // We lookup the closure using two ints:
108 // 1. The high dword is the number of parents to go up
109 // 2. The low dword is the index into that array
110 long closureKey = _indexes[index];
112 // walk up the parent chain to find the real environment
113 object[] result = _data;
114 for (int parents = (int)(closureKey >> 32); parents > 0; parents--) {
115 result = HoistedLocals.GetParent(result);
118 // Return the variable storage
119 return (IStrongBox)result[(int)closureKey];