Team Ai
Datasetpublic

MegaBites-AI/Windows-powershell

sourceHugging Facemitupdated 6mo agoView on Hugging Face
0likes308downloads
InterpretedFrame.cs334 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 !CLR217#else18using Microsoft.Scripting.Ast;19#endif20using System.Collections.Generic;21using System.Diagnostics;22using System.Management.Automation.Language;23using System.Reflection;24using System.Runtime.CompilerServices;25 26namespace System.Management.Automation.Interpreter27{28    internal sealed class InterpretedFrame29    {30        public static readonly ThreadLocal<InterpretedFrame> CurrentFrame = new ThreadLocal<InterpretedFrame>();31 32        internal readonly Interpreter Interpreter;33        internal InterpretedFrame _parent;34 35        private readonly int[] _continuations;36 37        private int _continuationIndex;38        private int _pendingContinuation;39        private object _pendingValue;40 41        public readonly object[] Data;42 43        public readonly StrongBox<object>[] Closure;44 45        public int StackIndex;46        public int InstructionIndex;47 48        internal InterpretedFrame(Interpreter interpreter, StrongBox<object>[] closure)49        {50            Interpreter = interpreter;51            StackIndex = interpreter.LocalCount;52            Data = new object[StackIndex + interpreter.Instructions.MaxStackDepth];53 54            int c = interpreter.Instructions.MaxContinuationDepth;55            if (c > 0)56            {57                _continuations = new int[c];58            }59 60            Closure = closure;61 62            _pendingContinuation = -1;63            _pendingValue = Interpreter.NoValue;64        }65 66        public DebugInfo GetDebugInfo(int instructionIndex)67        {68            return DebugInfo.GetMatchingDebugInfo(Interpreter._debugInfos, instructionIndex);69        }70 71        public string Name72        {73            get { return Interpreter._name; }74        }75 76        #region Data Stack Operations77 78        public void Push(object value)79        {80            Data[StackIndex++] = value;81        }82 83        public void Push(bool value)84        {85            Data[StackIndex++] = value ? ScriptingRuntimeHelpers.True : ScriptingRuntimeHelpers.False;86        }87 88        public void Push(int value)89        {90            Data[StackIndex++] = ScriptingRuntimeHelpers.Int32ToObject(value);91        }92 93        public object Pop()94        {95            return Data[--StackIndex];96        }97 98        internal void SetStackDepth(int depth)99        {100            StackIndex = Interpreter.LocalCount + depth;101        }102 103        public object Peek()104        {105            return Data[StackIndex - 1];106        }107 108        public void Dup()109        {110            int i = StackIndex;111            Data[i] = Data[i - 1];112            StackIndex = i + 1;113        }114 115        public ExecutionContext ExecutionContext116        {117            get { return (ExecutionContext)Data[1]; }118        }119 120        public FunctionContext FunctionContext121        {122            get { return (FunctionContext)Data[0]; }123        }124 125        #endregion126 127        #region Stack Trace128 129        public InterpretedFrame Parent130        {131            get { return _parent; }132        }133 134        public static bool IsInterpretedFrame(MethodBase method)135        {136            // ContractUtils.RequiresNotNull(method, "method");137            return method.DeclaringType == typeof(Interpreter) && method.Name == "Run";138        }139 140        /// <summary>141        /// A single interpreted frame might be represented by multiple subsequent Interpreter.Run CLR frames.142        /// This method filters out the duplicate CLR frames.143        /// </summary>144        public static IEnumerable<StackFrame> GroupStackFrames(IEnumerable<StackFrame> stackTrace)145        {146            bool inInterpretedFrame = false;147            foreach (StackFrame frame in stackTrace)148            {149                if (InterpretedFrame.IsInterpretedFrame(frame.GetMethod()))150                {151                    if (inInterpretedFrame)152                    {153                        continue;154                    }155 156                    inInterpretedFrame = true;157                }158                else159                {160                    inInterpretedFrame = false;161                }162 163                yield return frame;164            }165        }166 167        public IEnumerable<InterpretedFrameInfo> GetStackTraceDebugInfo()168        {169            var frame = this;170            do171            {172                yield return new InterpretedFrameInfo(frame.Name, frame.GetDebugInfo(frame.InstructionIndex));173                frame = frame.Parent;174            } while (frame != null);175        }176 177        internal void SaveTraceToException(Exception exception)178        {179            if (exception.Data[typeof(InterpretedFrameInfo)] == null)180            {181                exception.Data[typeof(InterpretedFrameInfo)] = new List<InterpretedFrameInfo>(GetStackTraceDebugInfo()).ToArray();182            }183        }184 185        public static InterpretedFrameInfo[] GetExceptionStackTrace(Exception exception)186        {187            return exception.Data[typeof(InterpretedFrameInfo)] as InterpretedFrameInfo[];188        }189 190#if DEBUG191        internal string[] Trace192        {193            get194            {195                var trace = new List<string>();196                var frame = this;197                do198                {199                    trace.Add(frame.Name);200                    frame = frame.Parent;201                } while (frame != null);202                return trace.ToArray();203            }204        }205#endif206 207        internal ThreadLocal<InterpretedFrame>.StorageInfo Enter()208        {209            var currentFrame = InterpretedFrame.CurrentFrame.GetStorageInfo();210            _parent = currentFrame.Value;211            currentFrame.Value = this;212            return currentFrame;213        }214 215        internal void Leave(ThreadLocal<InterpretedFrame>.StorageInfo currentFrame)216        {217            currentFrame.Value = _parent;218        }219 220        #endregion221 222        #region Continuations223 224        internal bool IsJumpHappened()225        {226            return _pendingContinuation >= 0;227        }228 229        public void RemoveContinuation()230        {231            _continuationIndex--;232        }233 234        public void PushContinuation(int continuation)235        {236            _continuations[_continuationIndex++] = continuation;237        }238 239        public int YieldToCurrentContinuation()240        {241            var target = Interpreter._labels[_continuations[_continuationIndex - 1]];242            SetStackDepth(target.StackDepth);243            return target.Index - InstructionIndex;244        }245 246        /// <summary>247        /// Get called from the LeaveFinallyInstruction.248        /// </summary>249        public int YieldToPendingContinuation()250        {251            Debug.Assert(_pendingContinuation >= 0);252            RuntimeLabel pendingTarget = Interpreter._labels[_pendingContinuation];253 254            // the current continuation might have higher priority (continuationIndex is the depth of the current continuation):255            if (pendingTarget.ContinuationStackDepth < _continuationIndex)256            {257                RuntimeLabel currentTarget = Interpreter._labels[_continuations[_continuationIndex - 1]];258                SetStackDepth(currentTarget.StackDepth);259                return currentTarget.Index - InstructionIndex;260            }261 262            SetStackDepth(pendingTarget.StackDepth);263            if (_pendingValue != Interpreter.NoValue)264            {265                Data[StackIndex - 1] = _pendingValue;266            }267 268            // Set the _pendingContinuation and _pendingValue to the default values if we finally gets to the Goto target269            _pendingContinuation = -1;270            _pendingValue = Interpreter.NoValue;271            return pendingTarget.Index - InstructionIndex;272        }273 274        internal void PushPendingContinuation()275        {276            Push(_pendingContinuation);277            Push(_pendingValue);278 279            _pendingContinuation = -1;280            _pendingValue = Interpreter.NoValue;281        }282 283        internal void PopPendingContinuation()284        {285            _pendingValue = Pop();286            _pendingContinuation = (int)Pop();287        }288 289        private static MethodInfo s_goto;290        private static MethodInfo s_voidGoto;291 292        internal static MethodInfo GotoMethod293        {294            get { return s_goto ??= typeof(InterpretedFrame).GetMethod("Goto"); }295        }296 297        internal static MethodInfo VoidGotoMethod298        {299            get { return s_voidGoto ??= typeof(InterpretedFrame).GetMethod("VoidGoto"); }300        }301 302        public int VoidGoto(int labelIndex)303        {304            return Goto(labelIndex, Interpreter.NoValue, gotoExceptionHandler: false);305        }306 307        public int Goto(int labelIndex, object value, bool gotoExceptionHandler)308        {309            // TODO: we know this at compile time (except for compiled loop):310            RuntimeLabel target = Interpreter._labels[labelIndex];311            Debug.Assert(!gotoExceptionHandler || _continuationIndex == target.ContinuationStackDepth,312                "When it's time to jump to the exception handler, all previous finally blocks should already be processed");313 314            if (_continuationIndex == target.ContinuationStackDepth)315            {316                SetStackDepth(target.StackDepth);317                if (value != Interpreter.NoValue)318                {319                    Data[StackIndex - 1] = value;320                }321 322                return target.Index - InstructionIndex;323            }324 325            // if we are in the middle of executing jump we forget the previous target and replace it by a new one:326            _pendingContinuation = labelIndex;327            _pendingValue = value;328            return YieldToCurrentContinuation();329        }330 331        #endregion332    }333}334