Fix errors. Generalize AST optimizer to handle async methods

This commit is contained in:
konsoletyper 2015-02-01 00:02:20 +04:00
parent de85560876
commit 672de2f111
5 changed files with 52 additions and 1 deletions

View File

@ -214,6 +214,18 @@ public class Decompiler {
part.setStatement(getRegularMethodStatement(splitter.getProgram(i), i, splitter.getBlockSuccessors(i))); part.setStatement(getRegularMethodStatement(splitter.getProgram(i), i, splitter.getBlockSuccessors(i)));
node.getBody().add(part); node.getBody().add(part);
} }
Program program = method.getProgram();
for (int i = 0; i < program.variableCount(); ++i) {
node.getVariables().add(program.variableAt(i).getRegister());
}
Optimizer optimizer = new Optimizer();
optimizer.optimize(node, method.getProgram());
node.getModifiers().addAll(mapModifiers(method.getModifiers()));
int paramCount = Math.min(method.getSignature().length, program.variableCount());
for (int i = 0; i < paramCount; ++i) {
Variable var = program.variableAt(i);
node.getParameterDebugNames().add(new HashSet<>(var.getDebugNames()));
}
return node; return node;
} }

View File

@ -15,6 +15,8 @@
*/ */
package org.teavm.javascript; package org.teavm.javascript;
import org.teavm.javascript.ast.AsyncMethodNode;
import org.teavm.javascript.ast.AsyncMethodPart;
import org.teavm.javascript.ast.RegularMethodNode; import org.teavm.javascript.ast.RegularMethodNode;
import org.teavm.model.Program; import org.teavm.model.Program;
@ -40,4 +42,27 @@ public class Optimizer {
method.getVariables().set(i, i); method.getVariables().set(i, i);
} }
} }
public void optimize(AsyncMethodNode method, Program program) {
ReadWriteStatsBuilder stats = new ReadWriteStatsBuilder(method.getVariables().size());
stats.analyze(program);
OptimizingVisitor optimizer = new OptimizingVisitor(stats);
for (AsyncMethodPart part : method.getBody()) {
part.getStatement().acceptVisitor(optimizer);
part.setStatement(optimizer.resultStmt);
}
int paramCount = method.getReference().parameterCount();
UnusedVariableEliminator unusedEliminator = new UnusedVariableEliminator(paramCount, method.getVariables());
for (AsyncMethodPart part : method.getBody()) {
part.getStatement().acceptVisitor(unusedEliminator);
}
method.getVariables().subList(unusedEliminator.lastIndex, method.getVariables().size()).clear();
RedundantLabelEliminator labelEliminator = new RedundantLabelEliminator();
for (AsyncMethodPart part : method.getBody()) {
part.getStatement().acceptVisitor(labelEliminator);
}
for (int i = 0; i < method.getVariables().size(); ++i) {
method.getVariables().set(i, i);
}
}
} }

View File

@ -1455,7 +1455,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
break; break;
} }
if (expr.getAsyncTarget() != null) { if (expr.getAsyncTarget() != null) {
writer.append(',').ws().append("$part_").append(expr.getAsyncTarget()); writer.append(',').ws().append("$rt_continue($part_").append(expr.getAsyncTarget()).append(')');
} }
writer.append(')'); writer.append(')');
if (lastCallSite != null) { if (lastCallSite != null) {

View File

@ -57,6 +57,7 @@ public class AsyncProgramSplitter {
int end = step.sourceIndex; int end = step.sourceIndex;
boolean asyncOccured = false; boolean asyncOccured = false;
for (int i = step.sourceIndex; i < sourceBlock.getInstructions().size(); ++i) { for (int i = step.sourceIndex; i < sourceBlock.getInstructions().size(); ++i) {
end = i;
Instruction insn = sourceBlock.getInstructions().get(i); Instruction insn = sourceBlock.getInstructions().get(i);
if (insn instanceof InvokeInstruction) { if (insn instanceof InvokeInstruction) {
InvokeInstruction invoke = (InvokeInstruction)insn; InvokeInstruction invoke = (InvokeInstruction)insn;

View File

@ -402,6 +402,19 @@ function $rt_stringPool(strings) {
function $rt_s(index) { function $rt_s(index) {
return $rt_stringPool_instance[index]; return $rt_stringPool_instance[index];
} }
var $rt_continueCounter = 0;
function $rt_continue(f) {
if ($rt_continueCounter++ == 10) {
$rt_continueCounter = 0;
var self = f;
var args = arguments;
setTimeout(function() {
f.apply(self, args);
}, 0);
} else {
return f;
}
}
function $dbg_repr(obj) { function $dbg_repr(obj) {
return obj.toString ? obj.toString() : ""; return obj.toString ? obj.toString() : "";