PageRenderTime 1497ms CodeModel.GetById 1482ms app.highlight 9ms RepoModel.GetById 1ms app.codeStats 1ms

/IronPython_2_0/Src/Microsoft.Scripting.Core/Compiler/LocalVariableAccess.cs

#
C# | 101 lines | 50 code | 17 blank | 34 comment | 2 complexity | d60fee4a8cfd83c7fe95070205c352c2 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.Collections.ObjectModel;
 19using System.Diagnostics;
 20using Microsoft.Linq.Expressions.Compiler;
 21using System.Runtime.CompilerServices;
 22using Microsoft.Runtime.CompilerServices;
 23
 24using Microsoft.Scripting.Utils;
 25
 26namespace Microsoft.Linq.Expressions.Compiler {
 27
 28    /// <summary>
 29    /// Provides a list of local variables, supporing read/write of elements
 30    /// Exposed via LocalScopeExpression
 31    /// </summary>
 32    internal sealed class LocalVariableAccess : ILocalVariables {
 33        // The names of the variables
 34        private readonly ReadOnlyCollection<string> _names;
 35
 36        // The top level environment. It contains pointers to parent
 37        // environments, which are always in the first element
 38        private readonly object[] _data;
 39
 40        // An array of (int, int) pairs, each representing how to find a
 41        // variable in the environment data struction.
 42        //
 43        // The first integer indicates the number of times to go up in the
 44        // closure chain, the second integer indicates the index into that
 45        // closure chain.
 46        private readonly long[] _indexes;
 47
 48        internal static readonly ILocalVariables Empty = new LocalVariableAccess(new object[0], new string[0], new long[0]);
 49
 50        internal LocalVariableAccess(object[] data, string[] names, long[] indexes) {
 51            Assert.NotNull(names, data, indexes);
 52            Debug.Assert(names.Length == indexes.Length);
 53
 54            _names = new ReadOnlyCollection<string>(names);
 55            _data = data;
 56            _indexes = indexes;
 57        }
 58
 59        public int Count {
 60            get { return _indexes.Length; }
 61        }
 62
 63        public ReadOnlyCollection<string> Names {
 64            get { return _names; }
 65        }
 66
 67        public IStrongBox this[int index] {
 68            get {
 69                // We lookup the closure using two ints:
 70                // 1. The high dword is the number of parents to go up
 71                // 2. The low dword is the index into that array
 72                long closureKey = _indexes[index];
 73
 74                // walk up the parent chain to find the real environment
 75                object[] result = _data;
 76                for (int parents = (int)(closureKey >> 32); parents > 0; parents--) {
 77                    result = HoistedLocals.GetParent(result);
 78                }
 79
 80                // Return the variable storage
 81                return (IStrongBox)result[(int)closureKey];
 82            }
 83        }
 84    }
 85}
 86
 87namespace Microsoft.Runtime.CompilerServices {
 88    public static partial class RuntimeOps {
 89        // creates access for local variables in scope
 90        [Obsolete("used by generated code", true)]
 91        public static ILocalVariables CreateVariableAccess(object[] data, string[] names, long[] indexes) {
 92            return new LocalVariableAccess(data, names, indexes);
 93        }
 94
 95        // creates access when there are no variables in scope
 96        [Obsolete("used by generated code", true)]
 97        public static ILocalVariables CreateEmptyVariableAccess() {
 98            return LocalVariableAccess.Empty;
 99        }
100    }
101}