예제 #1
0
        public FlowGraphNode Split(long labelValue, long prevLabelValue)
        {
            if (nodes.ContainsKey(labelValue))
            {
                return(nodes[labelValue]);
            }
            FlowGraphNode n1 = Find(labelValue);

            if (n1 == null)
            {
                return(null);
            }
            FlowGraphNode n2 = NewNode(labelValue);

            //断开n1与它的后继并将之添加为n2的后继
            FlowGraphNode[] n1s = new FlowGraphNode[n1.NextNodes.Count];
            n1.NextNodes.CopyTo(n1s, 0);
            foreach (FlowGraphNode n in n1s)
            {
                n1.DelNext(n);
                n2.AddNext(n);
            }
            //将n2添加为n1的后继
            n1.AddNext(n2);
            //设置n2的结束标签为n1的结束标签,若n1的结束标签不大于n2的开始标签则不调整n2的结束标签
            if (n1.EndLabelValue > n2.LabelValue)
            {
                n2.EndLabelValue = n1.EndLabelValue;
            }
            //设置n1的结束标签为分离标签的前一个标签
            n1.EndLabelValue = prevLabelValue;

            return(n2);
        }
예제 #2
0
        private void BuildFlowGraph()
        {
            flowGraph = new FlowGraph();
            FlowGraphNode curNode     = null;
            FlowGraphNode prevNode    = null;
            bool          nextIsBlock = true;

            for (int i = 0; i < ilLines.Count; i++)
            {
                IlIns il = ilLines.Values[i];
                if (nextIsBlock)
                {
                    nextIsBlock = false;
                    FlowGraphNode node = flowGraph.NewNode(il.LabelValue);
                    curNode = node;
                    if (prevNode != null)
                    {
                        prevNode.AddNext(node);
                    }
                }
                else
                {
                    if (flowGraph.IsNode(il.LabelValue))
                    {
                        FlowGraphNode node = flowGraph[il.LabelValue];
                        curNode.EndLabelValue = GetPrevIlLabelValue(il.LabelValue);
                        curNode.AddNext(node);
                        curNode = node;
                    }
                }
                IlOpcode op0 = IlOpcodes.GetEH(il.Opcode);
                if (op0 != IlOpcode.Prefixref)
                {
                    switch (op0)
                    {
                    case IlOpcode.TRY:
                    {
                        FlowGraphNode node = flowGraph.NewNode(il.LabelValue);
                        if (curNode != null)
                        {
                            curNode.AddNext(node);
                        }
                        curNode = node;
                    }
                    break;

                    case IlOpcode.CATCH:
                    {
                        FlowGraphNode node = flowGraph.NewNode(il.LabelValue);
                        curNode = node;
                    }
                    break;

                    case IlOpcode.FINALLY:
                    {
                        FlowGraphNode node = flowGraph.NewNode(il.LabelValue);
                        curNode = node;
                    }
                    break;

                    case IlOpcode.FILTER:
                    {
                        FlowGraphNode node = flowGraph.NewNode(il.LabelValue);
                        curNode = node;
                    }
                    break;

                    case IlOpcode.FAULT:
                    {
                        FlowGraphNode node = flowGraph.NewNode(il.LabelValue);
                        curNode = node;
                    }
                    break;

                    case IlOpcode.ENDTRY:
                    case IlOpcode.ENDCATCH:
                    case IlOpcode.ENDFINALLY:
                    case IlOpcode.ENDFILTER:
                    case IlOpcode.ENDFAULT:
                    {
                        curNode.EndLabelValue = il.LabelValue;
                        prevNode    = null;
                        nextIsBlock = true;
                    }
                    break;
                    }
                }
                else
                {
                    OpCode op = IlOpcodes.Get(il.Opcode);
                    switch ((IlOpcode)op.Value)
                    {
                    case IlOpcode.Br:
                    case IlOpcode.Br_S:
                    {
                        long          val  = IlIns.LabelToValue(il.Value);
                        FlowGraphNode node = null;
                        if (val > il.LabelValue)
                        {
                            node = flowGraph.NewNode(val);
                            curNode.AddNext(node);
                        }
                        else
                        {
                            long          prevVal = GetPrevIlLabelValue(val);
                            FlowGraphNode d       = flowGraph.Find(val);
                            node = flowGraph.Split(val, prevVal);
                            if (curNode != d)
                            {
                                curNode.AddNext(node);
                            }
                            else
                            {
                                node.AddNext(node);
                                curNode = node;
                            }
                        }
                        curNode.EndLabelValue = il.LabelValue;
                        prevNode    = null;
                        nextIsBlock = true;
                    }
                    break;

                    case IlOpcode.Brtrue:
                    case IlOpcode.Brfalse:
                    case IlOpcode.Brtrue_S:
                    case IlOpcode.Brfalse_S:
                    case IlOpcode.Beq_S:
                    case IlOpcode.Bge_S:
                    case IlOpcode.Bgt_S:
                    case IlOpcode.Ble_S:
                    case IlOpcode.Blt_S:
                    case IlOpcode.Bne_Un_S:
                    case IlOpcode.Bge_Un_S:
                    case IlOpcode.Bgt_Un_S:
                    case IlOpcode.Ble_Un_S:
                    case IlOpcode.Blt_Un_S:
                    case IlOpcode.Beq:
                    case IlOpcode.Bge:
                    case IlOpcode.Bgt:
                    case IlOpcode.Ble:
                    case IlOpcode.Blt:
                    case IlOpcode.Bne_Un:
                    case IlOpcode.Bge_Un:
                    case IlOpcode.Bgt_Un:
                    case IlOpcode.Ble_Un:
                    case IlOpcode.Blt_Un:
                    {
                        long          val  = IlIns.LabelToValue(il.Value);
                        FlowGraphNode node = null;
                        if (val > il.LabelValue)
                        {
                            node = flowGraph.NewNode(val);
                            curNode.AddNext(node);
                        }
                        else
                        {
                            long          prevVal = GetPrevIlLabelValue(val);
                            FlowGraphNode d       = flowGraph.Find(val);
                            node = flowGraph.Split(val, prevVal);
                            if (curNode != d)
                            {
                                curNode.AddNext(node);
                            }
                            else
                            {
                                node.AddNext(node);
                                curNode = node;
                            }
                        }
                        curNode.EndLabelValue = il.LabelValue;
                        prevNode    = curNode;
                        nextIsBlock = true;
                    }
                    break;

                    case IlOpcode.Switch:
                    {
                        SwitchOperand opVal = il.Operand as SwitchOperand;
                        foreach (string label in opVal.Labels)
                        {
                            long          val  = IlIns.LabelToValue(label);
                            FlowGraphNode node = null;
                            if (val > il.LabelValue)
                            {
                                node = flowGraph.NewNode(val);
                                curNode.AddNext(node);
                            }
                            else
                            {
                                long          prevVal = GetPrevIlLabelValue(val);
                                FlowGraphNode d       = flowGraph.Find(val);
                                node = flowGraph.Split(val, prevVal);
                                if (curNode != d)
                                {
                                    curNode.AddNext(node);
                                }
                                else
                                {
                                    node.AddNext(node);
                                    curNode = node;
                                }
                            }
                        }
                        curNode.EndLabelValue = il.LabelValue;
                        prevNode    = curNode;
                        nextIsBlock = true;
                    }
                    break;

                    case IlOpcode.Ret:
                    case IlOpcode.Break:
                    case IlOpcode.Throw:
                    case IlOpcode.Rethrow:
                    case IlOpcode.Leave:
                    case IlOpcode.Leave_S:
                    case IlOpcode.Endfilter:
                    case IlOpcode.Endfinally:
                    {
                        curNode.EndLabelValue = il.LabelValue;
                        prevNode    = null;
                        nextIsBlock = true;
                    }
                    break;
                    }
                }
            }
        }
