Beispiel #1
0
        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();
            }
        }
Beispiel #2
0
        void WriteStructureFooter(ILStructure s)
        {
            output.Unindent();
            switch (s.Type)
            {
            case ILStructureType.Loop:
                output.WriteLine("// end loop", TextTokenType.Comment);
                break;

            case ILStructureType.Try:
                output.WriteRightBrace();
                output.WriteSpace();
                output.WriteLine("// end .try", TextTokenType.Comment);
                break;

            case ILStructureType.Handler:
                output.WriteRightBrace();
                output.WriteSpace();
                output.WriteLine("// end handler", TextTokenType.Comment);
                break;

            case ILStructureType.Filter:
                output.WriteRightBrace();
                output.WriteSpace();
                output.WriteLine("// end filter", TextTokenType.Comment);
                break;

            default:
                throw new NotSupportedException();
            }
        }
        void WriteStructureBody(ILStructure s, HashSet <int> branchTargets, ref BlobReader body)
        {
            bool isFirstInstructionInStructure = true;
            bool prevInstructionWasBranch      = false;
            int  childIndex = 0;

            while (body.RemainingBytes > 0 && body.Offset < s.EndOffset)
            {
                int offset = body.Offset;
                if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset)
                {
                    ILStructure child = s.Children[childIndex++];
                    WriteStructureHeader(child);
                    WriteStructureBody(child, branchTargets, ref body);
                    WriteStructureFooter(child);
                }
                else
                {
                    if (!isFirstInstructionInStructure && (prevInstructionWasBranch || branchTargets.Contains(offset)))
                    {
                        output.WriteLine();                         // put an empty line after branches, and in front of branch targets
                    }
                    var currentOpCode = ILParser.DecodeOpCode(ref body);
                    body.Offset = offset;                     // reset IL stream
                    WriteInstruction(output, metadata, s.MethodHandle, ref body);
                    prevInstructionWasBranch = currentOpCode.IsBranch() ||
                                               currentOpCode.IsReturn() ||
                                               currentOpCode == ILOpCode.Throw ||
                                               currentOpCode == ILOpCode.Rethrow ||
                                               currentOpCode == ILOpCode.Switch;
                }
                isFirstInstructionInStructure = false;
            }
        }
        void WriteStructureBody(ILStructure s, HashSet <int> branchTargets, ref Instruction inst, int codeSize)
        {
            bool isFirstInstructionInStructure = true;
            bool prevInstructionWasBranch      = false;
            int  childIndex = 0;

            while (inst != null && inst.Offset < s.EndOffset)
            {
                int offset = inst.Offset;
                if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset)
                {
                    ILStructure child = s.Children[childIndex++];
                    WriteStructureHeader(child);
                    WriteStructureBody(child, branchTargets, ref inst, codeSize);
                    WriteStructureFooter(child);
                }
                else
                {
                    if (!isFirstInstructionInStructure && (prevInstructionWasBranch || branchTargets.Contains(offset)))
                    {
                        output.WriteLine();                             // put an empty line after branches, and in front of branch targets
                    }
                    WriteInstruction(output, inst);
                    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;
            }
        }
