Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes372downloads
LocalVariables.cs323 linesDownload Raw Back to interpreter
1/* ****************************************************************************2 *3 * Copyright (c) Microsoft Corporation.4 *5 * This source code is subject to terms and conditions of the Apache License, Version 2.0. A6 * copy of the license can be found in the License.html file at the root of this distribution. If7 * you cannot locate the Apache License, Version 2.0, please send an email to8 * dlr@microsoft.com. By using this source code in any fashion, you are agreeing to be bound9 * by the terms of the Apache License, Version 2.0.10 *11 * You must not remove this notice, or any other, from this software.12 *13 *14 * ***************************************************************************/15 16#if !CLR217using System.Globalization;18using System.Linq.Expressions;19#else20using Microsoft.Scripting.Ast;21#endif22using System.Collections.Generic;23using System.Diagnostics;24using System.Runtime.CompilerServices;25 26namespace System.Management.Automation.Interpreter27{28    internal sealed class LocalVariable29    {30        private const int IsBoxedFlag = 1;31        private const int InClosureFlag = 2;32 33        public readonly int Index;34        private int _flags;35 36        public bool IsBoxed37        {38            get39            {40                return (_flags & IsBoxedFlag) != 0;41            }42 43            set44            {45                if (value)46                {47                    _flags |= IsBoxedFlag;48                }49                else50                {51                    _flags &= ~IsBoxedFlag;52                }53            }54        }55 56        public bool InClosure57        {58            get { return (_flags & InClosureFlag) != 0; }59        }60 61        public bool InClosureOrBoxed62        {63            get { return InClosure || IsBoxed; }64        }65 66        internal LocalVariable(int index, bool closure, bool boxed)67        {68            Index = index;69            _flags = (closure ? InClosureFlag : 0) | (boxed ? IsBoxedFlag : 0);70        }71 72        internal Expression LoadFromArray(Expression frameData, Expression closure)73        {74            Expression result = Expression.ArrayAccess(InClosure ? closure : frameData, Expression.Constant(Index));75            return IsBoxed ? Expression.Convert(result, typeof(StrongBox<object>)) : result;76        }77 78        public override string ToString()79        {80            return string.Format(CultureInfo.InvariantCulture, "{0}: {1} {2}", Index, IsBoxed ? "boxed" : null, InClosure ? "in closure" : null);81        }82    }83 84    internal readonly struct LocalDefinition85    {86        private readonly int _index;87        private readonly ParameterExpression _parameter;88 89        internal LocalDefinition(int localIndex, ParameterExpression parameter)90        {91            _index = localIndex;92            _parameter = parameter;93        }94 95        public int Index96        {97            get98            {99                return _index;100            }101        }102 103        public ParameterExpression Parameter104        {105            get106            {107                return _parameter;108            }109        }110 111        public override bool Equals(object obj)112        {113            if (obj is LocalDefinition)114            {115                LocalDefinition other = (LocalDefinition)obj;116                return other.Index == Index && other.Parameter == Parameter;117            }118 119            return false;120        }121 122        public override int GetHashCode()123        {124            if (_parameter == null)125            {126                return 0;127            }128 129            return _parameter.GetHashCode() ^ _index.GetHashCode();130        }131 132        public static bool operator ==(LocalDefinition self, LocalDefinition other)133        {134            return self.Index == other.Index && self.Parameter == other.Parameter;135        }136 137        public static bool operator !=(LocalDefinition self, LocalDefinition other)138        {139            return self.Index != other.Index || self.Parameter != other.Parameter;140        }141    }142 143    internal sealed class LocalVariables144    {145        private readonly HybridReferenceDictionary<ParameterExpression, VariableScope> _variables = new HybridReferenceDictionary<ParameterExpression, VariableScope>();146        private Dictionary<ParameterExpression, LocalVariable> _closureVariables;147 148        private int _localCount, _maxLocalCount;149 150        internal LocalVariables()151        {152        }153 154        public LocalDefinition DefineLocal(ParameterExpression variable, int start)155        {156            // ContractUtils.RequiresNotNull(variable, "variable");157            // ContractUtils.Requires(start >= 0, "start", "start must be positive");158 159            LocalVariable result = new LocalVariable(_localCount++, false, false);160            _maxLocalCount = System.Math.Max(_localCount, _maxLocalCount);161 162            VariableScope existing, newScope;163            if (_variables.TryGetValue(variable, out existing))164            {165                newScope = new VariableScope(result, start, existing);166                existing.ChildScopes ??= new List<VariableScope>();167 168                existing.ChildScopes.Add(newScope);169            }170            else171            {172                newScope = new VariableScope(result, start, null);173            }174 175            _variables[variable] = newScope;176            return new LocalDefinition(result.Index, variable);177        }178 179        public void UndefineLocal(LocalDefinition definition, int end)180        {181            var scope = _variables[definition.Parameter];182            scope.Stop = end;183            if (scope.Parent != null)184            {185                _variables[definition.Parameter] = scope.Parent;186            }187            else188            {189                _variables.Remove(definition.Parameter);190            }191 192            _localCount--;193        }194 195        internal void Box(ParameterExpression variable, InstructionList instructions)196        {197            var scope = _variables[variable];198 199            LocalVariable local = scope.Variable;200            Debug.Assert(!local.IsBoxed && !local.InClosure);201            _variables[variable].Variable.IsBoxed = true;202 203            int curChild = 0;204            for (int i = scope.Start; i < scope.Stop && i < instructions.Count; i++)205            {206                if (scope.ChildScopes != null && scope.ChildScopes[curChild].Start == i)207                {208                    // skip boxing in the child scope209                    var child = scope.ChildScopes[curChild];210                    i = child.Stop;211 212                    curChild++;213                    continue;214                }215 216                instructions.SwitchToBoxed(local.Index, i);217            }218        }219 220        public int LocalCount221        {222            get { return _maxLocalCount; }223        }224 225        public int GetOrDefineLocal(ParameterExpression var)226        {227            int index = GetLocalIndex(var);228            if (index == -1)229            {230                return DefineLocal(var, 0).Index;231            }232 233            return index;234        }235 236        public int GetLocalIndex(ParameterExpression var)237        {238            VariableScope loc;239            return _variables.TryGetValue(var, out loc) ? loc.Variable.Index : -1;240        }241 242        public bool TryGetLocalOrClosure(ParameterExpression var, out LocalVariable local)243        {244            VariableScope scope;245            if (_variables.TryGetValue(var, out scope))246            {247                local = scope.Variable;248                return true;249            }250 251            if (_closureVariables != null && _closureVariables.TryGetValue(var, out local))252            {253                return true;254            }255 256            local = null;257            return false;258        }259 260        /// <summary>261        /// Gets a copy of the local variables which are defined in the current scope.262        /// </summary>263        /// <returns></returns>264        internal Dictionary<ParameterExpression, LocalVariable> CopyLocals()265        {266            var res = new Dictionary<ParameterExpression, LocalVariable>(_variables.Count);267            foreach (var keyValue in _variables)268            {269                res[keyValue.Key] = keyValue.Value.Variable;270            }271 272            return res;273        }274 275        /// <summary>276        /// Checks to see if the given variable is defined within the current local scope.277        /// </summary>278        internal bool ContainsVariable(ParameterExpression variable)279        {280            return _variables.ContainsKey(variable);281        }282 283        /// <summary>284        /// Gets the variables which are defined in an outer scope and available within the current scope.285        /// </summary>286        internal Dictionary<ParameterExpression, LocalVariable> ClosureVariables287        {288            get289            {290                return _closureVariables;291            }292        }293 294        internal LocalVariable AddClosureVariable(ParameterExpression variable)295        {296            _closureVariables ??= new Dictionary<ParameterExpression, LocalVariable>();297 298            LocalVariable result = new LocalVariable(_closureVariables.Count, true, false);299            _closureVariables.Add(variable, result);300            return result;301        }302 303        /// <summary>304        /// Tracks where a variable is defined and what range of instructions it's used in.305        /// </summary>306        private sealed class VariableScope307        {308            public readonly int Start;309            public int Stop = Int32.MaxValue;310            public readonly LocalVariable Variable;311            public readonly VariableScope Parent;312            public List<VariableScope> ChildScopes;313 314            public VariableScope(LocalVariable variable, int start, VariableScope parent)315            {316                Variable = variable;317                Start = start;318                Parent = parent;319            }320        }321    }322}323