Esempio n. 1
0
        public static bool MatchStloc(this ILNode node, ILVariable expectedVar, out ILExpression expr)
        {
            ILVariable v;

            return(node.Match(ILCode.Stloc, out v, out expr) && v == expectedVar);
        }
Esempio n. 2
0
        public static bool MatchThis(this ILNode node)
        {
            ILVariable v;

            return(node.Match(ILCode.Ldloc, out v) && v.IsParameter && v.OriginalParameter.Index == -1);
        }
Esempio n. 3
0
        public static bool MatchLdloca(this ILNode node, ILVariable expectedVar)
        {
            ILVariable v;

            return(node.Match(ILCode.Ldloca, out v) && v == expectedVar);
        }
Esempio n. 4
0
        /// <summary>
        /// Group input into a set of blocks that can be later arbitraliby schufled.
        /// The method adds necessary branches to make control flow between blocks
        /// explicit and thus order independent.
        /// </summary>
        void SplitToBasicBlocks(ILBlock block)
        {
            List <ILNode> basicBlocks = new List <ILNode>();

            ILLabel entryLabel = block.Body.FirstOrDefault() as ILLabel ?? new ILLabel()
            {
                Name = "Block_" + (nextLabelIndex++)
            };
            ILBasicBlock basicBlock = new ILBasicBlock();

            basicBlocks.Add(basicBlock);
            basicBlock.Body.Add(entryLabel);
            block.EntryGoto = new ILExpression(ILCode.Br, entryLabel);

            if (block.Body.Count > 0)
            {
                if (block.Body[0] != entryLabel)
                {
                    basicBlock.Body.Add(block.Body[0]);
                }

                for (int i = 1; i < block.Body.Count; i++)
                {
                    ILNode lastNode = block.Body[i - 1];
                    ILNode currNode = block.Body[i];

                    // Start a new basic block if necessary
                    if (currNode is ILLabel ||
                        currNode is ILTryCatchBlock ||                     // Counts as label
                        lastNode.IsConditionalControlFlow() ||
                        lastNode.IsUnconditionalControlFlow())
                    {
                        // Try to reuse the label
                        ILLabel label = currNode as ILLabel ?? new ILLabel()
                        {
                            Name = "Block_" + (nextLabelIndex++).ToString()
                        };

                        // Terminate the last block
                        if (!lastNode.IsUnconditionalControlFlow())
                        {
                            // Explicit branch from one block to other
                            basicBlock.Body.Add(new ILExpression(ILCode.Br, label));
                        }

                        // Start the new block
                        basicBlock = new ILBasicBlock();
                        basicBlocks.Add(basicBlock);
                        basicBlock.Body.Add(label);

                        // Add the node to the basic block
                        if (currNode != label)
                        {
                            basicBlock.Body.Add(currNode);
                        }
                    }
                    else
                    {
                        basicBlock.Body.Add(currNode);
                    }
                }
            }

            block.Body = basicBlocks;
            return;
        }
Esempio n. 5
0
        public static bool IsUnconditionalControlFlow(this ILNode node)
        {
            ILExpression expr = node as ILExpression;

            return(expr != null && expr.Code.IsUnconditionalControlFlow());
        }
