private void WriteStructureFooter(ILStructure s) { _output.Unindent(); switch (s.Type) { case ILStructureType.Loop: _output.WriteLine("// end loop"); break; case ILStructureType.Try: _output.WriteLine("} // end .try"); break; case ILStructureType.Handler: _output.WriteLine("} // end handler"); break; case ILStructureType.Filter: _output.WriteLine("} // end filter"); break; default: throw new NotSupportedException(); } }
private void WriteStructureHeader(ILStructure s) { switch (s.Type) { case ILStructureType.Loop: _output.Write("// loop start"); if (s.LoopEntryPoint != null) { _output.Write(" (head: "); DisassemblerHelpers.WriteOffsetReference(_output, s.LoopEntryPoint); _output.Write(')'); } _output.WriteLine(); break; case ILStructureType.Try: _output.WriteLine(".try"); _output.WriteLine("{"); break; case ILStructureType.Handler: switch (s.ExceptionHandler?.HandlerType) { case ExceptionHandlerType.Catch: case ExceptionHandlerType.Filter: _output.Write("catch"); if (s.ExceptionHandler?.CatchType != null) { _output.Write(' '); s.ExceptionHandler.CatchType.WriteTo(_output, ILNameSyntax.TypeName); } _output.WriteLine(); break; case ExceptionHandlerType.Finally: _output.WriteLine("finally"); break; case ExceptionHandlerType.Fault: _output.WriteLine("fault"); break; default: throw new NotSupportedException(); } _output.WriteLine("{"); break; case ILStructureType.Filter: _output.WriteLine("filter"); _output.WriteLine("{"); break; default: throw new NotSupportedException(); } _output.Indent(); }
bool AddNestedStructure(ILStructure newStructure) { // special case: don't consider the loop-like structure of "continue;" statements to be nested loops if (Type == ILStructureType.Loop && newStructure.Type == ILStructureType.Loop && newStructure.StartOffset == StartOffset) { return(false); } // use <= for end-offset comparisons because both end and EndOffset are exclusive Debug.Assert(StartOffset <= newStructure.StartOffset && newStructure.EndOffset <= EndOffset); foreach (var child in Children) { if (child.StartOffset <= newStructure.StartOffset && newStructure.EndOffset <= child.EndOffset) { return(child.AddNestedStructure(newStructure)); } if (!(child.EndOffset <= newStructure.StartOffset || newStructure.EndOffset <= child.StartOffset)) { // child and newStructure overlap if (!(newStructure.StartOffset <= child.StartOffset && child.EndOffset <= newStructure.EndOffset)) { // Invalid nesting, can't build a tree. -> Don't add the new structure. return(false); } } } // Move existing structures into the new structure: for (var i = 0; i < Children.Count; i++) { var child = Children[i]; if (newStructure.StartOffset <= child.StartOffset && child.EndOffset <= newStructure.EndOffset) { Children.RemoveAt(i--); newStructure.Children.Add(child); } } // Add the structure here: Children.Add(newStructure); return(true); }
private void WriteStructureBody(ILStructure s, HashSet <int> branchTargets, ref Instruction inst) { var isFirstInstructionInStructure = true; var prevInstructionWasBranch = false; var childIndex = 0; while (inst != null && inst.Offset < s.EndOffset) { var offset = inst.Offset; if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset) { var child = s.Children[childIndex++]; WriteStructureHeader(child); WriteStructureBody(child, branchTargets, ref inst); WriteStructureFooter(child); } else { if (!isFirstInstructionInStructure && (prevInstructionWasBranch || branchTargets.Contains(offset))) { _output.WriteLine(); // put an empty line after branches, and in front of branch targets } inst.WriteTo(_output); _output.WriteLine(); prevInstructionWasBranch = inst.OpCode.FlowControl == FlowControl.Branch || inst.OpCode.FlowControl == FlowControl.Cond_Branch || inst.OpCode.FlowControl == FlowControl.Return || inst.OpCode.FlowControl == FlowControl.Throw; inst = inst.Next; } isFirstInstructionInStructure = false; } }