Exemple #1
0
        public ILStructure(CilBody body)
            : this(ILStructureType.Root, 0, body.GetCodeSize())
        {
            // Build the tree of exception structures:
            for (int i = 0; i < body.ExceptionHandlers.Count; i++)
            {
                ExceptionHandler eh = body.ExceptionHandlers[i];
                if (!body.ExceptionHandlers.Take(i).Any(oldEh => oldEh.TryStart == eh.TryStart && oldEh.TryEnd == eh.TryEnd))
                {
                    AddNestedStructure(new ILStructure(ILStructureType.Try, (int)eh.TryStart.Offset, (int)eh.TryEnd.Offset, eh));
                }
                if (eh.HandlerType == ExceptionHandlerType.Filter)
                {
                    AddNestedStructure(new ILStructure(ILStructureType.Filter, (int)eh.FilterStart.Offset, (int)eh.HandlerStart.Offset, eh));
                }
                AddNestedStructure(new ILStructure(ILStructureType.Handler, (int)eh.HandlerStart.Offset, eh.HandlerEnd == null ? body.GetCodeSize() : (int)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 = (int)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 = body.GetPrevious(allBranches[i].Value);
                    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();
        }