Esempio n. 6
0
        /// <summary>
        /// Get the first expression to be excecuted if the instruction pointer is at the start of the given node.
        /// Try blocks may not be entered in any way.  If possible, the try block is returned as the node to be executed.
        /// </summary>
        ILNode Enter(ILNode node, HashSet <ILNode> visitedNodes)
        {
            if (node == null)
            {
                throw new ArgumentNullException();
            }

            if (!visitedNodes.Add(node))
            {
                return(null);                 // Infinite loop
            }
            ILLabel label = node as ILLabel;

            if (label != null)
            {
                return(Exit(label, visitedNodes));
            }

            ILExpression expr = node as ILExpression;

            if (expr != null)
            {
                if (expr.Code == ILCode.Br || expr.Code == ILCode.Leave)
                {
                    ILLabel target = (ILLabel)expr.Operand;
                    // Early exit - same try-block
                    if (GetParents(expr).OfType <ILTryCatchBlock>().FirstOrDefault() == GetParents(target).OfType <ILTryCatchBlock>().FirstOrDefault())
                    {
                        return(Enter(target, visitedNodes));
                    }
                    // Make sure we are not entering any try-block
                    var srcTryBlocks = GetParents(expr).OfType <ILTryCatchBlock>().Reverse().ToList();
                    var dstTryBlocks = GetParents(target).OfType <ILTryCatchBlock>().Reverse().ToList();
                    // Skip blocks that we are already in
                    int i = 0;
                    while (i < srcTryBlocks.Count && i < dstTryBlocks.Count && srcTryBlocks[i] == dstTryBlocks[i])
                    {
                        i++;
                    }
                    if (i == dstTryBlocks.Count)
                    {
                        return(Enter(target, visitedNodes));
                    }
                    else
                    {
                        ILTryCatchBlock dstTryBlock = dstTryBlocks[i];
                        // Check that the goto points to the start
                        ILTryCatchBlock current = dstTryBlock;
                        while (current != null)
                        {
                            foreach (ILNode n in current.TryBlock.Body)
                            {
                                if (n is ILLabel)
                                {
                                    if (n == target)
                                    {
                                        return(dstTryBlock);
                                    }
                                }
                                else if (!n.Match(ILCode.Nop))
                                {
                                    current = n as ILTryCatchBlock;
                                    break;
                                }
                            }
                        }
                        return(null);
                    }
                }
                else if (expr.Code == ILCode.Nop)
                {
                    return(Exit(expr, visitedNodes));
                }
                else if (expr.Code == ILCode.LoopOrSwitchBreak)
                {
                    ILNode breakBlock = GetParents(expr).Where(n => n is ILWhileLoop || n is ILSwitch).First();
                    return(Exit(breakBlock, new HashSet <ILNode>()
                    {
                        expr
                    }));
                }
                else if (expr.Code == ILCode.LoopContinue)
                {
                    ILNode continueBlock = GetParents(expr).Where(n => n is ILWhileLoop).First();
                    return(Enter(continueBlock, new HashSet <ILNode>()
                    {
                        expr
                    }));
                }
                else
                {
                    return(expr);
                }
            }

            ILBlock block = node as ILBlock;

            if (block != null)
            {
                if (block.EntryGoto != null)
                {
                    return(Enter(block.EntryGoto, visitedNodes));
                }
                else if (block.Body.Count > 0)
                {
                    return(Enter(block.Body[0], visitedNodes));
                }
                else
                {
                    return(Exit(block, visitedNodes));
                }
            }

            ILCondition cond = node as ILCondition;

            if (cond != null)
            {
                return(cond.Condition);
            }

            ILWhileLoop loop = node as ILWhileLoop;

            if (loop != null)
            {
                if (loop.Condition != null)
                {
                    return(loop.Condition);
                }
                else
                {
                    return(Enter(loop.BodyBlock, visitedNodes));
                }
            }

            ILTryCatchBlock tryCatch = node as ILTryCatchBlock;

            if (tryCatch != null)
            {
                return(tryCatch);
            }

            ILSwitch ilSwitch = node as ILSwitch;

            if (ilSwitch != null)
            {
                return(ilSwitch.Condition);
            }

            throw new NotSupportedException(node.GetType().ToString());
        }
Esempio n. 7
0
 /// <summary>
 /// Initializes the state range logic:
 /// Clears 'ranges' and sets 'ranges[entryPoint]' to the full range (int.MinValue to int.MaxValue)
 /// </summary>
 void InitStateRanges(ILNode entryPoint)
 {
     ranges                     = new DefaultDictionary <ILNode, StateRange>(n => new StateRange());
     ranges[entryPoint]         = new StateRange(int.MinValue, int.MaxValue);
     rangeAnalysisStateVariable = null;
 }
        public static bool Match(this ILNode node, ILCode code)
        {
            ILExpression expr = node as ILExpression;

            return(expr != null && expr.Prefixes == null && expr.Code == code);
        }