Browse Source

The next statement for the end of loop is start of loop

pull/1/head^2
David Srbecký 18 years ago
parent
commit
110defad02
  1. 24
      bin/Debug/output.cs
  2. 49
      src/Transforms/Ast/RemoveGotos.cs

24
bin/Debug/output.cs

@ -61,15 +61,11 @@ namespace Reversi @@ -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 @@ -131,7 +127,6 @@ namespace Reversi
}
i = (i + dr);
j = (j + dc);
continue;
}
else {
break;
@ -183,16 +178,9 @@ namespace Reversi @@ -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 @@ -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 @@ -237,7 +222,6 @@ namespace Reversi
}
}
}
BasicBlock_262:
if (!((@this.squares).Get(i, j) != (IL__ldsfld(Black)))) {
IL__dup(@this);
object expr123 = expr122.blackCount;

49
src/Transforms/Ast/RemoveGotos.cs

@ -83,7 +83,7 @@ namespace Decompiler.Transforms.Ast @@ -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 @@ -96,22 +96,36 @@ namespace Decompiler.Transforms.Ast
if (statement.Parent is BlockStatement &&
statement.Parent.Parent is IfElseStatement) {
return GetNextStatement((Statement)statement.Parent.Parent);
}
// 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 null;
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 @@ -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) {
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 @@ -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 &&

Loading…
Cancel
Save