PageRenderTime 82ms CodeModel.GetById 40ms app.highlight 5ms RepoModel.GetById 35ms 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 * ***************************************************************************/
 15using System; using Microsoft;
 16
 17
 18using System.ComponentModel;
 19using System.Diagnostics;
 20#if CODEPLEX_40
 21using System.Linq.Expressions.Compiler;
 22#else
 23using Microsoft.Linq.Expressions.Compiler;
 24#endif
 25
 26#if CODEPLEX_40
 27namespace System.Runtime.CompilerServices {
 28#else
 29namespace Microsoft.Runtime.CompilerServices {
 30#endif
 31
 32    /// <summary>
 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.
 35    /// </summary>
 36    [EditorBrowsable(EditorBrowsableState.Never), DebuggerStepThrough]
 37    public static partial class RuntimeOps {
 38        /// <summary>
 39        /// Creates an interface that can be used to modify closed over variables at runtime.
 40        /// </summary>
 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);
 47        }
 48
 49        /// <summary>
 50        /// Creates an interface that can be used to modify closed over variables at runtime.
 51        /// </summary>
 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();
 56        }
 57
 58        private sealed class EmptyRuntimeVariables : IRuntimeVariables {
 59            int IRuntimeVariables.Count {
 60                get { return 0; }
 61            }
 62
 63            object IRuntimeVariables.this[int index] {
 64                get {
 65                    throw new ArgumentOutOfRangeException("index");
 66                }
 67                set {
 68                    throw new ArgumentOutOfRangeException("index");
 69                }
 70            }
 71        }
 72
 73        /// <summary>
 74        /// Provides a list of variables, supporing read/write of the values
 75        /// Exposed via RuntimeVariablesExpression
 76        /// </summary>
 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;
 81
 82            // An array of (int, int) pairs, each representing how to find a
 83            // variable in the environment data struction.
 84            //
 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
 87            // closure chain.
 88            private readonly long[] _indexes;
 89
 90            internal RuntimeVariableList(object[] data, long[] indexes) {
 91                Debug.Assert(data != null);
 92                Debug.Assert(indexes != null);
 93
 94                _data = data;
 95                _indexes = indexes;
 96            }
 97
 98            public int Count {
 99                get { return _indexes.Length; }
100            }
101
102            public object this[int index] {
103                get {
104                    return GetStrongBox(index).Value;
105                }
106                set {
107                    GetStrongBox(index).Value = value;
108                }
109            }
110
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];
116
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);
121                }
122
123                // Return the variable storage
124                return (IStrongBox)result[(int)closureKey];
125            }
126        }
127    }
128}