Browse Source

Remove redundant 'goto' statements in form:

goto labelX;
labelX: command();
pull/1/head^2
David Srbecký 18 years ago
parent
commit
8643290a4c
  1. 2
      Decompiler.csproj
  2. 2
      Decompiler.sln
  3. 17
      src/AstMetodBodyBuilder.cs
  4. 53
      src/MyAst/MyBlockStatement.cs
  5. 26
      src/Transforms/Ast/RemoveGotos.cs

2
Decompiler.csproj

@ -55,6 +55,7 @@
<Compile Include="src\ControlFlow\Node-Structure.cs" /> <Compile Include="src\ControlFlow\Node-Structure.cs" />
<Compile Include="src\MainForm.cs" /> <Compile Include="src\MainForm.cs" />
<Compile Include="src\MainForm.Designer.cs" /> <Compile Include="src\MainForm.Designer.cs" />
<Compile Include="src\MyAst\MyBlockStatement.cs" />
<Compile Include="src\MyAst\MyGotoStatement.cs" /> <Compile Include="src\MyAst\MyGotoStatement.cs" />
<Compile Include="src\MyAst\MyLabelStatement.cs" /> <Compile Include="src\MyAst\MyLabelStatement.cs" />
<Compile Include="src\Options.cs" /> <Compile Include="src\Options.cs" />
@ -63,6 +64,7 @@
<Compile Include="src\StackExpression.cs" /> <Compile Include="src\StackExpression.cs" />
<Compile Include="src\StackExpressionCollection.cs" /> <Compile Include="src\StackExpressionCollection.cs" />
<Compile Include="src\Transforms\Ast\RemoveDeadLabels.cs" /> <Compile Include="src\Transforms\Ast\RemoveDeadLabels.cs" />
<Compile Include="src\Transforms\Ast\RemoveGotos.cs" />
<Compile Include="src\Util.cs" /> <Compile Include="src\Util.cs" />
<EmbeddedResource Include="src\MainForm.resx"> <EmbeddedResource Include="src\MainForm.resx">
<DependentUpon>MainForm.cs</DependentUpon> <DependentUpon>MainForm.cs</DependentUpon>

2
Decompiler.sln

@ -1,7 +1,7 @@
 
Microsoft Visual Studio Solution File, Format Version 9.00 Microsoft Visual Studio Solution File, Format Version 9.00
# Visual Studio 2005 # Visual Studio 2005
# SharpDevelop 3.0.0.2909 # SharpDevelop 3.0.0.2914
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Decompiler", "Decompiler.csproj", "{EE3A3C1A-F9C3-4C75-853D-A9476E518C3A}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Decompiler", "Decompiler.csproj", "{EE3A3C1A-F9C3-4C75-853D-A9476E518C3A}"
EndProject EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil", "lib\cecil-0.6\src\Mono.Cecil\Mono.Cecil.csproj", "{D8F63DFF-5230-43E4-9AB2-DA6E721A1FAE}" Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil", "lib\cecil-0.6\src\Mono.Cecil\Mono.Cecil.csproj", "{D8F63DFF-5230-43E4-9AB2-DA6E721A1FAE}"

17
src/AstMetodBodyBuilder.cs

