예제 #1
0
        protected Scope(ScopeBounds bounds, ScopeNesting nesting)
        {
            Bounds  = Guard.MustBeDefined(bounds, "bounds");
            Nesting = Guard.MustBeDefined(nesting, "nesting");

            Initialize();
        }
예제 #2
0
            /// <summary>
            /// Gets all scopes that contain variables.
            /// </summary>
            /// <param name="edgeInclusive">Specifies whether scope spans should be reported as edge inclusive
            /// (position at "start + length" is IN the scope). VB EE expects that.</param>
            /// <returns></returns>
            /// <remarks>
            /// NOTE that edgeInclusive affects only how results are _reported_.
            /// All internal representation is EDGE EXCLUSIVE.
            /// </remarks>
            internal ImmutableArray <Cci.LocalScope> GetAllScopesWithLocals(bool edgeInclusive = false)
            {
                var result = ArrayBuilder <Cci.LocalScope> .GetInstance();

                ScopeBounds rootBounds = _rootScope.GetLocalScopes(result, edgeInclusive);

                uint expectedRootScopeLength = rootBounds.End - rootBounds.Begin;

                if (edgeInclusive)
                {
                    expectedRootScopeLength--;
                }

                // Add root scope if it was not already added.
                // we add it even if it does not contain any locals
                if (result.Count > 0 && result[result.Count - 1].Length != expectedRootScopeLength)
                {
                    result.Add(new Cci.LocalScope(
                                   0,
                                   expectedRootScopeLength,
                                   ImmutableArray <Cci.ILocalDefinition> .Empty,
                                   ImmutableArray <Cci.ILocalDefinition> .Empty));
                }

                //scopes should be sorted by position and size
                result.Sort(ScopeComparer.Instance);

                return(result.ToImmutableAndFree());
            }
            private static ScopeBounds GetBounds(ExceptionHandlerScope scope)
            {
                ArrayBuilder <Cci.LocalScope> scopes = ArrayBuilder <Cci.LocalScope> .GetInstance();

                ScopeBounds result = scope.GetLocalScopes(scopes);

                scopes.Free();
                return(result);
            }
예제 #4
0
            internal override ScopeBounds GetIteratorScopes(ArrayBuilder <Cci.LocalScope> scopesWithIteratorLocals, bool edgeInclusive)
            {
                uint begin = uint.MaxValue;
                uint end   = 0;

                // It may seem overkill to scan all blocks,
                // but blocks may be reordered so we cannot be sure which ones are first/last.
                if (Blocks != null)
                {
                    for (int i = 0; i < Blocks.Count; i++)
                    {
                        var block = Blocks[i];

                        if (block.Reachability != Reachability.NotReachable)
                        {
                            begin = Math.Min(begin, (uint)block.Start);
                            end   = Math.Max(end, (uint)(block.Start + block.TotalSize));
                        }
                    }
                }

                // if there are nested scopes, dump them too
                // also may need to adjust current scope bounds.
                if (NestedScopes != null)
                {
                    ScopeBounds nestedBounds = GetIteratorScopes(scopesWithIteratorLocals, NestedScopes, edgeInclusive);
                    begin = Math.Min(begin, nestedBounds.Begin);
                    end   = Math.Max(end, nestedBounds.End);
                }

                // we are not interested in scopes with no variables or no code in them.
                if (this.IteratorVariables != null && end > begin)
                {
                    uint endAdjusted = edgeInclusive ? end - 1 : end;

                    var newScope = new Cci.LocalScope(
                        begin,
                        endAdjusted - begin,
                        ImmutableArray <Cci.ILocalDefinition> .Empty,
                        ImmutableArray <Cci.ILocalDefinition> .Empty);

                    foreach (var iv in this.IteratorVariables)
                    {
                        while (scopesWithIteratorLocals.Count <= iv)
                        {
                            scopesWithIteratorLocals.Add(default(Cci.LocalScope));
                        }

                        scopesWithIteratorLocals[iv] = newScope;
                    }
                }

                return(new ScopeBounds(begin, end));
            }
