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