Beispiel #5
0
        void WriteStructureHeader(ILStructure s)
        {
            switch (s.Type)
            {
            case ILStructureType.Loop:
                output.Write("// loop start", TextTokenType.Comment);
                if (s.LoopEntryPoint != null)
                {
                    output.Write(" (head: ", TextTokenType.Comment);
                    DisassemblerHelpers.WriteOffsetReference(output, s.LoopEntryPoint, null, TextTokenType.Comment);
                    output.Write(')', TextTokenType.Comment);
                }
                output.WriteLine();
                break;

            case ILStructureType.Try:
                output.WriteLine(".try", TextTokenType.ILDirective);
                output.WriteLineLeftBrace();
                break;

            case ILStructureType.Handler:
                switch (s.ExceptionHandler.HandlerType)
                {
                case ExceptionHandlerType.Catch:
                case ExceptionHandlerType.Filter:
                    output.Write("catch", TextTokenType.Keyword);
                    if (s.ExceptionHandler.CatchType != null)
                    {
                        output.WriteSpace();
                        s.ExceptionHandler.CatchType.WriteTo(output, ILNameSyntax.TypeName);
                    }
                    output.WriteLine();
                    break;

                case ExceptionHandlerType.Finally:
                    output.WriteLine("finally", TextTokenType.Keyword);
                    break;

                case ExceptionHandlerType.Fault:
                    output.WriteLine("fault", TextTokenType.Keyword);
                    break;

                default:
                    output.WriteLine(s.ExceptionHandler.HandlerType.ToString(), TextTokenType.Keyword);
                    break;
                }
                output.WriteLineLeftBrace();
                break;

            case ILStructureType.Filter:
                output.WriteLine("filter", TextTokenType.Keyword);
                output.WriteLineLeftBrace();
                break;

            default:
                throw new NotSupportedException();
            }
            output.Indent();
        }
        void WriteStructureHeader(ILStructure s)
        {
            switch (s.Type)
            {
            case ILStructureType.Loop:
                output.Write("// loop start");
                if (s.LoopEntryPointOffset >= 0)
                {
                    output.Write(" (head: ");
                    DisassemblerHelpers.WriteOffsetReference(output, s.LoopEntryPointOffset);
                    output.Write(')');
                }
                output.WriteLine();
                break;

            case ILStructureType.Try:
                output.WriteLine(".try");
                output.WriteLine("{");
                break;

            case ILStructureType.Handler:
                switch (s.ExceptionHandler.Kind)
                {
                case ExceptionRegionKind.Catch:
                case ExceptionRegionKind.Filter:
                    output.Write("catch");
                    if (!s.ExceptionHandler.CatchType.IsNil)
                    {
                        output.Write(' ');
                        s.ExceptionHandler.CatchType.WriteTo(s.Module, output, s.GenericContext, ILNameSyntax.TypeName);
                    }
                    output.WriteLine();
                    break;

                case ExceptionRegionKind.Finally:
                    output.WriteLine("finally");
                    break;

                case ExceptionRegionKind.Fault:
                    output.WriteLine("fault");
                    break;

                default:
                    throw new ArgumentOutOfRangeException();
                }
                output.WriteLine("{");
                break;

            case ILStructureType.Filter:
                output.WriteLine("filter");
                output.WriteLine("{");
                break;

            default:
                throw new ArgumentOutOfRangeException();
            }
            output.Indent();
        }
Beispiel #7
0
        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 Mono.Cecil.Cil.ExceptionHandlerType.Catch:
                case Mono.Cecil.Cil.ExceptionHandlerType.Filter:
                    output.Write("catch");
                    if (s.ExceptionHandler.CatchType != null)
                    {
                        output.Write(' ');
                        s.ExceptionHandler.CatchType.WriteTo(output, ILNameSyntax.TypeName);
                    }
                    output.WriteLine();
                    break;

                case Mono.Cecil.Cil.ExceptionHandlerType.Finally:
                    output.WriteLine("finally");
                    break;

                case Mono.Cecil.Cil.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();
        }
Beispiel #8
0
        void WriteStructureBody(CilBody body, ILStructure s, HashSet <uint> branchTargets, ref int index, MemberMapping debugSymbols, int codeSize, uint baseRva, long baseOffs, IInstructionBytesReader byteReader, MethodDef method)
        {
            bool isFirstInstructionInStructure = true;
            bool prevInstructionWasBranch      = false;
            int  childIndex   = 0;
            var  instructions = body.Instructions;

            while (index < instructions.Count)
            {
                Instruction inst = instructions[index];
                if (inst.Offset >= s.EndOffset)
                {
                    break;
                }
                uint offset = inst.Offset;
                if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset)
                {
                    ILStructure child = s.Children[childIndex++];
                    WriteStructureHeader(child);
                    WriteStructureBody(body, child, branchTargets, ref index, debugSymbols, codeSize, baseRva, baseOffs, byteReader, method);
                    WriteStructureFooter(child);
                }
                else
                {
                    if (!isFirstInstructionInStructure && (prevInstructionWasBranch || branchTargets.Contains(offset)))
                    {
                        output.WriteLine();                         // put an empty line after branches, and in front of branch targets
                    }
                    var startLocation = output.Location;
                    inst.WriteTo(output, options, baseRva, baseOffs, byteReader, method);

                    // add IL code mappings - used in debugger
                    if (debugSymbols != null)
                    {
                        var next = index + 1 < instructions.Count ? instructions[index + 1] : null;
                        debugSymbols.MemberCodeMappings.Add(
                            new SourceCodeMapping()
                        {
                            StartLocation       = startLocation,
                            EndLocation         = output.Location,
                            ILInstructionOffset = new ILRange(inst.Offset, next == null ? (uint)codeSize : next.Offset),
                            MemberMapping       = debugSymbols
                        });
                    }

                    output.WriteLine();

                    prevInstructionWasBranch = inst.OpCode.FlowControl == FlowControl.Branch ||
                                               inst.OpCode.FlowControl == FlowControl.Cond_Branch ||
                                               inst.OpCode.FlowControl == FlowControl.Return ||
                                               inst.OpCode.FlowControl == FlowControl.Throw;

                    index++;
                }
                isFirstInstructionInStructure = false;
            }
        }
