diff --git a/bin/Debug/output.cs b/bin/Debug/output.cs index d7d1b7b76..c0f67e38f 100644 --- a/bin/Debug/output.cs +++ b/bin/Debug/output.cs @@ -61,15 +61,11 @@ namespace Reversi } if (!(!@this.IsOutflanking(color, row, col, i, j))) { int k = (row + i); - for (int l = (col + j);; l = (l + j)) { - if (!((@this.squares).Get(k, l) == -color)) { - goto BasicBlock_31; - } + for (int l = (col + j); ((@this.squares).Get(k, l) == -color); l = (l + j)) { (@this.squares).Set(k, l, color); k = (k + i); } } - BasicBlock_31: } } @this.UpdateCounts(); @@ -131,7 +127,6 @@ namespace Reversi } i = (i + dr); j = (j + dc); - continue; } else { break; @@ -183,16 +178,9 @@ namespace Reversi @this.whiteFrontierCount = 0; @this.whiteSafeCount = 0; @this.blackSafeCount = 0; - for (bool V_2 = 1;;) { - BasicBlock_244: - if (!(V_2)) { - break; - } + for (bool V_2 = 1; (V_2);) { V_2 = 0; - for (int i = 0;; i = (i + 1)) { - if (!(i < 8)) { - goto BasicBlock_244; - } + for (int i = 0; (i < 8); i = (i + 1)) { for (int j = 0; (j < 8); j = (j + 1)) { if (!((@this.squares).Get(i, j) == (IL__ldsfld(Empty)))) { if (!((@this.safeDiscs).Get(i, j))) { @@ -211,10 +199,7 @@ namespace Reversi for (; (j < 8); j = (j + 1)) { bool V_5 = 0; if (!((@this.squares).Get(i, j) == (IL__ldsfld(Empty)))) { - for (int k = -1;; k = (k + 1)) { - if (!(k <= 1)) { - goto BasicBlock_262; - } + for (int k = -1; (k <= 1); k = (k + 1)) { for (int l = -1; (l <= 1); l = (l + 1)) { if (!(k)) { if (!(!l)) { @@ -237,7 +222,6 @@ namespace Reversi } } } - BasicBlock_262: if (!((@this.squares).Get(i, j) != (IL__ldsfld(Black)))) { IL__dup(@this); object expr123 = expr122.blackCount; diff --git a/src/Transforms/Ast/RemoveGotos.cs b/src/Transforms/Ast/RemoveGotos.cs index 3ce9afd36..442823f7b 100644 --- a/src/Transforms/Ast/RemoveGotos.cs +++ b/src/Transforms/Ast/RemoveGotos.cs @@ -83,7 +83,7 @@ namespace Decompiler.Transforms.Ast // Gets a next fall though statement, entering and exiting code blocks // It does not matter what the current statement is // May return null - public static Statement GetNextStatement(Statement statement) + public static INode GetNextStatement(Statement statement) { if (statement == null) throw new ArgumentNullException(); @@ -96,22 +96,36 @@ namespace Decompiler.Transforms.Ast if (statement.Parent is BlockStatement && statement.Parent.Parent is IfElseStatement) { return GetNextStatement((Statement)statement.Parent.Parent); - } else { - return null; } + + // When a 'for' body is finished the execution continues by: + // Iterator; Condition; Body + if (statement.Parent is BlockStatement && + statement.Parent.Parent is ForStatement) { + ForStatement forLoop = statement.Parent.Parent as ForStatement; + if (forLoop.Iterator.Count > 0) { + return forLoop.Iterator[0]; + } else if (!forLoop.Condition.IsNull) { + return forLoop.Condition; + } else { + return forLoop.EmbeddedStatement.Children.First; + } + } + + return null; } // Enter a block of code while(true) { // If a 'for' loop does not have initializers and condition, // the next statement is the entry point - ForStatement stmtAsForStmt = next as ForStatement; - if (stmtAsForStmt != null && - stmtAsForStmt.Initializers.Count == 0 && - stmtAsForStmt.Condition.IsNull && - stmtAsForStmt.EmbeddedStatement is BlockStatement && - stmtAsForStmt.EmbeddedStatement.Children.Count > 0) { - next = (Statement)stmtAsForStmt.EmbeddedStatement.Children.First; + ForStatement nextAsForStmt = next as ForStatement; + if (nextAsForStmt != null && + nextAsForStmt.Initializers.Count == 0 && + nextAsForStmt.Condition.IsNull && + nextAsForStmt.EmbeddedStatement is BlockStatement && + nextAsForStmt.EmbeddedStatement.Children.Count > 0) { + next = (Statement)nextAsForStmt.EmbeddedStatement.Children.First; continue; // Restart } @@ -122,25 +136,28 @@ namespace Decompiler.Transforms.Ast public override object VisitGotoStatement(GotoStatement gotoStatement, object data) { // Remove redundant goto which goes to a label that imideately follows - LabelStatement followingLabel = GetNextStatement(gotoStatement) as LabelStatement; - if (followingLabel != null && followingLabel.Label == gotoStatement.Label) { + INode fallthoughTarget = GetNextStatement(gotoStatement); + if ((fallthoughTarget is LabelStatement) && + (fallthoughTarget as LabelStatement).Label == gotoStatement.Label) { RemoveCurrentNode(); return null; } // Replace goto with 'break' // Break statement moves right outside the looop - if (CurrentLoop != null && - (CurrentLoop.Next() as LabelStatement) != null && - (CurrentLoop.Next() as LabelStatement).Label == gotoStatement.Label) { - ReplaceCurrentNode(new BreakStatement()); - return null; + if (CurrentLoop != null) { + INode breakTarget = GetNextStatement(CurrentLoop); + if ((breakTarget is LabelStatement) && + (breakTarget as LabelStatement).Label == gotoStatement.Label) { + ReplaceCurrentNode(new BreakStatement()); + return null; + } } // Replace goto with 'continue' // Continue statement which moves at the very end of loop if (CurrentLoop != null && - (CurrentLoop.EmbeddedStatement as BlockStatement) != null && + (CurrentLoop.EmbeddedStatement is BlockStatement) && ((CurrentLoop.EmbeddedStatement as BlockStatement).Children.Last as LabelStatement) != null && ((CurrentLoop.EmbeddedStatement as BlockStatement).Children.Last as LabelStatement).Label == gotoStatement.Label) { ReplaceCurrentNode(new ContinueStatement()); @@ -149,7 +166,7 @@ namespace Decompiler.Transforms.Ast // Replace goto with 'continue' // Continue statement which moves at the very start of for loop if there is no contition and iteration - if ((CurrentLoop as ForStatement) != null && + if ((CurrentLoop is ForStatement) && (CurrentLoop as ForStatement).Condition.IsNull && (CurrentLoop as ForStatement).Iterator.Count == 0 && (CurrentLoop.EmbeddedStatement as BlockStatement) != null &&