예제 #5
0
            internal override ScopeBounds GetHoistedLocalScopes(ArrayBuilder <Cci.StateMachineHoistedLocalScope> result, bool edgeInclusive)
            {
                uint begin = uint.MaxValue;
                uint end   = 0;

                // It may seem overkill to scan all blocks,
                // but blocks may be reordered so we cannot be sure which ones are first/last.
                if (Blocks != null)
                {
                    for (int i = 0; i < Blocks.Count; i++)
                    {
                        var block = Blocks[i];

                        if (block.Reachability != Reachability.NotReachable)
                        {
                            begin = Math.Min(begin, (uint)block.Start);
                            end   = Math.Max(end, (uint)(block.Start + block.TotalSize));
                        }
                    }
                }

                // if there are nested scopes, dump them too
                // also may need to adjust current scope bounds.
                if (_nestedScopes != null)
                {
                    ScopeBounds nestedBounds = GetHoistedLocalScopes(result, _nestedScopes, edgeInclusive);
                    begin = Math.Min(begin, nestedBounds.Begin);
                    end   = Math.Max(end, nestedBounds.End);
                }

                // we are not interested in scopes with no variables or no code in them.
                if (_stateMachineUserHoistedLocalSlotIndices != null && end > begin)
                {
                    uint endAdjusted = edgeInclusive ? end - 1 : end;

                    var newScope = new Cci.StateMachineHoistedLocalScope(begin, endAdjusted);

                    foreach (var slotIndex in _stateMachineUserHoistedLocalSlotIndices)
                    {
                        while (result.Count <= slotIndex)
                        {
                            result.Add(default(Cci.StateMachineHoistedLocalScope));
                        }

                        result[slotIndex] = newScope;
                    }
                }

                return(new ScopeBounds(begin, end));
            }
예제 #6
0
            internal override ScopeBounds GetScopesWithLocals(ArrayBuilder <LocalScope> scopesWithVariables, bool edgeInclusive)
            {
                uint begin = uint.MaxValue;
                uint end   = 0;

                // It may seem overkill to scan all blocks,
                // but blocks may be reordered so we cannot be sure which ones are first/last.
                if (Blocks != null)
                {
                    for (int i = 0; i < Blocks.Count; i++)
                    {
                        var block = Blocks[i];

                        if (block.Reachability != Reachability.NotReachable)
                        {
                            begin = Math.Min(begin, (uint)block.Start);
                            end   = Math.Max(end, (uint)(block.Start + block.TotalSize));
                        }
                    }
                }

                // if there are nested scopes, dump them too
                // also may need to adjust current scope bounds.
                if (NestedScopes != null)
                {
                    ScopeBounds nestedBounds = GetScopesWithLocals(scopesWithVariables, NestedScopes, edgeInclusive);
                    begin = Math.Min(begin, nestedBounds.Begin);
                    end   = Math.Max(end, nestedBounds.End);
                }

                // we are not interested in scopes with no variables or no code in them.
                if ((this.LocalVariables != null || this.LocalConstants != null) && end > begin)
                {
                    uint endAdjusted = edgeInclusive ? end - 1 : end;
                    IEnumerable <Microsoft.Cci.ILocalDefinition> localConstantDefinitions = this.LocalConstants == null
                        ? SpecializedCollections.EmptyEnumerable <Microsoft.Cci.ILocalDefinition>()
                        : this.LocalConstants.ToArray();

                    IEnumerable <Microsoft.Cci.ILocalDefinition> localDefinitions = this.LocalVariables == null
                        ? SpecializedCollections.EmptyEnumerable <Microsoft.Cci.ILocalDefinition>()
                        : this.LocalVariables.ToArray();

                    LocalScope newScope = new LocalScope(begin, endAdjusted, null, localConstantDefinitions, localDefinitions);
                    scopesWithVariables.Add(newScope);
                }

                return(new ScopeBounds(begin, end));
            }
            protected static ScopeBounds GetHoistedLocalScopes <TScopeInfo>(ArrayBuilder <StateMachineHoistedLocalScope> result, ImmutableArray <TScopeInfo> .Builder scopes)
                where TScopeInfo : ScopeInfo
            {
                Debug.Assert(scopes.Count > 0);

                int begin = int.MaxValue;
                int end   = 0;

                foreach (TScopeInfo scope in scopes)
                {
                    ScopeBounds bounds = scope.GetHoistedLocalScopes(result);
                    begin = Math.Min(begin, bounds.Begin);
                    end   = Math.Max(end, bounds.End);
                }

                return(new ScopeBounds(begin, end));
            }
