diff --git a/Decompiler.csproj b/Decompiler.csproj index eda362fbd..8cb0cef3c 100644 --- a/Decompiler.csproj +++ b/Decompiler.csproj @@ -55,6 +55,7 @@ + @@ -63,6 +64,7 @@ + MainForm.cs diff --git a/Decompiler.sln b/Decompiler.sln index ae4af9b72..d0132cdfb 100644 --- a/Decompiler.sln +++ b/Decompiler.sln @@ -1,7 +1,7 @@  Microsoft Visual Studio Solution File, Format Version 9.00 # 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}" EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Mono.Cecil", "lib\cecil-0.6\src\Mono.Cecil\Mono.Cecil.csproj", "{D8F63DFF-5230-43E4-9AB2-DA6E721A1FAE}" diff --git a/src/AstMetodBodyBuilder.cs b/src/AstMetodBodyBuilder.cs index 0e5659825..6232f642b 100644 --- a/src/AstMetodBodyBuilder.cs +++ b/src/AstMetodBodyBuilder.cs @@ -18,16 +18,16 @@ namespace Decompiler static Dictionary localVarTypes = new Dictionary(); static Dictionary localVarDefined = new Dictionary(); - public static BlockStatement CreateMetodBody(MethodDefinition methodDef) + public static MyBlockStatement CreateMetodBody(MethodDefinition methodDef) { AstMetodBodyBuilder builder = new AstMetodBodyBuilder(); builder.methodDef = methodDef; return builder.CreateMetodBody(); } - public BlockStatement CreateMetodBody() + public MyBlockStatement CreateMetodBody() { - Ast.BlockStatement astBlock = new Ast.BlockStatement(); + Ast.MyBlockStatement astBlock = new Ast.MyBlockStatement(); methodDef.Body.Simplify(); @@ -50,6 +50,7 @@ namespace Decompiler astBlock.Children.AddRange(TransformNodes(bodyGraph.Childs)); + astBlock.AcceptVisitor(new Transforms.Ast.RemoveGotos(), null); astBlock.AcceptVisitor(new Transforms.Ast.RemoveDeadLabels(), null); return astBlock; @@ -78,15 +79,15 @@ namespace Decompiler } Node fallThroughNode = ((BasicBlock)node).FallThroughBasicBlock; // 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); } } else if (node is AcyclicGraph) { - Ast.BlockStatement blockStatement = new Ast.BlockStatement(); + Ast.MyBlockStatement blockStatement = new Ast.MyBlockStatement(); blockStatement.Children.AddRange(TransformNodes(node.Childs)); yield return blockStatement; } else if (node is Loop) { - Ast.BlockStatement blockStatement = new Ast.BlockStatement(); + Ast.MyBlockStatement blockStatement = new Ast.MyBlockStatement(); blockStatement.Children.AddRange(TransformNodes(node.Childs)); yield return new Ast.DoLoopStatement( new Ast.PrimitiveExpression(true, true.ToString()), @@ -112,14 +113,14 @@ namespace Decompiler // Swap the method bodies 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 trueBlock.Children.Add(Ast.MyGotoStatement.Create(node, conditionalNode.Condition.FallThroughBasicBlock)); // Sugested content trueBlock.Children.AddRange(TransformNode(conditionalNode.TrueBody)); ifElseStmt.TrueStatement.Add(trueBlock); - Ast.BlockStatement falseBlock = new Ast.BlockStatement(); + Ast.MyBlockStatement falseBlock = new Ast.MyBlockStatement(); // The block entry code falseBlock.Children.Add(oldTrueBody); // Sugested content diff --git a/src/MyAst/MyBlockStatement.cs b/src/MyAst/MyBlockStatement.cs new file mode 100644 index 000000000..64d5145ee --- /dev/null +++ b/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 + { + MyBlockStatement myStmt; + + public void AddRange(IEnumerable 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 nodes): base(nodes) + { + this.myStmt = myStmt; + } + } + + public new ChildrenCollection Children { + get { + return wrapper; + } + } + + public MyBlockStatement() + { + this.wrapper = new ChildrenCollection(this, base.Children); + } + } +} diff --git a/src/Transforms/Ast/RemoveGotos.cs b/src/Transforms/Ast/RemoveGotos.cs new file mode 100644 index 000000000..7290b36eb --- /dev/null +++ b/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; + } + } +}