Beispiel #9
0
        void WriteStructureBody(MethodDef method, CilBody body, ILStructure s, HashSet <uint> branchTargets, ref int index, MemberMapping currentMethodMapping, int codeSize)
        {
            bool isFirstInstructionInStructure = true;
            bool prevInstructionWasBranch      = false;
            int  childIndex = 0;

            while (index < body.Instructions.Count)
            {
                Instruction inst   = body.Instructions[index];
                uint        offset = inst.Offset;
                if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset)
                {
                    ILStructure child = s.Children[childIndex++];
                    WriteStructureHeader(child);
                    WriteStructureBody(method, body, child, branchTargets, ref index, currentMethodMapping, codeSize);
                    WriteStructureFooter(child);
                }
                else
                {
                    if (!isFirstInstructionInStructure && (prevInstructionWasBranch || branchTargets.Contains(offset)))
                    {
                        output.WriteLine();                         // put an empty line after branches, and in front of branch targets
                    }
                    var startLocation = output.Location;
                    inst.WriteTo(method, output);

                    // add IL code mappings - used in debugger
                    if (currentMethodMapping != null)
                    {
                        var next = body.GetNext(inst);
                        currentMethodMapping.MemberCodeMappings.Add(
                            new SourceCodeMapping()
                        {
                            StartLocation       = startLocation,
                            EndLocation         = output.Location,
                            ILInstructionOffset = new ILRange {
                                From = inst.Offset, To = next == null ? (uint)codeSize : next.Offset
                            },
                            MemberMapping = currentMethodMapping
                        });
                    }

                    output.WriteLine();

                    prevInstructionWasBranch = inst.OpCode.FlowControl == FlowControl.Branch ||
                                               inst.OpCode.FlowControl == FlowControl.Cond_Branch ||
                                               inst.OpCode.FlowControl == FlowControl.Return ||
                                               inst.OpCode.FlowControl == FlowControl.Throw;

                    index++;
                }
                isFirstInstructionInStructure = false;
            }
        }
Beispiel #10
0
        void WriteStructureBody(ILStructure s, HashSet <int> branchTargets, ref Instruction inst, MemberMapping currentMethodMapping, int codeSize)
        {
            bool isFirstInstructionInStructure = true;
            bool prevInstructionWasBranch      = false;
            int  childIndex = 0;

            while (inst != null && inst.Offset < s.EndOffset)
            {
                int offset = inst.Offset;
                if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset)
                {
                    ILStructure child = s.Children[childIndex++];
                    WriteStructureHeader(child);
                    WriteStructureBody(child, branchTargets, ref inst, currentMethodMapping, codeSize);
                    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);

                    // add IL code mappings - used in debugger
                    if (currentMethodMapping != null)
                    {
                        currentMethodMapping.MemberCodeMappings.Add(
                            new SourceCodeMapping()
                        {
                            SourceCodeLine      = output.CurrentLine,
                            ILInstructionOffset = new ILRange {
                                From = inst.Offset, To = inst.Next == null ? codeSize : inst.Next.Offset
                            },
                            MemberMapping = currentMethodMapping
                        });
                    }

                    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;
            }
        }
