MegaBites-AI/Windows-powershell
0372
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 16using System.Collections.Generic;17using System.Linq.Expressions;18using System.Runtime.CompilerServices;19 20namespace System.Management.Automation.Interpreter21{22 /// <summary>23 /// A simple forth-style stack machine for executing Expression trees24 /// without the need to compile to IL and then invoke the JIT. This trades25 /// off much faster compilation time for a slower execution performance.26 /// For code that is only run a small number of times this can be a27 /// sweet spot.28 ///29 /// The core loop in the interpreter is the RunInstructions method.30 /// </summary>31 internal sealed class Interpreter32 {33 internal static readonly object NoValue = new object();34 35 internal const int RethrowOnReturn = Int32.MaxValue;36 37 // zero: sync compilation38 // negative: default39 internal readonly int _compilationThreshold;40 41 internal readonly object[] _objects;42 internal readonly RuntimeLabel[] _labels;43 44 internal readonly string _name;45 internal readonly DebugInfo[] _debugInfos;46 47 internal Interpreter(string name, LocalVariables locals, HybridReferenceDictionary<LabelTarget, BranchLabel> labelMapping,48 InstructionArray instructions, DebugInfo[] debugInfos, int compilationThreshold)49 {50 _name = name;51 LocalCount = locals.LocalCount;52 ClosureVariables = locals.ClosureVariables;53 54 Instructions = instructions;55 _objects = instructions.Objects;56 _labels = instructions.Labels;57 LabelMapping = labelMapping;58 59 _debugInfos = debugInfos;60 _compilationThreshold = compilationThreshold;61 }62 63 internal int ClosureSize64 {65 get66 {67 if (ClosureVariables == null)68 {69 return 0;70 }71 72 return ClosureVariables.Count;73 }74 }75 76 internal int LocalCount { get; }77 78 internal bool CompileSynchronously79 {80 get { return _compilationThreshold <= 1; }81 }82 83 internal InstructionArray Instructions { get; }84 85 internal Dictionary<ParameterExpression, LocalVariable> ClosureVariables { get; }86 87 internal HybridReferenceDictionary<LabelTarget, BranchLabel> LabelMapping { get; }88 89 /// <summary>90 /// Runs instructions within the given frame.91 /// </summary>92 /// <remarks>93 /// Interpreted stack frames are linked via Parent reference so that each CLR frame of this method corresponds94 /// to an interpreted stack frame in the chain. It is therefore possible to combine CLR stack traces with95 /// interpreted stack traces by aligning interpreted frames to the frames of this method.96 /// Each group of subsequent frames of Run method corresponds to a single interpreted frame.97 /// </remarks>98 [SpecialName, MethodImpl(MethodImplOptions.NoInlining)]99 public void Run(InterpretedFrame frame)100 {101 var instructions = Instructions.Instructions;102 int index = frame.InstructionIndex;103 while (index < instructions.Length)104 {105 index += instructions[index].Run(frame);106 frame.InstructionIndex = index;107 }108 }109 }110}111 