@ -18,16 +18,16 @@ namespace Decompiler
static Dictionary<string, Cecil.TypeReference> localVarTypes = new Dictionary<string, Cecil.TypeReference>(); static Dictionary<string, Cecil.TypeReference> localVarTypes = new Dictionary<string, Cecil.TypeReference>();
static Dictionary<string, bool> localVarDefined = new Dictionary<string, bool>(); static Dictionary<string, bool> localVarDefined = new Dictionary<string, bool>();
public static BlockStatement CreateMetodBody(MethodDefinition methodDef) public static MyBlockStatement CreateMetodBody(MethodDefinition methodDef)
{ {
AstMetodBodyBuilder builder = new AstMetodBodyBuilder(); AstMetodBodyBuilder builder = new AstMetodBodyBuilder();
builder.methodDef = methodDef; builder.methodDef = methodDef;
return builder.CreateMetodBody(); return builder.CreateMetodBody();
} }
public BlockStatement CreateMetodBody() public MyBlockStatement CreateMetodBody()
{ {
Ast.BlockStatement astBlock = new Ast.BlockStatement(); Ast.MyBlockStatement astBlock = new Ast.MyBlockStatement();
methodDef.Body.Simplify(); methodDef.Body.Simplify();
@ -50,6 +50,7 @@ namespace Decompiler
astBlock.Children.AddRange(TransformNodes(bodyGraph.Childs)); astBlock.Children.AddRange(TransformNodes(bodyGraph.Childs));
astBlock.AcceptVisitor(new Transforms.Ast.RemoveGotos(), null);
astBlock.AcceptVisitor(new Transforms.Ast.RemoveDeadLabels(), null); astBlock.AcceptVisitor(new Transforms.Ast.RemoveDeadLabels(), null);
return astBlock; return astBlock;
@ -78,15 +79,15 @@ namespace Decompiler
} }
Node fallThroughNode = ((BasicBlock)node).FallThroughBasicBlock; Node fallThroughNode = ((BasicBlock)node).FallThroughBasicBlock;
// If there is default branch and it is not the following node // If there is default branch and it is not the following node
if (fallThroughNode != null && fallThroughNode != node.NextNode) { if (fallThroughNode != null) {
yield return Ast.MyGotoStatement.Create(node, fallThroughNode); yield return Ast.MyGotoStatement.Create(node, fallThroughNode);
} }
} else if (node is AcyclicGraph) { } else if (node is AcyclicGraph) {
Ast.BlockStatement blockStatement = new Ast.BlockStatement(); Ast.MyBlockStatement blockStatement = new Ast.MyBlockStatement();
blockStatement.Children.AddRange(TransformNodes(node.Childs)); blockStatement.Children.AddRange(TransformNodes(node.Childs));
yield return blockStatement; yield return blockStatement;
} else if (node is Loop) { } else if (node is Loop) {
Ast.BlockStatement blockStatement = new Ast.BlockStatement(); 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.DoLoopStatement(
new Ast.PrimitiveExpression(true, true.ToString()), new Ast.PrimitiveExpression(true, true.ToString()),
@ -112,14 +113,14 @@ namespace Decompiler
// Swap the method bodies // Swap the method bodies
ifElseStmt.Condition = new Ast.UnaryOperatorExpression(new Ast.ParenthesizedExpression(ifElseStmt.Condition), UnaryOperatorType.Not); ifElseStmt.Condition = new Ast.UnaryOperatorExpression(new Ast.ParenthesizedExpression(ifElseStmt.Condition), UnaryOperatorType.Not);
Ast.BlockStatement trueBlock = new Ast.BlockStatement(); Ast.MyBlockStatement trueBlock = new Ast.MyBlockStatement();
// The block entry code // The block entry code
trueBlock.Children.Add(Ast.MyGotoStatement.Create(node, conditionalNode.Condition.FallThroughBasicBlock)); trueBlock.Children.Add(Ast.MyGotoStatement.Create(node, conditionalNode.Condition.FallThroughBasicBlock));
// Sugested content // Sugested content
trueBlock.Children.AddRange(TransformNode(conditionalNode.TrueBody)); trueBlock.Children.AddRange(TransformNode(conditionalNode.TrueBody));
ifElseStmt.TrueStatement.Add(trueBlock); ifElseStmt.TrueStatement.Add(trueBlock);
Ast.BlockStatement falseBlock = new Ast.BlockStatement(); Ast.MyBlockStatement falseBlock = new Ast.MyBlockStatement();
// The block entry code // The block entry code
falseBlock.Children.Add(oldTrueBody); falseBlock.Children.Add(oldTrueBody);
// Sugested content // Sugested content

53
src/MyAst/MyBlockStatement.cs

@ -0,0 +1,53 @@
using System;
using System.Collections.Generic;
using Ast = ICSharpCode.NRefactory.Ast;
using Decompiler.ControlFlow;
namespace ICSharpCode.NRefactory.Ast
{
public class MyBlockStatement: BlockStatement
{
ChildrenCollection wrapper;
public class ChildrenCollection: System.Collections.ObjectModel.Collection<INode>
{
MyBlockStatement myStmt;
public void AddRange(IEnumerable<INode> items)
{
foreach(INode node in items) {
Add(node);
}
}
protected override void InsertItem(int index, INode item)
{
item.Parent = myStmt;
base.InsertItem(index, item);
}
protected override void SetItem(int index, INode item)
{
item.Parent = myStmt;
base.SetItem(index, item);
}
public ChildrenCollection(MyBlockStatement myStmt, IList<INode> nodes): base(nodes)
{
this.myStmt = myStmt;
}
}
public new ChildrenCollection Children {
get {
return wrapper;
}
}
public MyBlockStatement()
{
this.wrapper = new ChildrenCollection(this, base.Children);
}
}
}

26
src/Transforms/Ast/RemoveGotos.cs

@ -0,0 +1,26 @@
using System;
using ICSharpCode.NRefactory.Ast;
using ICSharpCode.NRefactory.Visitors;
namespace Decompiler.Transforms.Ast
{
public class RemoveGotos: AbstractAstTransformer
{
public override object VisitGotoStatement(GotoStatement gotoStatement, object data)
{
MyGotoStatement myGoto = (MyGotoStatement)gotoStatement;
if (gotoStatement.Parent == null) return null;
int index = gotoStatement.Parent.Children.IndexOf(gotoStatement);
if (index + 1 < gotoStatement.Parent.Children.Count) {
INode nextStmt = gotoStatement.Parent.Children[index + 1];
MyLabelStatement myLabel = nextStmt as MyLabelStatement;
if (myLabel != null && myLabel.NodeLabel == myGoto.NodeLabel) {
myGoto.NodeLabel.ReferenceCount--;
RemoveCurrentNode();
}
}
return null;
}
}
}
Loading…
Cancel
Save