Beispiel #11
0
        private void WriteStructureBody(ILStructure s, HashSet <int> branchTargets, ref Instruction inst, MethodDebugSymbols debugSymbols, int codeSize)
        {
            bool isFirstInstructionInStructure = true;
            bool prevInstructionWasBranch      = false;
            int  childIndex = 0;

            while (inst != null && inst.Offset < s.EndOffset)
            {
                int offset = inst.Offset;
                if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset)
                {
                    ILStructure child = s.Children[childIndex++];
                    WriteStructureHeader(child);
                    WriteStructureBody(child, branchTargets, ref inst, debugSymbols, codeSize);
                    WriteStructureFooter(child);
                }
                else
                {
                    if (!isFirstInstructionInStructure && (prevInstructionWasBranch || branchTargets.Contains(offset)))
                    {
                        output.WriteLine();                         // put an empty line after branches, and in front of branch targets
                    }
                    var startLocation = output.Location;
                    inst.WriteTo(output);

                    // add IL code mappings - used in debugger
                    if (debugSymbols != null)
                    {
                        debugSymbols.SequencePoints.Add(
                            new SequencePoint()
                        {
                            StartLocation = startLocation,
                            EndLocation   = output.Location,
                            ILRanges      = new ILRange[] { new ILRange(inst.Offset, inst.Next == null ? codeSize : inst.Next.Offset) }
                        });
                    }

                    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;
            }
        }
        bool AddNestedStructure(ILStructure newStructure)
        {
            // special case: don't consider the loop-like structure of "continue;" statements to be nested loops
            if (this.Type == ILStructureType.Loop && newStructure.Type == ILStructureType.Loop && newStructure.StartOffset == this.StartOffset)
            {
                return(false);
            }

            // use <= for end-offset comparisons because both end and EndOffset are exclusive
            Debug.Assert(StartOffset <= newStructure.StartOffset && newStructure.EndOffset <= EndOffset);
            foreach (ILStructure child in this.Children)
            {
                if (child.StartOffset <= newStructure.StartOffset && newStructure.EndOffset <= child.EndOffset)
                {
                    return(child.AddNestedStructure(newStructure));
                }
                else 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 (int i = 0; i < this.Children.Count; i++)
            {
                ILStructure child = this.Children[i];
                if (newStructure.StartOffset <= child.StartOffset && child.EndOffset <= newStructure.EndOffset)
                {
                    this.Children.RemoveAt(i--);
                    newStructure.Children.Add(child);
                }
            }
            // Add the structure here:
            this.Children.Add(newStructure);
            return(true);
        }
        void WriteStructureBody(ILStructure s, ref Instruction inst)
        {
            int childIndex = 0;

            while (inst != null && inst.Offset < s.EndOffset)
            {
                int offset = inst.Offset;
                if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset)
                {
                    ILStructure child = s.Children[childIndex++];
                    WriteStructureHeader(child);
                    WriteStructureBody(child, ref inst);
                    WriteStructureFooter(child);
                }
                else
                {
                    inst.WriteTo(output);
                    output.WriteLine();
                    inst = inst.Next;
                }
            }
        }
        void WriteStructureBody(ILStructure s, ref Instruction inst, MemberMapping currentMethodMapping, int codeSize)
        {
            int childIndex = 0;

            while (inst != null && inst.Offset < s.EndOffset)
            {
                int offset = inst.Offset;
                if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset)
                {
                    ILStructure child = s.Children[childIndex++];
                    WriteStructureHeader(child);
                    WriteStructureBody(child, ref inst, currentMethodMapping, codeSize);
                    WriteStructureFooter(child);
                }
                else
                {
                    inst.WriteTo(output);

                    // add IL code mappings - used in debugger
                    if (currentMethodMapping != null)
                    {
                        currentMethodMapping.MemberCodeMappings.Add(
                            new SourceCodeMapping()
                        {
                            SourceCodeLine      = output.CurrentLine,
                            ILInstructionOffset = new ILRange {
                                From = inst.Offset, To = inst.Next == null ? codeSize : inst.Next.Offset
                            },
                            MemberMapping = currentMethodMapping
                        });
                    }

                    output.WriteLine();
                    inst = inst.Next;
                }
            }
        }
		void WriteStructureBody(ILStructure s, ref Instruction inst, MemberMapping currentMethodMapping, int codeSize)
		{
			int childIndex = 0;
			while (inst != null && inst.Offset < s.EndOffset) {
				int offset = inst.Offset;
				if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset) {
					ILStructure child = s.Children[childIndex++];
					WriteStructureHeader(child);
					WriteStructureBody(child, ref inst, currentMethodMapping, codeSize);
					WriteStructureFooter(child);
				} else {
					inst.WriteTo(output);
					
					// add IL code mappings - used in debugger
					if (currentMethodMapping != null) {
						currentMethodMapping.MemberCodeMappings.Add(
							new SourceCodeMapping() {
								SourceCodeLine = output.CurrentLine,
								ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? codeSize : inst.Next.Offset },
								MemberMapping = currentMethodMapping
							});
					}
					
					output.WriteLine();
					inst = inst.Next;
				}
			}
		}
		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();
			}
		}
 void WriteStructureFooter(ILStructure s)
 {
     output.Unindent();
     switch (s.Type) {
         case ILStructureType.Loop:
             output.WriteLine("// end loop", TextTokenType.Comment);
             break;
         case ILStructureType.Try:
             output.WriteRightBrace();
             output.WriteSpace();
             output.WriteLine("// end .try", TextTokenType.Comment);
             break;
         case ILStructureType.Handler:
             output.WriteRightBrace();
             output.WriteSpace();
             output.WriteLine("// end handler", TextTokenType.Comment);
             break;
         case ILStructureType.Filter:
             output.WriteRightBrace();
             output.WriteSpace();
             output.WriteLine("// end filter", TextTokenType.Comment);
             break;
         default:
             throw new NotSupportedException();
     }
 }
        void WriteStructureBody(CilBody body, ILStructure s, HashSet<uint> branchTargets, ref int index, MemberMapping debugSymbols, int codeSize, uint baseRva, long baseOffs, IInstructionBytesReader byteReader, MethodDef method)
        {
            bool isFirstInstructionInStructure = true;
            bool prevInstructionWasBranch = false;
            int childIndex = 0;
            var instructions = body.Instructions;
            while (index < instructions.Count) {
                Instruction inst = instructions[index];
                if (inst.Offset >= s.EndOffset)
                    break;
                uint offset = inst.Offset;
                if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset) {
                    ILStructure child = s.Children[childIndex++];
                    WriteStructureHeader(child);
                    WriteStructureBody(body, child, branchTargets, ref index, debugSymbols, codeSize, baseRva, baseOffs, byteReader, method);
                    WriteStructureFooter(child);
                } else {
                    if (!isFirstInstructionInStructure && (prevInstructionWasBranch || branchTargets.Contains(offset))) {
                        output.WriteLine(); // put an empty line after branches, and in front of branch targets
                    }
                    var startLocation = output.Location;
                    inst.WriteTo(output, options, baseRva, baseOffs, byteReader, method);

                    // add IL code mappings - used in debugger
                    if (debugSymbols != null) {
                        var next = index + 1 < instructions.Count ? instructions[index + 1] : null;
                        debugSymbols.MemberCodeMappings.Add(
                            new SourceCodeMapping() {
                                StartLocation = startLocation,
                                EndLocation = output.Location,
                                ILInstructionOffset = new ILRange(inst.Offset, next == null ? (uint)codeSize : next.Offset),
                                MemberMapping = debugSymbols
                            });
                    }

                    output.WriteLine();

                    prevInstructionWasBranch = inst.OpCode.FlowControl == FlowControl.Branch
                        || inst.OpCode.FlowControl == FlowControl.Cond_Branch
                        || inst.OpCode.FlowControl == FlowControl.Return
                        || inst.OpCode.FlowControl == FlowControl.Throw;

                    index++;
                }
                isFirstInstructionInStructure = false;
            }
        }
 void WriteStructureHeader(ILStructure s)
 {
     switch (s.Type) {
         case ILStructureType.Loop:
             output.Write("// loop start", TextTokenType.Comment);
             if (s.LoopEntryPoint != null) {
                 output.Write(" (head: ", TextTokenType.Comment);
                 DisassemblerHelpers.WriteOffsetReference(output, s.LoopEntryPoint, null, TextTokenType.Comment);
                 output.Write(')', TextTokenType.Comment);
             }
             output.WriteLine();
             break;
         case ILStructureType.Try:
             output.WriteLine(".try", TextTokenType.ILDirective);
             output.WriteLineLeftBrace();
             break;
         case ILStructureType.Handler:
             switch (s.ExceptionHandler.HandlerType) {
                 case ExceptionHandlerType.Catch:
                 case ExceptionHandlerType.Filter:
                     output.Write("catch", TextTokenType.Keyword);
                     if (s.ExceptionHandler.CatchType != null) {
                         output.WriteSpace();
                         s.ExceptionHandler.CatchType.WriteTo(output, ILNameSyntax.TypeName);
                     }
                     output.WriteLine();
                     break;
                 case ExceptionHandlerType.Finally:
                     output.WriteLine("finally", TextTokenType.Keyword);
                     break;
                 case ExceptionHandlerType.Fault:
                     output.WriteLine("fault", TextTokenType.Keyword);
                     break;
                 default:
                     output.WriteLine(s.ExceptionHandler.HandlerType.ToString(), TextTokenType.Keyword);
                     break;
             }
             output.WriteLineLeftBrace();
             break;
         case ILStructureType.Filter:
             output.WriteLine("filter", TextTokenType.Keyword);
             output.WriteLineLeftBrace();
             break;
         default:
             throw new NotSupportedException();
     }
     output.Indent();
 }
