Beispiel #1
0
        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();
            }
        }
Beispiel #2
0
        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();
        }
Beispiel #3
0
        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);
        }
Beispiel #4
0
        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 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 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 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();
		}