// internal stuff private Digraph GetIlSourceAsDot(MethodDefinition method) { Digraph dot = new Digraph(); dot.Name = "IL"; dot.Label = method.ToString(); dot.LabelLoc = "t"; dot.FontName = "tahoma"; dot.FontSize = 10; if (method.Body != null) { List <IlInstruction> instructions = new List <IlInstruction> (); foreach (Instruction instr in method.Body.Instructions) { IlInstruction i = new IlInstruction(instr); i.Name = instr.OpCode.Name; switch (instr.OpCode.OperandType) { case OperandType.InlineNone: break; case OperandType.InlineSwitch: int[] brchs = instr.Operand as int[]; i.Calls = new List <string> (brchs.Length); for (int j = 0; j < brchs.Length; j++) { string switchtarget = String.Format("IL_{0}", brchs[j].ToString("X4")); i.Name += String.Format("\t{0}{1}", (j > 0) ? ", " : String.Empty, switchtarget); i.Calls.Add(switchtarget); } break; case OperandType.ShortInlineBrTarget: case OperandType.InlineBrTarget: Instruction ins = (instr.Operand as Instruction); string target = String.Format("IL_{0}", ins.Offset.ToString("X4")); i.Name = String.Format("{0} {1}", i.Name, target); i.Calls = new List <string> (1); i.Calls.Add(target); break; case OperandType.InlineString: i.Name = String.Format("{0} '{1}'", i.Name, instr.Operand); break; default: i.Name = String.Format("{0} {1}", i.Name, instr.Operand); break; } // add instruction instructions.Add(i); } // build dot for each instructions // first add the nodes foreach (IlInstruction i in instructions) { Node n = i.GetNode(true); dot.Nodes.Add(n); } // then add the edges for (int j = 0; j < instructions.Count; j++) { IlInstruction i = instructions[j]; Node n = i.GetNode(false); if (i.Calls != null) { foreach (string callee in i.Calls) { IlInstruction target = FindCallee(callee, instructions); Node t = target.GetNode(false); Edge e = new Edge(n, t); string label = target.Label; if (label.Length > 0) { e.Attributes["label"] = label; } dot.Edges.Add(e); } } // by default execution continues to the next instruction // unless - we have an unconditional branch or it's the last instruction if ((j < instructions.Count - 1) && !i.IsUnconditionalBranch()) { IlInstruction next = (IlInstruction)instructions[j + 1]; Edge e = new Edge(n, next.GetNode(false)); string label = next.Label; if (label.Length > 0) { e.Attributes["label"] = label; } dot.Edges.Add(e); } } } return(dot); }
// internal stuff private Digraph GetIlSourceAsDot (MethodDefinition method) { Digraph dot = new Digraph (); dot.Name = "IL"; dot.Label = method.ToString (); dot.LabelLoc = "t"; dot.FontName = "tahoma"; dot.FontSize = 10; if (method.Body != null) { List<IlInstruction> instructions = new List<IlInstruction> (); foreach (Instruction instr in method.Body.Instructions) { IlInstruction i = new IlInstruction (instr); i.Name = instr.OpCode.Name; switch (instr.OpCode.OperandType) { case OperandType.InlineNone: break; case OperandType.InlineSwitch: int[] brchs = instr.Operand as int[]; i.Calls = new List<string> (brchs.Length); for (int j = 0; j < brchs.Length; j++) { string switchtarget = String.Format ("IL_{0}", brchs[j].ToString ("X4")); i.Name += String.Format ("\t{0}{1}", (j > 0) ? ", " : String.Empty, switchtarget); i.Calls.Add (switchtarget); } break; case OperandType.ShortInlineBrTarget: case OperandType.InlineBrTarget: Instruction ins = (instr.Operand as Instruction); string target = String.Format ("IL_{0}", ins.Offset.ToString ("X4")); i.Name = String.Format ("{0} {1}", i.Name, target); i.Calls = new List<string> (1); i.Calls.Add (target); break; case OperandType.InlineString: i.Name = String.Format ("{0} '{1}'", i.Name, instr.Operand); break; default: i.Name = String.Format ("{0} {1}", i.Name, instr.Operand); break; } // add instruction instructions.Add (i); } // build dot for each instructions // first add the nodes foreach (IlInstruction i in instructions) { Node n = i.GetNode (true); dot.Nodes.Add (n); } // then add the edges for (int j = 0; j < instructions.Count; j++) { IlInstruction i = instructions[j]; Node n = i.GetNode (false); if (i.Calls != null) { foreach (string callee in i.Calls) { IlInstruction target = FindCallee (callee, instructions); Node t = target.GetNode (false); Edge e = new Edge (n, t); string label = target.Label; if (label.Length > 0) e.Attributes["label"] = label; dot.Edges.Add (e); } } // by default execution continues to the next instruction // unless - we have an unconditional branch or it's the last instruction if ((j < instructions.Count - 1) && !i.IsUnconditionalBranch ()) { IlInstruction next = (IlInstruction)instructions[j + 1]; Edge e = new Edge (n, next.GetNode (false)); string label = next.Label; if (label.Length > 0) e.Attributes["label"] = label; dot.Edges.Add (e); } } } return dot; }