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 { class AllBlocksCountVisitor implements StatementVisitor {
private Map<IdentifiedStatement, Integer> blocksCount = new HashMap<>(); private Map<IdentifiedStatement, Integer> blocksCount = new HashMap<>();
private IdentifiedStatement currentBlock; private IdentifiedStatement currentBlock;
private boolean last = true;
public void visit(List<Statement> statements) { public void visit(List<Statement> statements) {
if (statements == null) { if (statements == null) {
return; return;
} }
for (Statement part : statements) { if (statements.isEmpty()) {
part.acceptVisitor(this); 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) { public int getCount(IdentifiedStatement statement) {
@ -44,6 +54,9 @@ class AllBlocksCountVisitor implements StatementVisitor {
@Override @Override
public void visit(AssignmentStatement statement) { public void visit(AssignmentStatement statement) {
if (last) {
incrementCurrentBlock();
}
} }
@Override @Override
@ -66,6 +79,9 @@ class AllBlocksCountVisitor implements StatementVisitor {
} }
visit(statement.getDefaultClause()); visit(statement.getDefaultClause());
currentBlock = oldCurrentBlock; currentBlock = oldCurrentBlock;
if (last && blocksCount.containsKey(statement)) {
incrementCurrentBlock();
}
} }
@Override @Override
@ -74,6 +90,9 @@ class AllBlocksCountVisitor implements StatementVisitor {
currentBlock = statement; currentBlock = statement;
visit(statement.getBody()); visit(statement.getBody());
currentBlock = oldCurrentBlock; currentBlock = oldCurrentBlock;
if (last && (statement.getCondition() != null || blocksCount.containsKey(statement))) {
incrementCurrentBlock();
}
} }
@Override @Override
@ -82,6 +101,9 @@ class AllBlocksCountVisitor implements StatementVisitor {
currentBlock = statement; currentBlock = statement;
visit(statement.getBody()); visit(statement.getBody());
currentBlock = oldCurrentBlock; currentBlock = oldCurrentBlock;
if (last && blocksCount.containsKey(statement)) {
incrementCurrentBlock();
}
} }
@Override @Override
@ -90,7 +112,7 @@ class AllBlocksCountVisitor implements StatementVisitor {
if (target == null) { if (target == null) {
target = currentBlock; target = currentBlock;
} }
blocksCount.put(target, getCount(target) + 1); incrementBlock(target);
} }
@Override @Override
@ -99,7 +121,17 @@ class AllBlocksCountVisitor implements StatementVisitor {
if (target == null) { if (target == null) {
target = currentBlock; 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 @Override
@ -126,9 +158,15 @@ class AllBlocksCountVisitor implements StatementVisitor {
@Override @Override
public void visit(MonitorEnterStatement statement) { public void visit(MonitorEnterStatement statement) {
if (last) {
incrementCurrentBlock();
}
} }
@Override @Override
public void visit(MonitorExitStatement statement) { 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 Map<BlockStatement, List<Statement>> blockSuccessors = new HashMap<>();
private Set<IdentifiedStatement> outerStatements = new HashSet<>(); private Set<IdentifiedStatement> outerStatements = new HashSet<>();
private List<Statement> currentSequence; private List<Statement> currentSequence;
private boolean sequenceEscapes;
private int currentIndex; private int currentIndex;
private AllBlocksCountVisitor usageCounter; private AllBlocksCountVisitor usageCounter;
@ -39,15 +38,12 @@ class BreakEliminator implements StatementVisitor {
private void processSequence(List<Statement> statements) { private void processSequence(List<Statement> statements) {
List<Statement> oldSequence = currentSequence; List<Statement> oldSequence = currentSequence;
int oldIndex = currentIndex; int oldIndex = currentIndex;
boolean oldEscapes = sequenceEscapes;
sequenceEscapes = escapes(statements);
currentSequence = statements; currentSequence = statements;
for (currentIndex = 0; currentIndex < currentSequence.size(); ++currentIndex) { for (currentIndex = 0; currentIndex < currentSequence.size(); ++currentIndex) {
statements.get(currentIndex).acceptVisitor(this); statements.get(currentIndex).acceptVisitor(this);
} }
sequenceEscapes = oldEscapes;
currentIndex = oldIndex; currentIndex = oldIndex;
currentSequence = oldSequence; currentSequence = oldSequence;
} }
@ -93,7 +89,7 @@ class BreakEliminator implements StatementVisitor {
@Override @Override
public void visit(BlockStatement statement) { public void visit(BlockStatement statement) {
outerStatements.add(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())); blockSuccessors.put(statement, currentSequence.subList(currentIndex + 1, currentSequence.size()));
} }
processSequence(statement.getBody()); processSequence(statement.getBody());
@ -110,7 +106,6 @@ class BreakEliminator implements StatementVisitor {
currentSequence.addAll(successors); currentSequence.addAll(successors);
successors.clear(); successors.clear();
--currentIndex; --currentIndex;
sequenceEscapes = escapes(currentSequence);
return; return;
} }
} }

View File

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