Ejemplo n.º 1
0
        private static string DetermineRegionPrefix(IControlFlowRegion <TInstruction> region)
        {
            string prefix = null;

            switch (region)
            {
            case BasicControlFlowRegion <TInstruction> basicRegion:
                if (basicRegion.ParentRegion is ExceptionHandlerRegion <TInstruction> parentEh)
                {
                    if (parentEh.ProtectedRegion == basicRegion)
                    {
                        prefix = "cluster_protected";
                    }
                    else if (parentEh.HandlerRegions.Contains(basicRegion))
                    {
                        prefix = "cluster_handler";
                    }
                }

                prefix ??= "cluster_block";
                break;

            case ExceptionHandlerRegion <TInstruction> _:
                prefix = "cluster_eh";
                break;

            default:
                prefix = "cluster_region";
                break;
            }

            return(prefix);
        }
Ejemplo n.º 2
0
        private static void EnterGenericRegion <TInstruction>(IndexableStack <ScopeInfo <TInstruction> > scopeStack,
                                                              IControlFlowRegion <TInstruction> enteredRegion)
        {
            var scopeBlock = new ScopeBlock <TInstruction>();

            scopeStack.Peek().AddBlock(scopeBlock);
            scopeStack.Push(new ScopeInfo <TInstruction>(enteredRegion, scopeBlock));
        }
Ejemplo n.º 3
0
        private (DotEntityStyle Style, string Label) GetSubGraphStyle(IControlFlowRegion <TInstruction> region)
        {
            switch (region)
            {
            case ScopeRegion <TInstruction> basicRegion:
                return(GetScopeStyle(basicRegion));

            case ExceptionHandlerRegion <TInstruction> _:
                return(ExceptionHandlerStyle, ExceptionHandlerLabel);

            case HandlerRegion <TInstruction> _:
                return(HandlerStyle, HandlerLabel);
            }

            return(DefaultStyle, string.Empty);
        }
Ejemplo n.º 4
0
        private static string DetermineRegionPrefix(IControlFlowRegion <TInstruction> region)
        {
            switch (region)
            {
            case ScopeRegion <TInstruction> scopeRegion:
                return(GetScopeRegionPrefix(scopeRegion));

            case ExceptionHandlerRegion <TInstruction> _:
                return("cluster_eh");

            case HandlerRegion <TInstruction> _:
                return("cluster_handler");

            default:
                return("cluster_region");
            }
        }
Ejemplo n.º 5
0
        private static void EnterExceptionHandlerSubRegion <TInstruction>(
            IndexableStack <ScopeInfo <TInstruction> > scopeStack,
            ExceptionHandlerRegion <TInstruction> parentRegion,
            IControlFlowRegion <TInstruction> enteredRegion)
        {
            IBlock <TInstruction>             enteredBlock;
            IControlFlowRegion <TInstruction> enteredSubRegion;

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

            // Did we enter the protected region, or one of the handler regions?
            if (parentRegion.ProtectedRegion == enteredRegion)
            {
                // We entered the protected region.
                enteredBlock     = ehBlock.ProtectedBlock;
                enteredSubRegion = parentRegion.ProtectedRegion;
            }
            else
            {
                // We entered a handler region.
                var handlerRegion = parentRegion.Handlers.First(r => r == enteredRegion);
                var handlerBlock  = new HandlerBlock <TInstruction>
                {
                    Tag = handlerRegion.Tag
                };

                enteredBlock     = handlerBlock;
                enteredSubRegion = handlerRegion;
                ehBlock.Handlers.Add(handlerBlock);
            }

            // Sanity check: If the entered subregion's parent is the exception handler region but the region
            // isn't a protected, prologue, epilogue nor one of the handler regions, that would mean that
            // something went *seriously* wrong.
            if (enteredSubRegion is null)
            {
                throw new InvalidOperationException(
                          "Entered subregion of exception handler doesn't belong to any of its regions!?");
            }

            // Push the entered scope.
            scopeStack.Push(new ScopeInfo <TInstruction>(enteredSubRegion, enteredBlock));
        }
