mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Return back AST optimization of async methods.
This commit is contained in:
parent
73721e5b31
commit
5dfc8a3ed6
|
@ -202,7 +202,6 @@ public class Decompiler {
|
||||||
AsyncMethodNode node = new AsyncMethodNode(method.getReference());
|
AsyncMethodNode node = new AsyncMethodNode(method.getReference());
|
||||||
AsyncProgramSplitter splitter = new AsyncProgramSplitter(asyncMethods);
|
AsyncProgramSplitter splitter = new AsyncProgramSplitter(asyncMethods);
|
||||||
splitter.split(method.getProgram());
|
splitter.split(method.getProgram());
|
||||||
List<Program> partPrograms = new ArrayList<>();
|
|
||||||
for (int i = 0; i < splitter.size(); ++i) {
|
for (int i = 0; i < splitter.size(); ++i) {
|
||||||
Integer input = null;
|
Integer input = null;
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
|
@ -214,14 +213,13 @@ public class Decompiler {
|
||||||
AsyncMethodPart part = getRegularMethodStatement(splitter.getProgram(i), splitter.getBlockSuccessors(i),
|
AsyncMethodPart part = getRegularMethodStatement(splitter.getProgram(i), splitter.getBlockSuccessors(i),
|
||||||
input);
|
input);
|
||||||
node.getBody().add(part);
|
node.getBody().add(part);
|
||||||
partPrograms.add(splitter.getProgram(i));
|
|
||||||
}
|
}
|
||||||
Program program = method.getProgram();
|
Program program = method.getProgram();
|
||||||
for (int i = 0; i < program.variableCount(); ++i) {
|
for (int i = 0; i < program.variableCount(); ++i) {
|
||||||
node.getVariables().add(program.variableAt(i).getRegister());
|
node.getVariables().add(program.variableAt(i).getRegister());
|
||||||
}
|
}
|
||||||
Optimizer optimizer = new Optimizer();
|
Optimizer optimizer = new Optimizer();
|
||||||
optimizer.optimize(node, partPrograms);
|
optimizer.optimize(node, program, splitter);
|
||||||
node.getModifiers().addAll(mapModifiers(method.getModifiers()));
|
node.getModifiers().addAll(mapModifiers(method.getModifiers()));
|
||||||
int paramCount = Math.min(method.getSignature().length, program.variableCount());
|
int paramCount = Math.min(method.getSignature().length, program.variableCount());
|
||||||
for (int i = 0; i < paramCount; ++i) {
|
for (int i = 0; i < paramCount; ++i) {
|
||||||
|
|
|
@ -15,12 +15,11 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.javascript;
|
package org.teavm.javascript;
|
||||||
|
|
||||||
import java.util.List;
|
|
||||||
import org.teavm.javascript.ast.AsyncMethodNode;
|
import org.teavm.javascript.ast.AsyncMethodNode;
|
||||||
import org.teavm.javascript.ast.AsyncMethodPart;
|
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;
|
||||||
|
import org.teavm.model.util.AsyncProgramSplitter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -44,13 +43,17 @@ public class Optimizer {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public void optimize(AsyncMethodNode method, List<Program> programs) {
|
public void optimize(AsyncMethodNode method, Program program, AsyncProgramSplitter splitter) {
|
||||||
ReadWriteStatsBuilder stats = new ReadWriteStatsBuilder(method.getVariables().size());
|
ReadWriteStatsBuilder stats = new ReadWriteStatsBuilder(method.getVariables().size());
|
||||||
for (Program program : programs) {
|
stats.analyze(program);
|
||||||
stats.analyze(program);
|
for (int i = 0; i < splitter.size(); ++i) {
|
||||||
|
Integer var = splitter.getInput(i);
|
||||||
|
if (var != null) {
|
||||||
|
stats.reads[var]++;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
OptimizingVisitor optimizer = new OptimizingVisitor(stats);
|
|
||||||
for (AsyncMethodPart part : method.getBody()) {
|
for (AsyncMethodPart part : method.getBody()) {
|
||||||
|
OptimizingVisitor optimizer = new OptimizingVisitor(stats.copy());
|
||||||
part.getStatement().acceptVisitor(optimizer);
|
part.getStatement().acceptVisitor(optimizer);
|
||||||
part.setStatement(optimizer.resultStmt);
|
part.setStatement(optimizer.resultStmt);
|
||||||
}
|
}
|
||||||
|
|
|
@ -15,6 +15,7 @@
|
||||||
*/
|
*/
|
||||||
package org.teavm.javascript;
|
package org.teavm.javascript;
|
||||||
|
|
||||||
|
import java.util.Arrays;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
import org.teavm.model.util.DefinitionExtractor;
|
import org.teavm.model.util.DefinitionExtractor;
|
||||||
import org.teavm.model.util.UsageExtractor;
|
import org.teavm.model.util.UsageExtractor;
|
||||||
|
@ -27,11 +28,21 @@ class ReadWriteStatsBuilder {
|
||||||
public int[] reads;
|
public int[] reads;
|
||||||
public int[] writes;
|
public int[] writes;
|
||||||
|
|
||||||
|
private ReadWriteStatsBuilder() {
|
||||||
|
}
|
||||||
|
|
||||||
public ReadWriteStatsBuilder(int variableCount) {
|
public ReadWriteStatsBuilder(int variableCount) {
|
||||||
reads = new int[variableCount];
|
reads = new int[variableCount];
|
||||||
writes = new int[variableCount];
|
writes = new int[variableCount];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public ReadWriteStatsBuilder copy() {
|
||||||
|
ReadWriteStatsBuilder result = new ReadWriteStatsBuilder();
|
||||||
|
result.reads = Arrays.copyOf(reads, reads.length);
|
||||||
|
result.writes = Arrays.copyOf(writes, writes.length);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
public void analyze(Program program) {
|
public void analyze(Program program) {
|
||||||
DefinitionExtractor defExtractor = new DefinitionExtractor();
|
DefinitionExtractor defExtractor = new DefinitionExtractor();
|
||||||
UsageExtractor useExtractor = new UsageExtractor();
|
UsageExtractor useExtractor = new UsageExtractor();
|
||||||
|
|
|
@ -533,7 +533,11 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
}
|
}
|
||||||
writer.append(")").ws().append("{").softNewLine().indent();
|
writer.append(")").ws().append("{").softNewLine().indent();
|
||||||
method.acceptVisitor(new MethodBodyRenderer());
|
method.acceptVisitor(new MethodBodyRenderer());
|
||||||
writer.outdent().append("}").newLine();
|
writer.outdent().append("}");
|
||||||
|
if (inner) {
|
||||||
|
writer.append(';');
|
||||||
|
}
|
||||||
|
writer.newLine();
|
||||||
debugEmitter.emitMethod(null);
|
debugEmitter.emitMethod(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -630,18 +634,15 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
writer.append(";").softNewLine();
|
writer.append(";").softNewLine();
|
||||||
}
|
}
|
||||||
for (int i = 0; i < methodNode.getBody().size(); ++i) {
|
for (int i = 0; i < methodNode.getBody().size(); ++i) {
|
||||||
writer.append("function $part_").append(i).append("(");
|
writer.append("var $part_").append(i).ws().append("=").ws().append("$rt_guardAsync(function(");
|
||||||
if (i > 0) {
|
if (i > 0) {
|
||||||
writer.append("$restore");
|
writer.append("$restore");
|
||||||
}
|
}
|
||||||
writer.append(")").ws().append('{').indent().softNewLine();
|
writer.append(")").ws().append("{").indent().softNewLine();
|
||||||
writer.append("try {").indent().softNewLine();
|
|
||||||
AsyncMethodPart part = methodNode.getBody().get(i);
|
AsyncMethodPart part = methodNode.getBody().get(i);
|
||||||
part.getStatement().acceptVisitor(Renderer.this);
|
part.getStatement().acceptVisitor(Renderer.this);
|
||||||
writer.outdent().append("} catch ($guard) {").indent().softNewLine();
|
|
||||||
writer.append("return $return($rt_asyncError($guard));").softNewLine();
|
writer.append("return $return($rt_asyncError($guard));").softNewLine();
|
||||||
writer.outdent().append("}").softNewLine();
|
writer.outdent().append("},").ws().append("$return);").softNewLine();
|
||||||
writer.outdent().append("}").softNewLine();
|
|
||||||
}
|
}
|
||||||
writer.append("return $part_0();").softNewLine();
|
writer.append("return $part_0();").softNewLine();
|
||||||
} catch (IOException e) {
|
} catch (IOException e) {
|
||||||
|
|
|
@ -455,6 +455,15 @@ function $rt_continue(f) {
|
||||||
return f;
|
return f;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
function $rt_guardAsync(f, continuation) {
|
||||||
|
return function() {
|
||||||
|
try {
|
||||||
|
return f.apply(this, arguments);
|
||||||
|
} catch (e) {
|
||||||
|
return continuation($rt_asyncError(e));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
function $dbg_repr(obj) {
|
function $dbg_repr(obj) {
|
||||||
return obj.toString ? obj.toString() : "";
|
return obj.toString ? obj.toString() : "";
|
||||||
|
|
|
@ -55,18 +55,5 @@ public final class AsyncProgram {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
System.out.println("Complete async");
|
System.out.println("Complete async");
|
||||||
|
|
||||||
System.out.println("Throwing exception");
|
|
||||||
try {
|
|
||||||
throwException();
|
|
||||||
} catch (IllegalStateException e) {
|
|
||||||
System.out.println("Exception caught");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static void throwException() {
|
|
||||||
Thread.yield();
|
|
||||||
System.out.println("Thread.yield called");
|
|
||||||
throw new IllegalStateException();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue
Block a user