Browse Source

Fix detection of do-while and for loops.

pull/734/merge
Daniel Grunwald 8 years ago
parent
commit
00564f5fcd
  1. 28
      ICSharpCode.Decompiler/CSharp/StatementBuilder.cs
  2. 1
      ICSharpCode.Decompiler/IL/Instructions.cs
  3. 17
      ICSharpCode.Decompiler/IL/Transforms/LoopingTransform.cs
  4. 2
      ICSharpCode.Decompiler/Util/CollectionExtensions.cs

28
ICSharpCode.Decompiler/CSharp/StatementBuilder.cs

@ -381,21 +381,25 @@ namespace ICSharpCode.Decompiler.CSharp @@ -381,21 +381,25 @@ namespace ICSharpCode.Decompiler.CSharp
private static Block FindDoWhileConditionBlock(BlockContainer container, out ILInstruction condition)
{
var conditionGroup = new CaptureGroup();
var conditionBlockPattern = new Block {
Instructions = {
new IfInstruction(new AnyNode(conditionGroup), new Branch(container.EntryPoint)),
new Leave(container)
}
};
condition = null;
foreach (var b in container.Blocks) {
var match = conditionBlockPattern.Match(b);
if (match.Success) {
condition = match.Get(conditionGroup).Single();
return b;
if (b.Instructions.Last().MatchBranch(container.EntryPoint)) {
// potentially the do-while-condition block
int i = b.Instructions.Count - 2;
while (i >= 0 && b.Instructions[i] is IfInstruction ifInst
&& ifInst.TrueInst.MatchLeave(container) && ifInst.FalseInst.MatchNop())
{
if (condition == null)
condition = new LogicNot(ifInst.Condition);
else
condition = IfInstruction.LogicAnd(new LogicNot(ifInst.Condition), condition);
i--;
}
if (i == -1) {
return b;
}
}
}
condition = null;
return null;
}

1
ICSharpCode.Decompiler/IL/Instructions.cs

@ -836,6 +836,7 @@ namespace ICSharpCode.Decompiler.IL @@ -836,6 +836,7 @@ namespace ICSharpCode.Decompiler.IL
{
}
public override StackType ResultType { get { return StackType.I4; } }
public override void AcceptVisitor(ILVisitor visitor)
{
visitor.VisitLogicNot(this);

17
ICSharpCode.Decompiler/IL/Transforms/LoopingTransform.cs

@ -39,13 +39,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms @@ -39,13 +39,16 @@ namespace ICSharpCode.Decompiler.IL.Transforms
if (running)
throw new InvalidOperationException("LoopingBlockTransform already running. Transforms (and the CSharpDecompiler) are neither neither thread-safe nor re-entrant.");
running = true;
do {
block.ResetDirty();
block.RunTransforms(children, context);
if (block.IsDirty)
context.Step("Block is dirty; running another loop iteration.", block);
} while (block.IsDirty);
running = false;
try {
do {
block.ResetDirty();
block.RunTransforms(children, context);
if (block.IsDirty)
context.Step("Block is dirty; running another loop iteration.", block);
} while (block.IsDirty);
} finally {
running = false;
}
}
public IReadOnlyCollection<IBlockTransform> Transforms {

2
ICSharpCode.Decompiler/Util/CollectionExtensions.cs

@ -19,7 +19,7 @@ namespace ICSharpCode.Decompiler.Util @@ -19,7 +19,7 @@ namespace ICSharpCode.Decompiler.Util
public static IEnumerable<T> SkipLast<T>(this IReadOnlyCollection<T> input, int count)
{
return input.Skip(input.Count - count);
return input.Take(input.Count - count);
}
public static T PopOrDefault<T>(this Stack<T> stack)

Loading…
Cancel
Save