Fix issues in break elimination

This commit is contained in:
Alexey Andreev 2015-04-17 22:52:02 +03:00
parent b3f662327c
commit eb48c349d0
2 changed files with 34 additions and 19 deletions

View File

@ -161,6 +161,6 @@ class BreakEliminator implements StatementVisitor {
} }
private boolean escapes(List<Statement> statements) { private boolean escapes(List<Statement> statements) {
return new EscapingStatementFinder(outerStatements).check(statements); return new EscapingStatementFinder().check(statements);
} }
} }

View File

@ -15,6 +15,7 @@
*/ */
package org.teavm.javascript; package org.teavm.javascript;
import java.util.HashSet;
import java.util.List; import java.util.List;
import java.util.Set; import java.util.Set;
import org.teavm.javascript.ast.*; import org.teavm.javascript.ast.*;
@ -25,26 +26,36 @@ import org.teavm.javascript.ast.*;
*/ */
class EscapingStatementFinder implements StatementVisitor { class EscapingStatementFinder implements StatementVisitor {
public boolean escaping; public boolean escaping;
private Set<IdentifiedStatement> outerStatements; private boolean last = true;
private Set<IdentifiedStatement> outerStatements = new HashSet<>();
public EscapingStatementFinder(Set<IdentifiedStatement> nestingStatements) {
this.outerStatements = nestingStatements;
}
public boolean check(List<Statement> statements) { public boolean check(List<Statement> statements) {
if (!escaping) { if (escaping) {
return true;
}
if (statements.isEmpty()) { if (statements.isEmpty()) {
escaping = true; escaping = last;
} else { return true;
}
boolean oldLast = last;
for (int i = 0; i < statements.size(); ++i) {
last = false;
statements.get(i).acceptVisitor(this);
if (escaping) {
break;
}
}
last = oldLast;
if (!escaping) {
statements.get(statements.size() - 1).acceptVisitor(this); statements.get(statements.size() - 1).acceptVisitor(this);
} }
} last = oldLast;
return escaping; return escaping;
} }
@Override @Override
public void visit(AssignmentStatement statement) { public void visit(AssignmentStatement statement) {
escaping = true; escaping |= last;
} }
@Override @Override
@ -73,7 +84,11 @@ class EscapingStatementFinder implements StatementVisitor{
@Override @Override
public void visit(WhileStatement statement) { public void visit(WhileStatement statement) {
escaping = true; outerStatements.add(statement);
if (!check(statement.getBody()) && statement.getCondition() != null) {
escaping |= last;
}
outerStatements.remove(statement);
} }
@Override @Override
@ -85,12 +100,12 @@ class EscapingStatementFinder implements StatementVisitor{
@Override @Override
public void visit(BreakStatement statement) { public void visit(BreakStatement statement) {
escaping = !outerStatements.contains(statement.getTarget()); escaping |= !outerStatements.contains(statement.getTarget());
} }
@Override @Override
public void visit(ContinueStatement statement) { public void visit(ContinueStatement statement) {
escaping = !outerStatements.contains(statement.getTarget()); escaping |= !outerStatements.contains(statement.getTarget());
} }
@Override @Override
@ -103,7 +118,7 @@ class EscapingStatementFinder implements StatementVisitor{
@Override @Override
public void visit(InitClassStatement statement) { public void visit(InitClassStatement statement) {
escaping = true; escaping |= last;
} }
@Override @Override
@ -118,11 +133,11 @@ class EscapingStatementFinder implements StatementVisitor{
@Override @Override
public void visit(MonitorEnterStatement statement) { public void visit(MonitorEnterStatement statement) {
escaping = true; escaping |= last;
} }
@Override @Override
public void visit(MonitorExitStatement statement) { public void visit(MonitorExitStatement statement) {
escaping = true; escaping |= last;
} }
} }