Browse Source

When looking what follows a 'goto' statement, exit and enter code blocks.

This simplifies code like:
if (p) {
    Code();
    goto Label;  // This goto is redundant
}
for(;;) {
    Label:
    Code();
}
pull/1/head^2
David Srbecký 18 years ago
parent
commit
ba59de34fb
  1. 60
      bin/Debug/output.cs
  2. 50
      src/Transforms/Ast/RemoveGotos.cs

60
bin/Debug/output.cs

@ -54,13 +54,11 @@ namespace Reversi @@ -54,13 +54,11 @@ namespace Reversi
for (int j = -1; (j <= 1); j = (j + 1)) {
if (!(i)) {
if (!(!j)) {
goto BasicBlock_27;
}
else {
continue;
}
}
BasicBlock_27:
if (!(!@this.IsOutflanking(color, row, col, i, j))) {
int k = (row + i);
for (int l = (col + j);; l = (l + j)) {
@ -96,13 +94,11 @@ namespace Reversi @@ -96,13 +94,11 @@ namespace Reversi
for (int j = -1; (j <= 1); j = (j + 1)) {
if (!(i)) {
if (!(!j)) {
goto BasicBlock_100;
}
else {
continue;
}
}
BasicBlock_100:
if (!(!@this.IsOutflanking(color, row, col, i, j))) {
return 1;
}
@ -159,31 +155,19 @@ namespace Reversi @@ -159,31 +155,19 @@ namespace Reversi
if (!(j > 7)) {
if (!((i - dr) != row)) {
if (!((j - dc) == col)) {
goto BasicBlock_178;
}
else {
goto BasicBlock_179;
}
}
BasicBlock_178:
if (!((@this.squares).Get(i, j) == color)) {
goto BasicBlock_179;
}
else {
goto BasicBlock_180;
}
}
else {
goto BasicBlock_179;
}
}
else {
goto BasicBlock_179;
}
}
else {
goto BasicBlock_179;
}
}
BasicBlock_179:
return 0;
@ -215,15 +199,8 @@ namespace Reversi @@ -215,15 +199,8 @@ namespace Reversi
if (!(@this.IsOutflankable(i, j))) {
(@this.safeDiscs).Set(i, j, 1);
V_2 = 1;
continue;
}
else {
continue;
}
}
else {
continue;
}
}
}
}
@ -241,35 +218,20 @@ namespace Reversi @@ -241,35 +218,20 @@ namespace Reversi
for (int l = -1; (l <= 1); l = (l + 1)) {
if (!(k)) {
if (!(!l)) {
goto BasicBlock_252;
}
else {
continue;
}
}
BasicBlock_252:
if (!((i + k) < 0)) {
if (!((i + k) >= 8)) {
if (!((j + l) < 0)) {
if (!((j + l) >= 8)) {
if (!((@this.squares).Get((i + k), (j + l)) != (IL__ldsfld(Empty)))) {
V_5 = 1;
continue;
}
else {
continue;
}
}
else {
continue;
}
}
else {
continue;
}
}
else {
continue;
}
}
}
@ -292,10 +254,6 @@ namespace Reversi @@ -292,10 +254,6 @@ namespace Reversi
object expr152 = expr151.blackSafeCount;
int expr158 = expr152 + 1;
expr151.blackSafeCount = expr158;
continue;
}
else {
continue;
}
}
else {
@ -349,9 +307,6 @@ namespace Reversi @@ -349,9 +307,6 @@ namespace Reversi
if (!((@this.safeDiscs).Get(row, k))) {
goto BasicBlock_400;
}
else {
goto BasicBlock_401;
}
}
else {
goto BasicBlock_400;
@ -381,9 +336,6 @@ namespace Reversi @@ -381,9 +336,6 @@ namespace Reversi
if (!((@this.safeDiscs).Get(row, k))) {
goto BasicBlock_409;
}
else {
goto BasicBlock_410;
}
}
else {
goto BasicBlock_409;
@ -427,9 +379,6 @@ namespace Reversi @@ -427,9 +379,6 @@ namespace Reversi
if (!((@this.safeDiscs).Get(j, col))) {
goto BasicBlock_425;
}
else {
goto BasicBlock_426;
}
}
else {
goto BasicBlock_425;
@ -459,9 +408,6 @@ namespace Reversi @@ -459,9 +408,6 @@ namespace Reversi
if (!((@this.safeDiscs).Get(j, col))) {
goto BasicBlock_434;
}
else {
goto BasicBlock_435;
}
}
else {
goto BasicBlock_434;
@ -508,9 +454,6 @@ namespace Reversi @@ -508,9 +454,6 @@ namespace Reversi
if (!((@this.safeDiscs).Get(j, k))) {
goto BasicBlock_450;
}
else {
goto BasicBlock_451;
}
}
else {
goto BasicBlock_450;
@ -547,9 +490,6 @@ namespace Reversi @@ -547,9 +490,6 @@ namespace Reversi
if (!((@this.safeDiscs).Get(j, k))) {
goto BasicBlock_460;
}
else {
goto BasicBlock_461;
}
}
else {
goto BasicBlock_460;

50
src/Transforms/Ast/RemoveGotos.cs

@ -80,21 +80,49 @@ namespace Decompiler.Transforms.Ast @@ -80,21 +80,49 @@ namespace Decompiler.Transforms.Ast
return null;
}
public override object VisitGotoStatement(GotoStatement gotoStatement, object data)
// 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)
{
// Find what is the next statement following this one
// It does fall though loop entries (the loop must not have initializer and condition)
INode followingStmt = gotoStatement.Next();
while(
(followingStmt as ForStatement) != null &&
(followingStmt as ForStatement).Initializers.Count == 0 &&
(followingStmt as ForStatement).Condition.IsNull &&
(followingStmt as ForStatement).EmbeddedStatement is BlockStatement) {
followingStmt = (followingStmt as ForStatement).EmbeddedStatement.Children.First;
if (statement == null) throw new ArgumentNullException();
Statement next = (Statement)statement.Next();
// Exit a block of code
if (next == null) {
// When an 'if' body is finished the execution continues with the
// next statement after the 'if' statement
if (statement.Parent is BlockStatement &&
statement.Parent.Parent is IfElseStatement) {
return GetNextStatement((Statement)statement.Parent.Parent);
} else {
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;
continue; // Restart
}
return next;
}
}
public override object VisitGotoStatement(GotoStatement gotoStatement, object data)
{
// Remove redundant goto which goes to a label that imideately follows
LabelStatement followingLabel = followingStmt as LabelStatement;
LabelStatement followingLabel = GetNextStatement(gotoStatement) as LabelStatement;
if (followingLabel != null && followingLabel.Label == gotoStatement.Label) {
RemoveCurrentNode();
return null;

Loading…
Cancel
Save