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.Diagnostics;17using System.Collections.Generic;18using System.Globalization;19 20namespace System.Management.Automation.Interpreter21{22 internal readonly struct RuntimeLabel23 {24 public readonly int Index;25 public readonly int StackDepth;26 public readonly int ContinuationStackDepth;27 28 public RuntimeLabel(int index, int continuationStackDepth, int stackDepth)29 {30 Index = index;31 ContinuationStackDepth = continuationStackDepth;32 StackDepth = stackDepth;33 }34 35 public override string ToString()36 {37 return string.Format(CultureInfo.InvariantCulture, "->{0} C({1}) S({2})", Index, ContinuationStackDepth, StackDepth);38 }39 }40 41 internal sealed class BranchLabel42 {43 internal const int UnknownIndex = Int32.MinValue;44 internal const int UnknownDepth = Int32.MinValue;45 46 internal int _labelIndex = UnknownIndex;47 internal int _targetIndex = UnknownIndex;48 internal int _stackDepth = UnknownDepth;49 internal int _continuationStackDepth = UnknownDepth;50 51 // Offsets of forward branching instructions targeting this label52 // that need to be updated after we emit the label.53 private List<int> _forwardBranchFixups;54 55 public BranchLabel()56 {57 }58 59 internal int LabelIndex60 {61 get { return _labelIndex; }62 63 set { _labelIndex = value; }64 }65 66 internal bool HasRuntimeLabel67 {68 get { return _labelIndex != UnknownIndex; }69 }70 71 internal int TargetIndex72 {73 get { return _targetIndex; }74 }75 76 internal int StackDepth77 {78 get { return _stackDepth; }79 }80 81 internal RuntimeLabel ToRuntimeLabel()82 {83 Debug.Assert(_targetIndex != UnknownIndex && _stackDepth != UnknownDepth && _continuationStackDepth != UnknownDepth);84 return new RuntimeLabel(_targetIndex, _continuationStackDepth, _stackDepth);85 }86 87 internal void Mark(InstructionList instructions)88 {89 // ContractUtils.Requires(_targetIndex == UnknownIndex && _stackDepth == UnknownDepth && _continuationStackDepth == UnknownDepth);90 91 _stackDepth = instructions.CurrentStackDepth;92 _continuationStackDepth = instructions.CurrentContinuationsDepth;93 _targetIndex = instructions.Count;94 95 if (_forwardBranchFixups != null)96 {97 foreach (var branchIndex in _forwardBranchFixups)98 {99 FixupBranch(instructions, branchIndex);100 }101 102 _forwardBranchFixups = null;103 }104 }105 106 internal void AddBranch(InstructionList instructions, int branchIndex)107 {108 Debug.Assert(((_targetIndex == UnknownIndex) == (_stackDepth == UnknownDepth)));109 Debug.Assert(((_targetIndex == UnknownIndex) == (_continuationStackDepth == UnknownDepth)));110 111 if (_targetIndex == UnknownIndex)112 {113 _forwardBranchFixups ??= new List<int>();114 115 _forwardBranchFixups.Add(branchIndex);116 }117 else118 {119 FixupBranch(instructions, branchIndex);120 }121 }122 123 internal void FixupBranch(InstructionList instructions, int branchIndex)124 {125 Debug.Assert(_targetIndex != UnknownIndex);126 instructions.FixupBranch(branchIndex, _targetIndex - branchIndex);127 }128 }129}130 