Browse Source

Add CheckInvariant() and fix Return.ComputeFlags()

pull/728/head
Daniel Grunwald 11 years ago
parent
commit
1f14dea33f
  1. 2
      ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs
  2. 4
      ICSharpCode.Decompiler/IL/Instructions.cs
  3. 2
      ICSharpCode.Decompiler/IL/Instructions.tt
  4. 8
      ICSharpCode.Decompiler/IL/Instructions/Branch.cs
  5. 22
      ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs
  6. 9
      ICSharpCode.Decompiler/IL/Instructions/Return.cs
  7. 1
      ILSpy/Languages/CSharpLanguage.cs

2
ICSharpCode.Decompiler/CSharp/CSharpDecompiler.cs

@ -138,7 +138,9 @@ namespace ICSharpCode.Decompiler.CSharp
if (methodDefinition.HasBody) { if (methodDefinition.HasBody) {
var ilReader = new ILReader(); var ilReader = new ILReader();
var function = ilReader.ReadIL(methodDefinition.Body, CancellationToken); var function = ilReader.ReadIL(methodDefinition.Body, CancellationToken);
function.CheckInvariant();
function.Body = function.Body.AcceptVisitor(new TransformingVisitor()); function.Body = function.Body.AcceptVisitor(new TransformingVisitor());
function.CheckInvariant();
var statementBuilder = new StatementBuilder(method, cecilMapper); var statementBuilder = new StatementBuilder(method, cecilMapper);
var body = statementBuilder.ConvertAsBlock(function.Body); var body = statementBuilder.ConvertAsBlock(function.Body);
body.AcceptVisitor(new InsertParenthesesVisitor { body.AcceptVisitor(new InsertParenthesesVisitor {

4
ICSharpCode.Decompiler/IL/Instructions.cs

@ -1113,10 +1113,6 @@ namespace ICSharpCode.Decompiler.IL
public sealed partial class Return : ILInstruction public sealed partial class Return : ILInstruction
{ {
public override StackType ResultType { get { return StackType.Void; } } public override StackType ResultType { get { return StackType.Void; } }
protected override InstructionFlags ComputeFlags()
{
return InstructionFlags.MayBranch | InstructionFlags.EndPointUnreachable;
}
public override T AcceptVisitor<T>(ILVisitor<T> visitor) public override T AcceptVisitor<T>(ILVisitor<T> visitor)
{ {
return visitor.VisitReturn(this); return visitor.VisitReturn(this);

2
ICSharpCode.Decompiler/IL/Instructions.tt

@ -126,7 +126,7 @@
new OpCode("localloc", "Allocates space in the stack frame", new OpCode("localloc", "Allocates space in the stack frame",
CustomClassName("LocAlloc"), Unary, ResultType("I"), MayThrow), CustomClassName("LocAlloc"), Unary, ResultType("I"), MayThrow),
new OpCode("ret", "Returns from the current method or lambda.", new OpCode("ret", "Returns from the current method or lambda.",
CustomClassName("Return"), CustomConstructor, MayBranch, UnconditionalBranch), CustomClassName("Return"), CustomConstructor, CustomComputeFlags, MayBranch, UnconditionalBranch),
new OpCode("shl", "Shift left", BinaryNumeric), new OpCode("shl", "Shift left", BinaryNumeric),
new OpCode("shr", "Shift right", BinaryNumeric), new OpCode("shr", "Shift right", BinaryNumeric),

8
ICSharpCode.Decompiler/IL/Instructions/Branch.cs

@ -75,6 +75,14 @@ namespace ICSharpCode.Decompiler.IL
get { return targetBlock != null ? targetBlock.Label : CecilExtensions.OffsetToString(TargetILOffset); } get { return targetBlock != null ? targetBlock.Label : CecilExtensions.OffsetToString(TargetILOffset); }
} }
internal override void CheckInvariant()
{
base.CheckInvariant();
if (targetBlock != null) {
Debug.Assert(targetBlock.Parent is BlockContainer);
Debug.Assert(this.IsDescendantOf(targetBlock.Parent));
}
}
public override void WriteTo(ITextOutput output) public override void WriteTo(ITextOutput output)
{ {

22
ICSharpCode.Decompiler/IL/Instructions/ILInstruction.cs

@ -53,8 +53,28 @@ namespace ICSharpCode.Decompiler.IL
} }
[Conditional("DEBUG")] [Conditional("DEBUG")]
internal void CheckInvariant() internal virtual void CheckInvariant()
{ {
foreach (var child in Children) {
Debug.Assert(child.Parent == this);
// if child flags are invalid, parent flags must be too
Debug.Assert(child.flags != invalidFlags || this.flags == invalidFlags);
Debug.Assert(child.IsConnected == this.IsConnected);
child.CheckInvariant();
}
}
/// <summary>
/// Gets whether this node is a descendant of <paramref name="possibleAncestor"/>.
/// Also returns true if <c>this</c>==<paramref name="possibleAncestor"/>.
/// </summary>
public bool IsDescendantOf(ILInstruction possibleAncestor)
{
for (ILInstruction ancestor = this; ancestor != null; ancestor = ancestor.Parent) {
if (ancestor == possibleAncestor)
return true;
}
return false;
} }
/// <summary> /// <summary>

9
ICSharpCode.Decompiler/IL/Instructions/Return.cs

@ -47,6 +47,15 @@ namespace ICSharpCode.Decompiler.IL
this.ReturnValue = argument; this.ReturnValue = argument;
} }
protected override InstructionFlags ComputeFlags()
{
InstructionFlags flags = InstructionFlags.MayBranch | InstructionFlags.EndPointUnreachable;
if (returnValue != null) {
flags |= returnValue.Flags;
}
return flags;
}
public override void WriteTo(ITextOutput output) public override void WriteTo(ITextOutput output)
{ {
output.Write(OpCode); output.Write(OpCode);

1
ILSpy/Languages/CSharpLanguage.cs

@ -212,7 +212,6 @@ namespace ICSharpCode.ILSpy
{ {
CSharpDecompiler decompiler = new CSharpDecompiler(type.Module); CSharpDecompiler decompiler = new CSharpDecompiler(type.Module);
output.WriteLine(decompiler.Decompile(type).ToString()); output.WriteLine(decompiler.Decompile(type).ToString());
// AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: type); // AstBuilder codeDomBuilder = CreateAstBuilder(options, currentType: type);
// codeDomBuilder.AddType(type); // codeDomBuilder.AddType(type);
// RunTransformsAndGenerateCode(codeDomBuilder, output, options); // RunTransformsAndGenerateCode(codeDomBuilder, output, options);

Loading…
Cancel
Save