Ejemplo n.º 1
0
        // 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;
		}