예제 #8
0
            internal override ScopeBounds GetLocalScopes(ArrayBuilder <Cci.LocalScope> result, bool edgeInclusive)
            {
                uint begin = uint.MaxValue;
                uint end   = 0;

                // It may seem overkill to scan all blocks,
                // but blocks may be reordered so we cannot be sure which ones are first/last.
                if (Blocks != null)
                {
                    for (int i = 0; i < Blocks.Count; i++)
                    {
                        var block = Blocks[i];

                        if (block.Reachability != Reachability.NotReachable)
                        {
                            begin = Math.Min(begin, (uint)block.Start);
                            end   = Math.Max(end, (uint)(block.Start + block.TotalSize));
                        }
                    }
                }

                // if there are nested scopes, dump them too
                // also may need to adjust current scope bounds.
                if (_nestedScopes != null)
                {
                    ScopeBounds nestedBounds = GetLocalScopes(result, _nestedScopes, edgeInclusive);
                    begin = Math.Min(begin, nestedBounds.Begin);
                    end   = Math.Max(end, nestedBounds.End);
                }

                // we are not interested in scopes with no variables or no code in them.
                if ((_localVariables != null || _localConstants != null) && end > begin)
                {
                    uint endAdjusted = edgeInclusive ? end - 1 : end;

                    var newScope = new Cci.LocalScope(
                        begin,
                        endAdjusted - begin,
                        _localConstants.AsImmutableOrEmpty <Cci.ILocalDefinition>(),
                        _localVariables.AsImmutableOrEmpty <Cci.ILocalDefinition>());

                    result.Add(newScope);
                }

                return(new ScopeBounds(begin, end));
            }
예제 #9
0
            protected static ScopeBounds GetLocalScopes <TScopeInfo>(ArrayBuilder <Cci.LocalScope> result, ImmutableArray <TScopeInfo> .Builder scopes, bool edgeInclusive)
                where TScopeInfo : ScopeInfo
            {
                Debug.Assert(scopes.Count > 0);

                uint begin = uint.MaxValue;
                uint end   = 0;

                foreach (var scope in scopes)
                {
                    ScopeBounds bounds = scope.GetLocalScopes(result, edgeInclusive);
                    begin = Math.Min(begin, bounds.Begin);
                    end   = Math.Max(end, bounds.End);
                }

                return(new ScopeBounds(begin, end));
            }
            internal override void GetExceptionHandlerRegions(ArrayBuilder <Cci.ExceptionHandlerRegion> regions)
            {
                Debug.Assert(_handlers.Count > 1);

                ExceptionHandlerScope tryScope  = null;
                ScopeBounds           tryBounds = new ScopeBounds();

                foreach (ExceptionHandlerScope handlerScope in _handlers)
                {
                    // Partition I, section 12.4.2.5:
                    // The ordering of the exception clauses in the Exception Handler Table is important. If handlers are nested,
                    // the most deeply nested try blocks shall come before the try blocks that enclose them.
                    //
                    // so we collect the inner regions first.
                    handlerScope.GetExceptionHandlerRegions(regions);

                    ScopeBounds handlerBounds = GetBounds(handlerScope);

                    if (tryScope == null)
                    {
                        // the first scope that we see should be Try.
                        Debug.Assert(handlerScope.Type == ScopeType.Try);

                        tryScope  = handlerScope;
                        tryBounds = handlerBounds;

                        Reachability reachability = tryScope.LeaderBlock.Reachability;
                        Debug.Assert((reachability == Reachability.Reachable) || (reachability == Reachability.NotReachable));

                        // All handler blocks should have same reachability.
                        Debug.Assert(_handlers.All(h => (h.LeaderBlock.Reachability == reachability)));

                        if (reachability != Reachability.Reachable)
                        {
                            return;
                        }
                    }
                    else
                    {
                        Cci.ExceptionHandlerRegion region;
                        switch (handlerScope.Type)
                        {
                        case ScopeType.Finally:
                            region = new Cci.ExceptionHandlerRegionFinally(tryBounds.Begin, tryBounds.End, handlerBounds.Begin, handlerBounds.End);
                            break;

                        case ScopeType.Fault:
                            region = new Cci.ExceptionHandlerRegionFault(tryBounds.Begin, tryBounds.End, handlerBounds.Begin, handlerBounds.End);
                            break;

                        case ScopeType.Catch:
                            region = new Cci.ExceptionHandlerRegionCatch(tryBounds.Begin, tryBounds.End, handlerBounds.Begin, handlerBounds.End, handlerScope.ExceptionType);
                            break;

                        case ScopeType.Filter:
                            region = new Cci.ExceptionHandlerRegionFilter(tryBounds.Begin, tryBounds.End, handlerScope.FilterHandlerStart, handlerBounds.End, handlerBounds.Begin);
                            break;

                        default:
                            throw ExceptionUtilities.UnexpectedValue(handlerScope.Type);
                        }

                        regions.Add(region);
                    }
                }
            }
예제 #11
0
 protected EnlistmentScope(ScopeBounds bounds, ScopeNesting nesting) : base(bounds, nesting)
 {
 }
예제 #12
0
 private SystemClock(ScopeBounds bounds, ScopeNesting nesting)
     : base(bounds, nesting)
 {
 }
예제 #13
0
 public StubScope(ScopeBounds bounds, ScopeNesting nesting) : base(bounds, nesting)
 {
 }
 public DisposableContext(ScopeBounds bounds, ScopeNesting nesting) : base(bounds, nesting)
 {
 }