Exemplo n.º 1
0
        private static void UpdateScopeStack <TInstruction>(
            IndexableStack <ScopeInfo <TInstruction> > scopeStack, ControlFlowNode <TInstruction> node)
        {
            // Figure out regions the node is in.
            var activeRegions = node.GetSituatedRegions()
                                .Reverse()
                                .ToArray();

            // Leave for every left region a scope block.
            int commonDepth = GetCommonRegionDepth(scopeStack, activeRegions);

            while (scopeStack.Count > commonDepth)
            {
                scopeStack.Pop();
            }

            // Enter for every entered region a new block.
            while (scopeStack.Count < activeRegions.Length)
            {
                EnterNextRegion(scopeStack, activeRegions);
            }
        }
Exemplo n.º 2
0
        private void UpdateScopeStack(ControlFlowNode <TInstruction> node, IndexableStack <ScopeInfo> scopeStack)
        {
            var activeRegions = node.GetSituatedRegions()
                                .Reverse()
                                .ToArray();

            int largestPossibleCommonDepth = Math.Min(scopeStack.Count, activeRegions.Length);

            // Figure out common region depth.
            int commonDepth = 1;

            while (commonDepth < largestPossibleCommonDepth)
            {
                if (scopeStack[commonDepth].Region != activeRegions[commonDepth])
                {
                    break;
                }
                commonDepth++;
            }

            // Leave for every left region a scope block.
            while (scopeStack.Count > commonDepth)
            {
                scopeStack.Pop();
            }

            // Enter for every entered region a new block.
            while (scopeStack.Count < activeRegions.Length)
            {
                // Create new scope block.
                var enteredRegion = activeRegions[scopeStack.Count];

                // Add new cope block to the current scope.
                var currentScope = scopeStack.Peek();

                if (enteredRegion is ExceptionHandlerRegion <TInstruction> ehRegion)
                {
                    // We entered an exception handler region.
                    var ehBlock = new ExceptionHandlerBlock <TInstruction>();
                    currentScope.AddBlock(ehBlock);
                    scopeStack.Push(new ScopeInfo(ehRegion, ehBlock));
                }
                else if (enteredRegion.ParentRegion is ExceptionHandlerRegion <TInstruction> parentEhRegion)
                {
                    // We entered one of the exception handler sub regions. Figure out which one it is.
                    var enteredBlock = default(ScopeBlock <TInstruction>);

                    if (!(currentScope.Block is ExceptionHandlerBlock <TInstruction> ehBlock))
                    {
                        throw new InvalidOperationException("The parent scope is not an exception handler scope.");
                    }

                    if (parentEhRegion.ProtectedRegion == enteredRegion)
                    {
                        // We entered the protected region.
                        enteredBlock = ehBlock.ProtectedBlock;
                    }
                    else
                    {
                        // We entered a handler region.
                        enteredBlock = new ScopeBlock <TInstruction>();
                        ehBlock.HandlerBlocks.Add(enteredBlock);
                    }

                    // Push the entered scope.
                    scopeStack.Push(new ScopeInfo(parentEhRegion.ProtectedRegion, enteredBlock));
                }
                else
                {
                    // Fall back method: just enter a new scope block.
                    var scopeBlock = new ScopeBlock <TInstruction>();
                    currentScope.AddBlock(scopeBlock);
                    scopeStack.Push(new ScopeInfo(enteredRegion, scopeBlock));
                }
            }
        }