public ILStructure(MethodBody body) : this(ILStructureType.Root, 0, body.CodeSize) { // Build the tree of exception structures: foreach (ExceptionHandler eh in body.ExceptionHandlers) { AddNestedStructure(new ILStructure(ILStructureType.Try, eh.TryStart.Offset, eh.TryEnd.Offset, eh)); if (eh.HandlerType == ExceptionHandlerType.Filter) { AddNestedStructure(new ILStructure(ILStructureType.Filter, eh.FilterStart.Offset, eh.HandlerStart.Offset, eh)); } AddNestedStructure(new ILStructure(ILStructureType.Handler, eh.HandlerStart.Offset, eh.HandlerEnd == null ? body.CodeSize : eh.HandlerEnd.Offset, eh)); } // Very simple loop detection: look for backward branches List <KeyValuePair <Instruction, Instruction> > allBranches = FindAllBranches(body); // We go through the branches in reverse so that we find the biggest possible loop boundary first (think loops with "continue;") for (int i = allBranches.Count - 1; i >= 0; i--) { int loopEnd = allBranches[i].Key.GetEndOffset(); int loopStart = allBranches[i].Value.Offset; if (loopStart < loopEnd) { // We found a backward branch. This is a potential loop. // Check that is has only one entry point: Instruction entryPoint = null; // entry point is first instruction in loop if prev inst isn't an unconditional branch Instruction prev = allBranches[i].Value.Previous; if (prev != null && !OpCodeInfo.IsUnconditionalBranch(prev.OpCode)) { entryPoint = allBranches[i].Value; } bool multipleEntryPoints = false; foreach (var pair in allBranches) { if (pair.Key.Offset < loopStart || pair.Key.Offset >= loopEnd) { if (loopStart <= pair.Value.Offset && pair.Value.Offset < loopEnd) { // jump from outside the loop into the loop if (entryPoint == null) { entryPoint = pair.Value; } else if (pair.Value != entryPoint) { multipleEntryPoints = true; } } } } if (!multipleEntryPoints) { AddNestedStructure(new ILStructure(ILStructureType.Loop, loopStart, loopEnd, entryPoint)); } } } SortChildren(); }
public IlStructure(MethodBody body, int codesize) : this(IlStructureType.Root, 0, codesize) { // Build the tree of exception structures: for (var i = 0; i < body.ExceptionHandlers.Count; i++) { var eh = body.ExceptionHandlers[i]; if (!body.ExceptionHandlers.Take(i).Any(oldEh => oldEh.TryStart == eh.TryStart && oldEh.TryEnd == eh.TryEnd)) { AddNestedStructure(new IlStructure(IlStructureType.Try, eh.TryStart.Offset, eh.TryEnd.Offset, eh)); } if (eh.HandlerType == ExceptionHandlerType.Filter) { AddNestedStructure(new IlStructure(IlStructureType.Filter, eh.FilterStart.Offset, eh.HandlerStart.Offset, eh)); } AddNestedStructure(new IlStructure(IlStructureType.Handler, eh.HandlerStart.Offset, eh.HandlerEnd?.Offset ?? codesize, eh)); } // Very simple loop detection: look for backward branches var allBranches = FindAllBranches(body); // We go through the branches in reverse so that we find the biggest possible loop boundary first (think loops with "continue;") for (var i = allBranches.Count - 1; i >= 0; i--) { var loopEnd = allBranches[i].Key.Offset + allBranches[i].Key.GetSize(); var loopStart = allBranches[i].Value.Offset; if (loopStart >= loopEnd) { continue; } // We found a backward branch. This is a potential loop. // Check that is has only one entry point: Instruction entryPoint = null; // entry point is first instruction in loop if prev inst isn't an unconditional branch var prev = allBranches[i].Value.Previous; if (prev != null && !OpCodeInfo.IsUnconditionalBranch(prev.OpCode)) { entryPoint = allBranches[i].Value; } var multipleEntryPoints = false; foreach (var pair in allBranches) { if (pair.Key.Offset >= loopStart && pair.Key.Offset < loopEnd) { continue; } if (loopStart > pair.Value.Offset || pair.Value.Offset >= loopEnd) { continue; } // jump from outside the loop into the loop if (entryPoint == null) { entryPoint = pair.Value; } else if (pair.Value != entryPoint) { multipleEntryPoints = true; } } if (!multipleEntryPoints) { AddNestedStructure(new IlStructure(IlStructureType.Loop, loopStart, loopEnd, entryPoint)); } } SortChildren(); }