Browse Source

Restore for loop condition. It is a simple pattern match.

pull/1/head^2
David Srbecký 18 years ago
parent
commit
af00ad101a
  1. 1
      Decompiler.csproj
  2. 2
      src/AstBuilder.cs
  3. 10
      src/AstMetodBodyBuilder.cs
  4. 9
      src/Transforms/Ast/RemoveGotos.cs
  5. 38
      src/Transforms/Ast/RestoreLoop.cs

1
Decompiler.csproj

@ -66,6 +66,7 @@
<Compile Include="src\Transforms\Ast\RemoveDeadLabels.cs" /> <Compile Include="src\Transforms\Ast\RemoveDeadLabels.cs" />
<Compile Include="src\Transforms\Ast\RemoveEmptyElseBody.cs" /> <Compile Include="src\Transforms\Ast\RemoveEmptyElseBody.cs" />
<Compile Include="src\Transforms\Ast\RemoveGotos.cs" /> <Compile Include="src\Transforms\Ast\RemoveGotos.cs" />
<Compile Include="src\Transforms\Ast\RestoreLoop.cs" />
<Compile Include="src\Transforms\Ast\SimplifyTypeReferences.cs" /> <Compile Include="src\Transforms\Ast\SimplifyTypeReferences.cs" />
<Compile Include="src\Util.cs" /> <Compile Include="src\Util.cs" />
<EmbeddedResource Include="src\MainForm.resx"> <EmbeddedResource Include="src\MainForm.resx">

2
src/AstBuilder.cs

@ -28,6 +28,8 @@ namespace Decompiler
astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveDeadLabels(), null); astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveDeadLabels(), null);
astCompileUnit.AcceptVisitor(new Transforms.Ast.SimplifyTypeReferences(), null); astCompileUnit.AcceptVisitor(new Transforms.Ast.SimplifyTypeReferences(), null);
astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveEmptyElseBody(), null); astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveEmptyElseBody(), null);
astCompileUnit.AcceptVisitor(new Transforms.Ast.RestoreLoop(), null);
astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveDeadLabels(), null);
astCompileUnit.AcceptVisitor(csOutVisitor, null); astCompileUnit.AcceptVisitor(csOutVisitor, null);

10
src/AstMetodBodyBuilder.cs

@ -86,11 +86,11 @@ namespace Decompiler
} else if (node is Loop) { } else if (node is Loop) {
Ast.MyBlockStatement blockStatement = new Ast.MyBlockStatement(); Ast.MyBlockStatement blockStatement = new Ast.MyBlockStatement();
blockStatement.Children.AddRange(TransformNodes(node.Childs)); blockStatement.Children.AddRange(TransformNodes(node.Childs));
yield return new Ast.DoLoopStatement( yield return new Ast.ForStatement(
new Ast.PrimitiveExpression(true, true.ToString()), null,
blockStatement, null,
ConditionType.While, null,
ConditionPosition.Start blockStatement
); );
} else if (node is Block) { } else if (node is Block) {
foreach(Ast.INode inode in TransformNodes(node.Childs)) { foreach(Ast.INode inode in TransformNodes(node.Childs)) {

9
src/Transforms/Ast/RemoveGotos.cs

@ -13,13 +13,20 @@ namespace Decompiler.Transforms.Ast
// Remove redundant jump at the end of block // Remove redundant jump at the end of block
INode lastStmt = blockStatement.Children[blockStatement.Children.Count - 1]; INode lastStmt = blockStatement.Children[blockStatement.Children.Count - 1];
// End of loop // End of while loop
if (lastStmt is ContinueStatement && if (lastStmt is ContinueStatement &&
blockStatement.Parent is DoLoopStatement) blockStatement.Parent is DoLoopStatement)
{ {
blockStatement.Children.Remove(lastStmt); blockStatement.Children.Remove(lastStmt);
return null; return null;
} }
// End of for loop
if (lastStmt is ContinueStatement &&
blockStatement.Parent is ForStatement)
{
blockStatement.Children.Remove(lastStmt);
return null;
}
// End of method // End of method
if (lastStmt is ReturnStatement && if (lastStmt is ReturnStatement &&
blockStatement.Parent is MethodDeclaration && blockStatement.Parent is MethodDeclaration &&

38
src/Transforms/Ast/RestoreLoop.cs

@ -0,0 +1,38 @@
using System;
using Ast = ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.Visitors;
namespace Decompiler.Transforms.Ast
{
public class RestoreLoop: AbstractAstTransformer
{
public override object VisitForStatement(ForStatement forStatement, object data)
{
base.VisitForStatement(forStatement, data);
if (forStatement.Condition.IsNull &&
forStatement.EmbeddedStatement.Children.Count >= 3)
{
IfElseStatement condition = forStatement.EmbeddedStatement.Children[0] as IfElseStatement;
BreakStatement breakStmt = forStatement.EmbeddedStatement.Children[1] as BreakStatement;
MyLabelStatement label = forStatement.EmbeddedStatement.Children[2] as MyLabelStatement;
if (condition != null &&
breakStmt != null &&
label != null &&
condition.TrueStatement.Count == 1)
{
MyGotoStatement gotoStmt = condition.TrueStatement[0] as MyGotoStatement;
if (gotoStmt != null && gotoStmt.NodeLabel == label.NodeLabel) {
forStatement.EmbeddedStatement.Children.RemoveAt(0);
forStatement.EmbeddedStatement.Children.RemoveAt(0);
gotoStmt.NodeLabel.ReferenceCount--;
forStatement.Condition = condition.Condition;
}
}
}
return null;
}
}
}
Loading…
Cancel
Save