private void WriteStructureFooter(IlStructure s) { _o.Unindent(); switch (s.Type) { case IlStructureType.Loop: _o.WriteLine("// end loop"); break; case IlStructureType.Try: _o.WriteLine("} // end .try"); break; case IlStructureType.Handler: _o.WriteLine("} // end handler"); break; case IlStructureType.Filter: _o.WriteLine("} // end filter"); break; default: throw new NotSupportedException(); } }
private void WriteStructureHeader(IlStructure s) { switch (s.Type) { case IlStructureType.Loop: _o.Write("// loop start"); if (s.LoopEntryPoint != null) { _o.Write(" (head: "); DisassemblerHelpers.WriteOffsetReference(_o, s.LoopEntryPoint); _o.Write(')'); } _o.WriteLine(); break; case IlStructureType.Try: _o.WriteLine(".try"); _o.WriteLine("{"); break; case IlStructureType.Handler: switch (s.ExceptionHandler.HandlerType) { case ExceptionHandlerType.Catch: case ExceptionHandlerType.Filter: _o.Write("catch"); if (s.ExceptionHandler.CatchType != null) { _o.Write(' '); s.ExceptionHandler.CatchType.WriteTo(_o, IlNameSyntax.TypeName); } _o.WriteLine(); break; case ExceptionHandlerType.Finally: _o.WriteLine("finally"); break; case ExceptionHandlerType.Fault: _o.WriteLine("fault"); break; default: throw new NotSupportedException(); } _o.WriteLine("{"); break; case IlStructureType.Filter: _o.WriteLine("filter"); _o.WriteLine("{"); break; default: throw new NotSupportedException(); } _o.Indent(); }
private 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) { continue; } // 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) { continue; } 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))) { _o.WriteLine(); // put an empty line after branches, and in front of branch targets } inst.WriteTo(_o); _o.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; } }
private 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) continue; // 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) continue; 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))) { _o.WriteLine(); // put an empty line after branches, and in front of branch targets } inst.WriteTo(_o); _o.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; } }