This commit is contained in:
Alexey Andreev 2015-04-19 15:33:56 +03:00
parent b7c7c2da73
commit 358766d5f6
3 changed files with 67 additions and 12 deletions

View File

@ -27,14 +27,24 @@ import org.teavm.javascript.ast.*;
class AllBlocksCountVisitor implements StatementVisitor {
private Map<IdentifiedStatement, Integer> blocksCount = new HashMap<>();
private IdentifiedStatement currentBlock;
private boolean last = true;
public void visit(List<Statement> statements) {
if (statements == null) {
return;
}
for (Statement part : statements) {
part.acceptVisitor(this);
if (statements.isEmpty()) {
incrementCurrentBlock();
return;
}
boolean oldLast = last;
for (int i = 0; i < statements.size() - 1; ++i) {
last = false;
statements.get(i).acceptVisitor(this);
}
last = true;
statements.get(statements.size() - 1).acceptVisitor(this);
last = oldLast;
}
public int getCount(IdentifiedStatement statement) {
@ -44,6 +54,9 @@ class AllBlocksCountVisitor implements StatementVisitor {
@Override
public void visit(AssignmentStatement statement) {
if (last) {
incrementCurrentBlock();
}
}
@Override
@ -66,6 +79,9 @@ class AllBlocksCountVisitor implements StatementVisitor {
}
visit(statement.getDefaultClause());
currentBlock = oldCurrentBlock;
if (last && blocksCount.containsKey(statement)) {
incrementCurrentBlock();
}
}
@Override
@ -74,6 +90,9 @@ class AllBlocksCountVisitor implements StatementVisitor {
currentBlock = statement;
visit(statement.getBody());
currentBlock = oldCurrentBlock;
if (last && (statement.getCondition() != null || blocksCount.containsKey(statement))) {
incrementCurrentBlock();
}
}
@Override
@ -82,6 +101,9 @@ class AllBlocksCountVisitor implements StatementVisitor {
currentBlock = statement;
visit(statement.getBody());
currentBlock = oldCurrentBlock;
if (last && blocksCount.containsKey(statement)) {
incrementCurrentBlock();
}
}
@Override
@ -90,7 +112,7 @@ class AllBlocksCountVisitor implements StatementVisitor {
if (target == null) {
target = currentBlock;
}
blocksCount.put(target, getCount(target) + 1);
incrementBlock(target);
}
@Override
@ -99,7 +121,17 @@ class AllBlocksCountVisitor implements StatementVisitor {
if (target == null) {
target = currentBlock;
}
blocksCount.put(target, getCount(target) + 1);
incrementBlock(target);
}
private void incrementBlock(IdentifiedStatement statement) {
blocksCount.put(statement, getCount(statement) + 1);
}
private void incrementCurrentBlock() {
if (currentBlock != null) {
incrementBlock(currentBlock);
}
}
@Override
@ -126,9 +158,15 @@ class AllBlocksCountVisitor implements StatementVisitor {
@Override
public void visit(MonitorEnterStatement statement) {
if (last) {
incrementCurrentBlock();
}
}
@Override
public void visit(MonitorExitStatement statement) {
if (last) {
incrementCurrentBlock();
}
}
}

View File

@ -26,7 +26,6 @@ class BreakEliminator implements StatementVisitor {
private Map<BlockStatement, List<Statement>> blockSuccessors = new HashMap<>();
private Set<IdentifiedStatement> outerStatements = new HashSet<>();
private List<Statement> currentSequence;
private boolean sequenceEscapes;
private int currentIndex;
private AllBlocksCountVisitor usageCounter;
@ -39,15 +38,12 @@ class BreakEliminator implements StatementVisitor {
private void processSequence(List<Statement> statements) {
List<Statement> oldSequence = currentSequence;
int oldIndex = currentIndex;
boolean oldEscapes = sequenceEscapes;
sequenceEscapes = escapes(statements);
currentSequence = statements;
for (currentIndex = 0; currentIndex < currentSequence.size(); ++currentIndex) {
statements.get(currentIndex).acceptVisitor(this);
}
sequenceEscapes = oldEscapes;
currentIndex = oldIndex;
currentSequence = oldSequence;
}
@ -93,7 +89,7 @@ class BreakEliminator implements StatementVisitor {
@Override
public void visit(BlockStatement statement) {
outerStatements.add(statement);
if (!sequenceEscapes && !escapes(statement.getBody())) {
if (!escapes(currentSequence.subList(currentIndex + 1, currentSequence.size()))) {
blockSuccessors.put(statement, currentSequence.subList(currentIndex + 1, currentSequence.size()));
}
processSequence(statement.getBody());
@ -110,7 +106,6 @@ class BreakEliminator implements StatementVisitor {
currentSequence.addAll(successors);
successors.clear();
--currentIndex;
sequenceEscapes = escapes(currentSequence);
return;
}
}

View File

@ -28,6 +28,8 @@ class EscapingStatementFinder implements StatementVisitor {
public boolean escaping;
private boolean last = true;
private Set<IdentifiedStatement> outerStatements = new HashSet<>();
private Set<IdentifiedStatement> breakTargets = new HashSet<>();
private IdentifiedStatement currentBlock;
public boolean check(List<Statement> statements) {
if (escaping) {
@ -72,6 +74,8 @@ class EscapingStatementFinder implements StatementVisitor {
@Override
public void visit(SwitchStatement statement) {
IdentifiedStatement oldCurrentBlock = currentBlock;
currentBlock = statement;
outerStatements.add(statement);
for (SwitchClause clause : statement.getClauses()) {
if (check(clause.getBody())) {
@ -80,32 +84,50 @@ class EscapingStatementFinder implements StatementVisitor {
}
check(statement.getDefaultClause());
outerStatements.remove(statement);
currentBlock = oldCurrentBlock;
if (breakTargets.contains(statement)) {
escaping |= last;
}
}
@Override
public void visit(WhileStatement statement) {
IdentifiedStatement oldCurrentBlock = currentBlock;
currentBlock = statement;
outerStatements.add(statement);
if (!check(statement.getBody()) && statement.getCondition() != null) {
escaping |= last;
}
outerStatements.remove(statement);
currentBlock = oldCurrentBlock;
if (breakTargets.contains(statement)) {
escaping |= last;
}
}
@Override
public void visit(BlockStatement statement) {
IdentifiedStatement oldCurrentBlock = currentBlock;
currentBlock = statement;
outerStatements.add(statement);
check(statement.getBody());
outerStatements.remove(statement);
currentBlock = oldCurrentBlock;
if (breakTargets.contains(statement)) {
escaping |= last;
}
}
@Override
public void visit(BreakStatement statement) {
escaping |= !outerStatements.contains(statement.getTarget());
IdentifiedStatement target = statement.getTarget() != null ? statement.getTarget() : currentBlock;
if (target != null) {
breakTargets.add(target);
}
}
@Override
public void visit(ContinueStatement statement) {
escaping |= !outerStatements.contains(statement.getTarget());
}
@Override