Beispiel #20
0
		bool AddNestedStructure(ILStructure newStructure)
		{
			// special case: don't consider the loop-like structure of "continue;" statements to be nested loops
			if (this.Type == ILStructureType.Loop && newStructure.Type == ILStructureType.Loop && newStructure.StartOffset == this.StartOffset)
				return false;
			
			// use <= for end-offset comparisons because both end and EndOffset are exclusive
			Debug.Assert(StartOffset <= newStructure.StartOffset && newStructure.EndOffset <= EndOffset);
			foreach (ILStructure child in this.Children) {
				if (child.StartOffset <= newStructure.StartOffset && newStructure.EndOffset <= child.EndOffset) {
					return child.AddNestedStructure(newStructure);
				} else 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 (int i = 0; i < this.Children.Count; i++) {
				ILStructure child = this.Children[i];
				if (newStructure.StartOffset <= child.StartOffset && child.EndOffset <= newStructure.EndOffset) {
					this.Children.RemoveAt(i--);
					newStructure.Children.Add(child);
				}
			}
			// Add the structure here:
			this.Children.Add(newStructure);
			return true;
		}
		void WriteStructureBody(ILStructure s, HashSet<int> branchTargets, ref Instruction inst, MemberMapping currentMethodMapping, int codeSize)
		{
			bool isFirstInstructionInStructure = true;
			bool prevInstructionWasBranch = false;
			int childIndex = 0;
			while (inst != null && inst.Offset < s.EndOffset) {
				int offset = inst.Offset;
				if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset) {
					ILStructure child = s.Children[childIndex++];
					WriteStructureHeader(child);
					WriteStructureBody(child, branchTargets, ref inst, currentMethodMapping, codeSize);
					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);
					
					// add IL code mappings - used in debugger
					if (currentMethodMapping != null) {
						currentMethodMapping.MemberCodeMappings.Add(
							new SourceCodeMapping() {
								SourceCodeLine = output.CurrentLine,
								ILInstructionOffset = new ILRange { From = inst.Offset, To = inst.Next == null ? codeSize : inst.Next.Offset },
								MemberMapping = currentMethodMapping
							});
					}
					
					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;
			}
		}
		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 Mono.Cecil.Cil.ExceptionHandlerType.Catch:
						case Mono.Cecil.Cil.ExceptionHandlerType.Filter:
							output.Write("catch");
							if (s.ExceptionHandler.CatchType != null) {
								output.Write(' ');
								s.ExceptionHandler.CatchType.WriteTo(output, ILNameSyntax.TypeName);
							}
							output.WriteLine();
							break;
						case Mono.Cecil.Cil.ExceptionHandlerType.Finally:
							output.WriteLine("finally");
							break;
						case Mono.Cecil.Cil.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();
		}
		void WriteStructureBody(ILStructure s, HashSet<int> branchTargets, ref Instruction inst, MethodDebugSymbols debugSymbols, int codeSize)
		{
			bool isFirstInstructionInStructure = true;
			bool prevInstructionWasBranch = false;
			int childIndex = 0;
			while (inst != null && inst.Offset < s.EndOffset) {
				int offset = inst.Offset;
				if (childIndex < s.Children.Count && s.Children[childIndex].StartOffset <= offset && offset < s.Children[childIndex].EndOffset) {
					ILStructure child = s.Children[childIndex++];
					WriteStructureHeader(child);
					WriteStructureBody(child, branchTargets, ref inst, debugSymbols, codeSize);
					WriteStructureFooter(child);
				} else {
					if (!isFirstInstructionInStructure && (prevInstructionWasBranch || branchTargets.Contains(offset))) {
						output.WriteLine(); // put an empty line after branches, and in front of branch targets
					}
					var startLocation = output.Location;
					inst.WriteTo(output);
					
					// add IL code mappings - used in debugger
					if (debugSymbols != null) {
						debugSymbols.SequencePoints.Add(
							new SequencePoint() {
								StartLocation = startLocation,
								EndLocation = output.Location,
								ILRanges = new ILRange[] { new ILRange(inst.Offset, inst.Next == null ? codeSize : inst.Next.Offset) }
							});
					}
					
					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;
			}
		}