Browse Source

Remove flowing redundant jumps at the end of Ast blocks:

- Continue at the very end of loop
 - Empty Return at the very end of method
 - Goto at the very end of 'if' body, if the goto jumps right after the whole 'if' statement
pull/1/head^2
David Srbecký 18 years ago
parent
commit
d086b446e8
  1. 2
      src/AstBuilder.cs
  2. 2
      src/AstMetodBodyBuilder.cs
  3. 1
      src/Transforms/Ast/RemoveDeadLabels.cs
  4. 43
      src/Transforms/Ast/RemoveGotos.cs
  5. 1
      src/Transforms/Ast/SimplifyTypeReferences.cs

2
src/AstBuilder.cs

@ -22,6 +22,8 @@ namespace Decompiler
{ {
CSharpOutputVisitor csOutVisitor = new CSharpOutputVisitor(); CSharpOutputVisitor csOutVisitor = new CSharpOutputVisitor();
astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveGotos(), null);
astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveDeadLabels(), null);
astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveGotos(), null); astCompileUnit.AcceptVisitor(new Transforms.Ast.RemoveGotos(), null);
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);

2
src/AstMetodBodyBuilder.cs

@ -116,6 +116,7 @@ namespace Decompiler
// Sugested content // Sugested content
trueBlock.Children.AddRange(TransformNode(conditionalNode.TrueBody)); trueBlock.Children.AddRange(TransformNode(conditionalNode.TrueBody));
ifElseStmt.TrueStatement.Add(trueBlock); ifElseStmt.TrueStatement.Add(trueBlock);
trueBlock.Parent = ifElseStmt;
Ast.MyBlockStatement falseBlock = new Ast.MyBlockStatement(); Ast.MyBlockStatement falseBlock = new Ast.MyBlockStatement();
// The block entry code // The block entry code
@ -123,6 +124,7 @@ namespace Decompiler
// Sugested content // Sugested content
falseBlock.Children.AddRange(TransformNode(conditionalNode.FalseBody)); falseBlock.Children.AddRange(TransformNode(conditionalNode.FalseBody));
ifElseStmt.FalseStatement.Add(falseBlock); ifElseStmt.FalseStatement.Add(falseBlock);
falseBlock.Parent = ifElseStmt;
} else { } else {
throw new Exception("Bad node type"); throw new Exception("Bad node type");
} }

1
src/Transforms/Ast/RemoveDeadLabels.cs

@ -1,5 +1,6 @@
using System; using System;
using Ast = ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.Ast; using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.Visitors; using ICSharpCode.NRefactory.Visitors;

43
src/Transforms/Ast/RemoveGotos.cs

@ -7,6 +7,49 @@ namespace Decompiler.Transforms.Ast
{ {
public class RemoveGotos: AbstractAstTransformer public class RemoveGotos: AbstractAstTransformer
{ {
public override object VisitBlockStatement(BlockStatement blockStatement, object data)
{
base.VisitBlockStatement(blockStatement, data);
// Remove redundant jump at the end of block
INode lastStmt = blockStatement.Children[blockStatement.Children.Count - 1];
// End of loop
if (lastStmt is ContinueStatement &&
blockStatement.Parent is DoLoopStatement)
{
blockStatement.Children.Remove(lastStmt);
return null;
}
// End of method
if (lastStmt is ReturnStatement &&
blockStatement.Parent is MethodDeclaration &&
((ReturnStatement)lastStmt).Expression.IsNull)
{
blockStatement.Children.Remove(lastStmt);
return null;
}
// End of if body
if (lastStmt is GotoStatement &&
blockStatement.Parent is IfElseStatement)
{
INode ifParent = blockStatement.Parent.Parent;
int ifIndex = ifParent.Children.IndexOf(blockStatement.Parent);
if (ifIndex + 1 < ifParent.Children.Count) {
MyLabelStatement nextNodeAsLabel = ifParent.Children[ifIndex + 1] as MyLabelStatement;
if (nextNodeAsLabel != null) {
if (nextNodeAsLabel.NodeLabel == ((MyGotoStatement)lastStmt).NodeLabel) {
((MyGotoStatement)lastStmt).NodeLabel.ReferenceCount--;
blockStatement.Children.Remove(lastStmt);
}
}
}
return null;
}
return null;
}
public override object VisitGotoStatement(GotoStatement gotoStatement, object data) public override object VisitGotoStatement(GotoStatement gotoStatement, object data)
{ {
MyGotoStatement myGoto = (MyGotoStatement)gotoStatement; MyGotoStatement myGoto = (MyGotoStatement)gotoStatement;

1
src/Transforms/Ast/SimplifyTypeReferences.cs

@ -1,5 +1,6 @@
using System; using System;
using Ast = ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.Ast; using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.Visitors; using ICSharpCode.NRefactory.Visitors;

Loading…
Cancel
Save