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); } }
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)); } } }