Beispiel #1
0
        private static uint BuildPointsForBranch(List <BranchPoint> list, Instruction then, int branchingInstructionLine, string document,
                                                 int branchOffset, uint ordinal, int pathCounter, BranchPoint path0, List <Instruction> instructions, MethodDefinition methodDefinition)
        {
            var pathOffsetList1 = GetBranchPath(@then);

            // Add path 1
            var path1 = new BranchPoint
            {
                StartLine    = branchingInstructionLine,
                Document     = document,
                Offset       = branchOffset,
                Ordinal      = ordinal++,
                Path         = pathCounter,
                OffsetPoints =
                    pathOffsetList1.Count > 1
                        ? pathOffsetList1.GetRange(0, pathOffsetList1.Count - 1)
                        : new List <int>(),
                EndOffset = pathOffsetList1.Last()
            };

            // only add branch if branch does not match a known sequence
            // e.g. auto generated field assignment
            // or encapsulates at least one sequence point
            var offsets = new[]
            {
                path0.Offset,
                path0.EndOffset,
                path1.Offset,
                path1.EndOffset
            };

            var ignoreSequences = new[]
            {
                // we may need other samples
                new[] { Code.Brtrue_S, Code.Pop, Code.Ldsfld, Code.Ldftn, Code.Newobj, Code.Dup, Code.Stsfld, Code.Newobj }, // CachedAnonymousMethodDelegate field allocation
            };

            var bs = offsets.Min();
            var be = offsets.Max();

            var range = instructions.Where(i => (i.Offset >= bs) && (i.Offset <= be)).ToList();

            var match = ignoreSequences
                        .Where(ignoreSequence => range.Count >= ignoreSequence.Length)
                        .Any(ignoreSequence => range.Zip(ignoreSequence, (instruction, code) => instruction.OpCode.Code == code).All(x => x));

            var count = range
                        .Count(i => methodDefinition.DebugInformation.GetSequencePoint(i) != null);

            if (!match || count > 0)
            {
                list.Add(path0);
                list.Add(path1);
            }
            return(ordinal);
        }
Beispiel #2
0
        private static bool BuildPointsForConditionalBranch(List <BranchPoint> list, Instruction instruction,
                                                            int branchingInstructionLine, string document, int branchOffset, int pathCounter,
                                                            List <Instruction> instructions, ref uint ordinal, MethodDefinition methodDefinition)
        {
            // Add Default branch (Path=0)

            // Follow else/default instruction
            var @else = instruction.Next;

            var pathOffsetList = GetBranchPath(@else);

            // add Path 0
            var path0 = new BranchPoint
            {
                StartLine    = branchingInstructionLine,
                Document     = document,
                Offset       = branchOffset,
                Ordinal      = ordinal++,
                Path         = pathCounter++,
                OffsetPoints =
                    pathOffsetList.Count > 1
                        ? pathOffsetList.GetRange(0, pathOffsetList.Count - 1)
                        : new List <int>(),
                EndOffset = pathOffsetList.Last()
            };

            // Add Conditional Branch (Path=1)
            if (instruction.OpCode.Code != Code.Switch)
            {
                // Follow instruction at operand
                var @then = instruction.Operand as Instruction;
                if (@then == null)
                {
                    return(false);
                }

                ordinal = BuildPointsForBranch(list, then, branchingInstructionLine, document, branchOffset,
                                               ordinal, pathCounter, path0, instructions, methodDefinition);
            }
            else // instruction.OpCode.Code == Code.Switch
            {
                var branchInstructions = instruction.Operand as Instruction[];
                if (branchInstructions == null || branchInstructions.Length == 0)
                {
                    return(false);
                }

                ordinal = BuildPointsForSwitchCases(list, path0, branchInstructions, branchingInstructionLine,
                                                    document, branchOffset, ordinal, ref pathCounter);
            }
            return(true);
        }
Beispiel #3
0
        private static uint BuildPointsForSwitchCases(List <BranchPoint> list, BranchPoint path0, Instruction[] branchInstructions,
                                                      int branchingInstructionLine, string document, int branchOffset, uint ordinal, ref int pathCounter)
        {
            var counter = pathCounter;

            list.Add(path0);
            // Add Conditional Branches (Path>0)
            list.AddRange(branchInstructions.Select(GetBranchPath)
                          .Select(pathOffsetList1 => new BranchPoint
            {
                StartLine    = branchingInstructionLine,
                Document     = document,
                Offset       = branchOffset,
                Ordinal      = ordinal++,
                Path         = counter++,
                OffsetPoints =
                    pathOffsetList1.Count > 1
                            ? pathOffsetList1.GetRange(0, pathOffsetList1.Count - 1)
                            : new List <int>(),
                EndOffset = pathOffsetList1.Last()
            }));
            pathCounter = counter;
            return(ordinal);
        }