Ejemplo n.º 6
0
        private ControlFlowRegion <Statement <TInstruction> > TransformRegion(IControlFlowRegion <TInstruction> region)
        {
            switch (region)
            {
            case BasicControlFlowRegion <TInstruction> basicRegion:
                // Create new basic region.
                var newBasicRegion = new BasicControlFlowRegion <Statement <TInstruction> >();
                TransformSubRegions(basicRegion, newBasicRegion);

                // Register basic region pair.
                _context.RegionsMapping[basicRegion] = newBasicRegion;

                return(newBasicRegion);

            case ExceptionHandlerRegion <TInstruction> ehRegion:
                var newEhRegion = new ExceptionHandlerRegion <Statement <TInstruction> >();

                // ProtectedRegion is read-only, so instead we just transform all sub regions and add it to the
                // existing protected region.
                TransformSubRegions(ehRegion.ProtectedRegion, newEhRegion.ProtectedRegion);
                _context.RegionsMapping[ehRegion.ProtectedRegion] = newEhRegion.ProtectedRegion;

                // Add handler regions.
                foreach (var subRegion in ehRegion.HandlerRegions)
                {
                    newEhRegion.HandlerRegions.Add(TransformRegion(subRegion));
                }

                return(newEhRegion);

            default:
                throw new ArgumentOutOfRangeException(nameof(region));
            }

            void TransformSubRegions(
                BasicControlFlowRegion <TInstruction> originalRegion,
                BasicControlFlowRegion <Statement <TInstruction> > newRegion)
            {
                foreach (var subRegion in originalRegion.Regions)
                {
                    newRegion.Regions.Add(TransformRegion(subRegion));
                }
            }
        }
Ejemplo n.º 7
0
        private static void EnterHandlerSubRegion <TInstruction>(
            IndexableStack <ScopeInfo <TInstruction> > scopeStack,
            HandlerRegion <TInstruction> parentRegion,
            IControlFlowRegion <TInstruction> enteredRegion)
        {
            IBlock <TInstruction>             enteredBlock;
            IControlFlowRegion <TInstruction> enteredSubRegion;

            if (!(scopeStack.Peek().Block is HandlerBlock <TInstruction> handlerBlock))
            {
                throw new InvalidOperationException("The parent scope is not a handler scope.");
            }

            if (parentRegion.Prologue == enteredRegion)
            {
                // We entered the prologue.
                handlerBlock.Prologue = new ScopeBlock <TInstruction>();
                enteredBlock          = handlerBlock.Prologue;
                enteredSubRegion      = parentRegion.Prologue;
            }
            else if (parentRegion.Contents == enteredRegion)
            {
                // We entered the contents.
                enteredBlock     = handlerBlock.Contents;
                enteredSubRegion = parentRegion.Contents;
            }
            else if (parentRegion.Epilogue == enteredRegion)
            {
                // We entered the epilogue.
                handlerBlock.Epilogue = new ScopeBlock <TInstruction>();
                enteredBlock          = handlerBlock.Epilogue;
                enteredSubRegion      = parentRegion.Epilogue;
            }
            else
            {
                // Exhaustive search, this should never happen.
                throw new InvalidOperationException(
                          "Entered subregion of handler doesn't belong to any of its regions.");
            }

            // Push the entered scope.
            scopeStack.Push(new ScopeInfo <TInstruction>(enteredSubRegion, enteredBlock));
        }
Ejemplo n.º 8
0
        /// <summary>
        /// Obtains the parent exception handler region that this region resides in (if any).
        /// </summary>
        /// <returns>
        /// The parent exception handler region, or <c>null</c> if the region is not part of any exception handler.
        /// </returns>
        public static ExceptionHandlerRegion <TInstruction> GetParentExceptionHandler <TInstruction>(this IControlFlowRegion <TInstruction> self)
        {
            var region = self.ParentRegion;

            while (region is {})
Ejemplo n.º 9
0
 /// <summary>
 /// Creates a new instance of the <see cref="RegionCollection{TInstruction}"/> class.
 /// </summary>
 /// <param name="owner">The owner of the sub regions.</param>
 public RegionCollection(IControlFlowRegion <TInstruction> owner)
 {
     _owner = owner ?? throw new ArgumentNullException(nameof(owner));
 }
Ejemplo n.º 10
0
 public ScopeInfo(IControlFlowRegion <TInstruction> region, IBlock <TInstruction> block)
 {
     Region = region ?? throw new ArgumentNullException(nameof(region));
     Block  = block ?? throw new ArgumentNullException(nameof(block));
 }
Ejemplo n.º 11
0
        /// <summary>
        /// Obtains the parent region of a specific type that this region resides in (if any).
        /// </summary>
        /// <returns>
        /// The parent region, or <c>null</c> if the region is not part of any region of type <typeparamref name="TRegion"/>.
        /// </returns>
        private static TRegion GetParentRegion <TInstruction, TRegion>(IControlFlowRegion <TInstruction> self)
            where TRegion : class, IControlFlowRegion <TInstruction>
        {
            var region = self.ParentRegion;

            while (region is {})
Ejemplo n.º 12
0
 /// <summary>
 /// Obtains the parent handler region that this region resides in (if any).
 /// </summary>
 /// <returns>
 /// The parent exception handler region, or <c>null</c> if the region is not part of any exception handler.
 /// </returns>
 public static HandlerRegion <TInstruction> GetParentHandler <TInstruction>(this IControlFlowRegion <TInstruction> self) =>
 GetParentRegion <TInstruction, HandlerRegion <TInstruction> >(self);