예제 #3
0
 public void Combine(FlowGraphNode n1, FlowGraphNode n2)
 {
     if (n1 == null || n2 == null)
     {
         return;
     }
     if (n2.PrevNodes.Count == 1 && n2.PrevNodes[0] == n1 && n1.NextNodes.Count == 1 && n1.NextNodes[0] == n2)//合并条件:n2必须是n1的唯一后继,n1必须是n2的唯一前导
     {
         //断开n1与n2的关联
         n1.DelNext(n2);
         //断开n2与其后继的关联,并将其后继添加为n1的后继
         FlowGraphNode[] n2s = new FlowGraphNode[n2.NextNodes.Count];
         n2.NextNodes.CopyTo(n2s, 0);
         foreach (FlowGraphNode n in n2s)
         {
             n2.DelNext(n);
             n1.AddNext(n);
         }
         //n1的结束标签改为n2的结束标签
         n1.EndLabelValue = n2.EndLabelValue;
         //删除流图对n2的记忆
         nodes.Remove(n2.LabelValue);
         accessedNodes.Remove(n2);
         unaccessedNodes.Remove(n2);
         bool inStack = false;
         foreach (FlowGraphNode n in iterateStack)
         {
             if (n == n2)
             {
                 inStack = true;
                 break;
             }
         }
         if (inStack)
         {
             FlowGraphNode[] ns = iterateStack.ToArray();
             iterateStack.Clear();
             for (int i = ns.Length - 1; i >= 0; i--)
             {
                 if (ns[i] != n2)
                 {
                     iterateStack.Push(ns[i]);
                 }
             }
         }
         if (curNode == n2)
         {
             curNode = n1;
             //设置n1为已访问
             AccessNode(n1);
             //删除迭代器栈里的n1
             inStack = false;
             foreach (FlowGraphNode n in iterateStack)
             {
                 if (n == n1)
                 {
                     inStack = true;
                     break;
                 }
             }
             if (inStack)
             {
                 FlowGraphNode[] ns = iterateStack.ToArray();
                 iterateStack.Clear();
                 for (int i = ns.Length - 1; i >= 0; i--)
                 {
                     if (ns[i] != n1)
                     {
                         iterateStack.Push(ns[i]);
                     }
                 }
             }
         }
     }
 }