mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Start implementing async JS generator
This commit is contained in:
parent
c546af553b
commit
5593aa074e
|
@ -23,7 +23,7 @@ import org.teavm.javascript.ni.Generator;
|
||||||
import org.teavm.javascript.ni.InjectedBy;
|
import org.teavm.javascript.ni.InjectedBy;
|
||||||
import org.teavm.javascript.ni.PreserveOriginalName;
|
import org.teavm.javascript.ni.PreserveOriginalName;
|
||||||
import org.teavm.model.*;
|
import org.teavm.model.*;
|
||||||
import org.teavm.model.util.ProgramUtils;
|
import org.teavm.model.util.AsyncProgramSplitter;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -153,11 +153,16 @@ public class Decompiler {
|
||||||
}
|
}
|
||||||
|
|
||||||
public MethodNode decompile(MethodHolder method) {
|
public MethodNode decompile(MethodHolder method) {
|
||||||
return method.getModifiers().contains(ElementModifier.NATIVE) ? decompileNative(method) :
|
return method.getModifiers().contains(ElementModifier.NATIVE) ? decompileNative(method, false) :
|
||||||
decompileRegular(method);
|
decompileRegular(method);
|
||||||
}
|
}
|
||||||
|
|
||||||
public NativeMethodNode decompileNative(MethodHolder method) {
|
public MethodNode decompileAsync(MethodHolder method) {
|
||||||
|
return method.getModifiers().contains(ElementModifier.NATIVE) ? decompileNative(method, true) :
|
||||||
|
decompileAsync(method);
|
||||||
|
}
|
||||||
|
|
||||||
|
public NativeMethodNode decompileNative(MethodHolder method, boolean async) {
|
||||||
Generator generator = generators.get(method.getReference());
|
Generator generator = generators.get(method.getReference());
|
||||||
if (generator == null) {
|
if (generator == null) {
|
||||||
AnnotationHolder annotHolder = method.getAnnotations().get(GeneratedBy.class.getName());
|
AnnotationHolder annotHolder = method.getAnnotations().get(GeneratedBy.class.getName());
|
||||||
|
@ -179,10 +184,12 @@ public class Decompiler {
|
||||||
method.getDescriptor()));
|
method.getDescriptor()));
|
||||||
methodNode.getModifiers().addAll(mapModifiers(method.getModifiers()));
|
methodNode.getModifiers().addAll(mapModifiers(method.getModifiers()));
|
||||||
methodNode.setGenerator(generator);
|
methodNode.setGenerator(generator);
|
||||||
|
methodNode.setAsync(async);
|
||||||
return methodNode;
|
return methodNode;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegularMethodNode decompileRegular(MethodHolder method) {
|
public RegularMethodNode decompileRegular(MethodHolder method) {
|
||||||
|
// TODO: add caching in case of incremental build
|
||||||
if (regularMethodCache == null) {
|
if (regularMethodCache == null) {
|
||||||
return decompileRegularCacheMiss(method);
|
return decompileRegularCacheMiss(method);
|
||||||
}
|
}
|
||||||
|
@ -191,17 +198,52 @@ public class Decompiler {
|
||||||
node = decompileRegularCacheMiss(method);
|
node = decompileRegularCacheMiss(method);
|
||||||
regularMethodCache.store(method.getReference(), node);
|
regularMethodCache.store(method.getReference(), node);
|
||||||
}
|
}
|
||||||
|
// TODO: add optimization
|
||||||
|
node.getModifiers().addAll(mapModifiers(method.getModifiers()));
|
||||||
|
int paramCount = Math.min(method.getSignature().length, method.getProgram().variableCount());
|
||||||
|
for (int i = 0; i < paramCount; ++i) {
|
||||||
|
Variable var = method.getProgram().variableAt(i);
|
||||||
|
node.getParameterDebugNames().add(new HashSet<>(var.getDebugNames()));
|
||||||
|
}
|
||||||
|
return node;
|
||||||
|
}
|
||||||
|
|
||||||
|
public AsyncMethodNode decompileRegularAsync(MethodHolder method) {
|
||||||
|
AsyncMethodNode node = new AsyncMethodNode(method.getReference());
|
||||||
|
AsyncProgramSplitter splitter = new AsyncProgramSplitter();
|
||||||
|
splitter.split(method.getProgram());
|
||||||
|
for (int i = 0; i < splitter.size(); ++i) {
|
||||||
|
AsyncMethodPart part = new AsyncMethodPart();
|
||||||
|
part.setInputVariable(splitter.getInput(i));
|
||||||
|
part.setStatement(getRegularMethodStatement(splitter.getProgram(i)));
|
||||||
|
}
|
||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
public RegularMethodNode decompileRegularCacheMiss(MethodHolder method) {
|
public RegularMethodNode decompileRegularCacheMiss(MethodHolder method) {
|
||||||
|
RegularMethodNode methodNode = new RegularMethodNode(method.getReference());
|
||||||
|
Program program = method.getProgram();
|
||||||
|
methodNode.setBody(getRegularMethodStatement(program));
|
||||||
|
for (int i = 0; i < program.variableCount(); ++i) {
|
||||||
|
methodNode.getVariables().add(program.variableAt(i).getRegister());
|
||||||
|
}
|
||||||
|
Optimizer optimizer = new Optimizer();
|
||||||
|
optimizer.optimize(methodNode, method.getProgram());
|
||||||
|
methodNode.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);
|
||||||
|
methodNode.getParameterDebugNames().add(new HashSet<>(var.getDebugNames()));
|
||||||
|
}
|
||||||
|
return methodNode;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Statement getRegularMethodStatement(Program program) {
|
||||||
lastBlockId = 1;
|
lastBlockId = 1;
|
||||||
graph = ProgramUtils.buildControlFlowGraph(method.getProgram());
|
|
||||||
indexer = new GraphIndexer(graph);
|
indexer = new GraphIndexer(graph);
|
||||||
graph = indexer.getGraph();
|
graph = indexer.getGraph();
|
||||||
loopGraph = new LoopGraph(this.graph);
|
loopGraph = new LoopGraph(this.graph);
|
||||||
unflatCode();
|
unflatCode();
|
||||||
Program program = method.getProgram();
|
|
||||||
blockMap = new Block[program.basicBlockCount() * 2 + 1];
|
blockMap = new Block[program.basicBlockCount() * 2 + 1];
|
||||||
Deque<Block> stack = new ArrayDeque<>();
|
Deque<Block> stack = new ArrayDeque<>();
|
||||||
BlockStatement rootStmt = new BlockStatement();
|
BlockStatement rootStmt = new BlockStatement();
|
||||||
|
@ -276,22 +318,7 @@ public class Decompiler {
|
||||||
}
|
}
|
||||||
SequentialStatement result = new SequentialStatement();
|
SequentialStatement result = new SequentialStatement();
|
||||||
result.getSequence().addAll(rootStmt.getBody());
|
result.getSequence().addAll(rootStmt.getBody());
|
||||||
MethodReference reference = new MethodReference(method.getOwnerName(), method.getDescriptor());
|
return result;
|
||||||
RegularMethodNode methodNode = new RegularMethodNode(reference);
|
|
||||||
methodNode.getModifiers().addAll(mapModifiers(method.getModifiers()));
|
|
||||||
methodNode.setBody(result);
|
|
||||||
for (int i = 0; i < program.variableCount(); ++i) {
|
|
||||||
methodNode.getVariables().add(program.variableAt(i).getRegister());
|
|
||||||
}
|
|
||||||
Optimizer optimizer = new Optimizer();
|
|
||||||
optimizer.optimize(methodNode, method.getProgram());
|
|
||||||
methodNode.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);
|
|
||||||
methodNode.getParameterDebugNames().add(new HashSet<>(var.getDebugNames()));
|
|
||||||
}
|
|
||||||
return methodNode;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private Set<NodeModifier> mapModifiers(Set<ElementModifier> modifiers) {
|
private Set<NodeModifier> mapModifiers(Set<ElementModifier> modifiers) {
|
||||||
|
|
|
@ -53,6 +53,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
private Deque<LocationStackEntry> locationStack = new ArrayDeque<>();
|
private Deque<LocationStackEntry> locationStack = new ArrayDeque<>();
|
||||||
private DeferredCallSite lastCallSite;
|
private DeferredCallSite lastCallSite;
|
||||||
private DeferredCallSite prevCallSite;
|
private DeferredCallSite prevCallSite;
|
||||||
|
private boolean async;
|
||||||
|
|
||||||
private static class InjectorHolder {
|
private static class InjectorHolder {
|
||||||
public final Injector injector;
|
public final Injector injector;
|
||||||
|
@ -537,6 +538,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
@Override
|
@Override
|
||||||
public void visit(RegularMethodNode method) {
|
public void visit(RegularMethodNode method) {
|
||||||
try {
|
try {
|
||||||
|
Renderer.this.async = false;
|
||||||
MethodReference ref = method.getReference();
|
MethodReference ref = method.getReference();
|
||||||
for (int i = 0; i < method.getParameterDebugNames().size(); ++i) {
|
for (int i = 0; i < method.getParameterDebugNames().size(); ++i) {
|
||||||
debugEmitter.emitVariable(method.getParameterDebugNames().get(i).toArray(new String[0]),
|
debugEmitter.emitVariable(method.getParameterDebugNames().get(i).toArray(new String[0]),
|
||||||
|
@ -572,6 +574,50 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void visit(AsyncMethodNode methodNode) {
|
||||||
|
try {
|
||||||
|
Renderer.this.async = true;
|
||||||
|
MethodReference ref = methodNode.getReference();
|
||||||
|
for (int i = 0; i < methodNode.getParameterDebugNames().size(); ++i) {
|
||||||
|
debugEmitter.emitVariable(methodNode.getParameterDebugNames().get(i).toArray(new String[0]),
|
||||||
|
variableName(i));
|
||||||
|
}
|
||||||
|
int variableCount = 0;
|
||||||
|
for (int var : methodNode.getVariables()) {
|
||||||
|
variableCount = Math.max(variableCount, var + 1);
|
||||||
|
}
|
||||||
|
List<String> variableNames = new ArrayList<>();
|
||||||
|
for (int i = ref.parameterCount() + 1; i < variableCount; ++i) {
|
||||||
|
variableNames.add(variableName(i));
|
||||||
|
}
|
||||||
|
if (!variableNames.isEmpty()) {
|
||||||
|
writer.append("var ");
|
||||||
|
for (int i = 0; i < variableNames.size(); ++i) {
|
||||||
|
if (i > 0) {
|
||||||
|
writer.append(",").ws();
|
||||||
|
}
|
||||||
|
writer.append(variableNames.get(i));
|
||||||
|
}
|
||||||
|
writer.append(";").softNewLine();
|
||||||
|
}
|
||||||
|
for (int i = 0; i < methodNode.getBody().size(); ++i) {
|
||||||
|
writer.append("function $part_").append(i).append("($input,").ws().append("$return,").ws()
|
||||||
|
.append("$throw)").ws().append('{').indent().softNewLine();
|
||||||
|
AsyncMethodPart part = methodNode.getBody().get(i);
|
||||||
|
if (part.getInputVariable() != null) {
|
||||||
|
writer.append(variableName(part.getInputVariable())).ws().append('=').ws().append("$input;")
|
||||||
|
.softNewLine();
|
||||||
|
}
|
||||||
|
part.getStatement().acceptVisitor(Renderer.this);
|
||||||
|
writer.outdent().append('}').softNewLine();
|
||||||
|
}
|
||||||
|
writer.append("return $part_0;").softNewLine();
|
||||||
|
} catch (IOException e) {
|
||||||
|
throw new RenderingException("IO error occured", e);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public String getParameterName(int index) {
|
public String getParameterName(int index) {
|
||||||
return variableName(index);
|
return variableName(index);
|
||||||
|
@ -832,12 +878,18 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
pushLocation(statement.getLocation());
|
pushLocation(statement.getLocation());
|
||||||
}
|
}
|
||||||
writer.append("return");
|
writer.append("return");
|
||||||
|
if (async) {
|
||||||
|
writer.append(" $return(");
|
||||||
|
}
|
||||||
if (statement.getResult() != null) {
|
if (statement.getResult() != null) {
|
||||||
writer.append(' ');
|
writer.append(' ');
|
||||||
prevCallSite = debugEmitter.emitCallSite();
|
prevCallSite = debugEmitter.emitCallSite();
|
||||||
statement.getResult().acceptVisitor(this);
|
statement.getResult().acceptVisitor(this);
|
||||||
debugEmitter.emitCallSite();
|
debugEmitter.emitCallSite();
|
||||||
}
|
}
|
||||||
|
if (async) {
|
||||||
|
writer.append(')');
|
||||||
|
}
|
||||||
writer.append(";").softNewLine();
|
writer.append(";").softNewLine();
|
||||||
if (statement.getLocation() != null) {
|
if (statement.getLocation() != null) {
|
||||||
popLocation();
|
popLocation();
|
||||||
|
@ -854,7 +906,11 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
if (statement.getLocation() != null) {
|
if (statement.getLocation() != null) {
|
||||||
pushLocation(statement.getLocation());
|
pushLocation(statement.getLocation());
|
||||||
}
|
}
|
||||||
|
if (!async) {
|
||||||
writer.append("$rt_throw(");
|
writer.append("$rt_throw(");
|
||||||
|
} else {
|
||||||
|
writer.append("return $throw(");
|
||||||
|
}
|
||||||
prevCallSite = debugEmitter.emitCallSite();
|
prevCallSite = debugEmitter.emitCallSite();
|
||||||
statement.getException().acceptVisitor(this);
|
statement.getException().acceptVisitor(this);
|
||||||
writer.append(");").softNewLine();
|
writer.append(");").softNewLine();
|
||||||
|
@ -1336,6 +1392,9 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
if (injector != null) {
|
if (injector != null) {
|
||||||
injector.generate(new InjectorContextImpl(expr.getArguments()), expr.getMethod());
|
injector.generate(new InjectorContextImpl(expr.getArguments()), expr.getMethod());
|
||||||
} else {
|
} else {
|
||||||
|
if (expr.getAsyncTarget() != null) {
|
||||||
|
writer.append("return ");
|
||||||
|
}
|
||||||
if (expr.getType() == InvocationType.DYNAMIC) {
|
if (expr.getType() == InvocationType.DYNAMIC) {
|
||||||
expr.getArguments().get(0).acceptVisitor(this);
|
expr.getArguments().get(0).acceptVisitor(this);
|
||||||
}
|
}
|
||||||
|
@ -1358,7 +1417,6 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
}
|
}
|
||||||
expr.getArguments().get(i).acceptVisitor(this);
|
expr.getArguments().get(i).acceptVisitor(this);
|
||||||
}
|
}
|
||||||
writer.append(')');
|
|
||||||
break;
|
break;
|
||||||
case SPECIAL:
|
case SPECIAL:
|
||||||
writer.append(fullName).append("(");
|
writer.append(fullName).append("(");
|
||||||
|
@ -1368,7 +1426,6 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
writer.append(",").ws();
|
writer.append(",").ws();
|
||||||
expr.getArguments().get(i).acceptVisitor(this);
|
expr.getArguments().get(i).acceptVisitor(this);
|
||||||
}
|
}
|
||||||
writer.append(")");
|
|
||||||
break;
|
break;
|
||||||
case DYNAMIC:
|
case DYNAMIC:
|
||||||
writer.append(".").append(name).append("(");
|
writer.append(".").append(name).append("(");
|
||||||
|
@ -1379,7 +1436,6 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
}
|
}
|
||||||
expr.getArguments().get(i).acceptVisitor(this);
|
expr.getArguments().get(i).acceptVisitor(this);
|
||||||
}
|
}
|
||||||
writer.append(')');
|
|
||||||
virtual = true;
|
virtual = true;
|
||||||
break;
|
break;
|
||||||
case CONSTRUCTOR:
|
case CONSTRUCTOR:
|
||||||
|
@ -1391,9 +1447,12 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
||||||
}
|
}
|
||||||
expr.getArguments().get(i).acceptVisitor(this);
|
expr.getArguments().get(i).acceptVisitor(this);
|
||||||
}
|
}
|
||||||
writer.append(')');
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
if (expr.getAsyncTarget() != null) {
|
||||||
|
writer.append(',').ws().append("$part_").append(expr.getAsyncTarget());
|
||||||
|
}
|
||||||
|
writer.append(')');
|
||||||
if (lastCallSite != null) {
|
if (lastCallSite != null) {
|
||||||
if (virtual) {
|
if (virtual) {
|
||||||
lastCallSite.setVirtualMethod(expr.getMethod());
|
lastCallSite.setVirtualMethod(expr.getMethod());
|
||||||
|
|
|
@ -0,0 +1,52 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.javascript.ast;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Set;
|
||||||
|
import org.teavm.model.MethodReference;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public class AsyncMethodNode extends MethodNode {
|
||||||
|
private List<AsyncMethodPart> body = new ArrayList<>();
|
||||||
|
private List<Integer> variables = new ArrayList<>();
|
||||||
|
private List<Set<String>> parameterDebugNames = new ArrayList<>();
|
||||||
|
|
||||||
|
public AsyncMethodNode(MethodReference reference) {
|
||||||
|
super(reference);
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<AsyncMethodPart> getBody() {
|
||||||
|
return body;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Integer> getVariables() {
|
||||||
|
return variables;
|
||||||
|
}
|
||||||
|
|
||||||
|
public List<Set<String>> getParameterDebugNames() {
|
||||||
|
return parameterDebugNames;
|
||||||
|
}
|
||||||
|
|
||||||
|
@Override
|
||||||
|
public void acceptVisitor(MethodNodeVisitor visitor) {
|
||||||
|
visitor.visit(this);
|
||||||
|
}
|
||||||
|
}
|
|
@ -0,0 +1,41 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.javascript.ast;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public class AsyncMethodPart {
|
||||||
|
private Statement statement;
|
||||||
|
private Integer inputVariable;
|
||||||
|
|
||||||
|
public Statement getStatement() {
|
||||||
|
return statement;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setStatement(Statement statement) {
|
||||||
|
this.statement = statement;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getInputVariable() {
|
||||||
|
return inputVariable;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setInputVariable(Integer inputVariable) {
|
||||||
|
this.inputVariable = inputVariable;
|
||||||
|
}
|
||||||
|
}
|
|
@ -28,6 +28,7 @@ public class InvocationExpr extends Expr {
|
||||||
private MethodReference method;
|
private MethodReference method;
|
||||||
private InvocationType type;
|
private InvocationType type;
|
||||||
private List<Expr> arguments = new ArrayList<>();
|
private List<Expr> arguments = new ArrayList<>();
|
||||||
|
private Integer asyncTarget;
|
||||||
|
|
||||||
public MethodReference getMethod() {
|
public MethodReference getMethod() {
|
||||||
return method;
|
return method;
|
||||||
|
@ -49,6 +50,14 @@ public class InvocationExpr extends Expr {
|
||||||
return arguments;
|
return arguments;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Integer getAsyncTarget() {
|
||||||
|
return asyncTarget;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAsyncTarget(Integer asyncTarget) {
|
||||||
|
this.asyncTarget = asyncTarget;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void acceptVisitor(ExprVisitor visitor) {
|
public void acceptVisitor(ExprVisitor visitor) {
|
||||||
visitor.visit(this);
|
visitor.visit(this);
|
||||||
|
@ -63,6 +72,7 @@ public class InvocationExpr extends Expr {
|
||||||
InvocationExpr copy = new InvocationExpr();
|
InvocationExpr copy = new InvocationExpr();
|
||||||
cache.put(this, copy);
|
cache.put(this, copy);
|
||||||
copy.setMethod(method);
|
copy.setMethod(method);
|
||||||
|
copy.setAsyncTarget(asyncTarget);
|
||||||
for (Expr arg : arguments) {
|
for (Expr arg : arguments) {
|
||||||
copy.getArguments().add(arg.clone(cache));
|
copy.getArguments().add(arg.clone(cache));
|
||||||
}
|
}
|
||||||
|
|
|
@ -22,5 +22,7 @@ package org.teavm.javascript.ast;
|
||||||
public interface MethodNodeVisitor {
|
public interface MethodNodeVisitor {
|
||||||
void visit(RegularMethodNode methodNode);
|
void visit(RegularMethodNode methodNode);
|
||||||
|
|
||||||
|
void visit(AsyncMethodNode methodNode);
|
||||||
|
|
||||||
void visit(NativeMethodNode methodNode);
|
void visit(NativeMethodNode methodNode);
|
||||||
}
|
}
|
||||||
|
|
|
@ -24,6 +24,7 @@ import org.teavm.model.MethodReference;
|
||||||
*/
|
*/
|
||||||
public class NativeMethodNode extends MethodNode {
|
public class NativeMethodNode extends MethodNode {
|
||||||
private Generator generator;
|
private Generator generator;
|
||||||
|
private boolean async;
|
||||||
|
|
||||||
public NativeMethodNode(MethodReference reference) {
|
public NativeMethodNode(MethodReference reference) {
|
||||||
super(reference);
|
super(reference);
|
||||||
|
@ -37,6 +38,14 @@ public class NativeMethodNode extends MethodNode {
|
||||||
this.generator = generator;
|
this.generator = generator;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public boolean isAsync() {
|
||||||
|
return async;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setAsync(boolean async) {
|
||||||
|
this.async = async;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void acceptVisitor(MethodNodeVisitor visitor) {
|
public void acceptVisitor(MethodNodeVisitor visitor) {
|
||||||
visitor.visit(this);
|
visitor.visit(this);
|
||||||
|
|
|
@ -0,0 +1,36 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.model;
|
||||||
|
|
||||||
|
import java.util.HashSet;
|
||||||
|
import java.util.Set;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public class AsyncInformation {
|
||||||
|
private Set<MethodReference> syncMethods = new HashSet<>();
|
||||||
|
private Set<MethodReference> asyncMethods = new HashSet<>();
|
||||||
|
|
||||||
|
public Set<MethodReference> getSyncMethods() {
|
||||||
|
return syncMethods;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Set<MethodReference> getAsyncMethods() {
|
||||||
|
return asyncMethods;
|
||||||
|
}
|
||||||
|
}
|
|
@ -16,8 +16,12 @@
|
||||||
package org.teavm.model.instructions;
|
package org.teavm.model.instructions;
|
||||||
|
|
||||||
import java.util.ArrayList;
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import org.teavm.model.*;
|
import java.util.Set;
|
||||||
|
import org.teavm.model.Instruction;
|
||||||
|
import org.teavm.model.MethodReference;
|
||||||
|
import org.teavm.model.Variable;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
*
|
*
|
||||||
|
@ -28,6 +32,8 @@ public class InvokeInstruction extends Instruction {
|
||||||
private MethodReference method;
|
private MethodReference method;
|
||||||
private Variable instance;
|
private Variable instance;
|
||||||
private List<Variable> arguments = new ArrayList<>();
|
private List<Variable> arguments = new ArrayList<>();
|
||||||
|
private Set<MethodReference> implemenetations = new HashSet<MethodReference>();
|
||||||
|
private boolean resolved;
|
||||||
private Variable receiver;
|
private Variable receiver;
|
||||||
|
|
||||||
public InvocationType getType() {
|
public InvocationType getType() {
|
||||||
|
@ -66,6 +72,18 @@ public class InvokeInstruction extends Instruction {
|
||||||
this.receiver = receiver;
|
this.receiver = receiver;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public Set<MethodReference> getImplemenetations() {
|
||||||
|
return implemenetations;
|
||||||
|
}
|
||||||
|
|
||||||
|
public boolean isResolved() {
|
||||||
|
return resolved;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void setResolved(boolean resolved) {
|
||||||
|
this.resolved = resolved;
|
||||||
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void acceptVisitor(InstructionVisitor visitor) {
|
public void acceptVisitor(InstructionVisitor visitor) {
|
||||||
visitor.visit(this);
|
visitor.visit(this);
|
||||||
|
|
|
@ -0,0 +1,54 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.model.util;
|
||||||
|
|
||||||
|
import java.util.ArrayList;
|
||||||
|
import java.util.HashMap;
|
||||||
|
import java.util.List;
|
||||||
|
import java.util.Map;
|
||||||
|
import org.teavm.model.Program;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public class AsyncProgramSplitter {
|
||||||
|
private List<Part> parts = new ArrayList<>();
|
||||||
|
private Map<Long, Integer> partMap = new HashMap<>();
|
||||||
|
|
||||||
|
public void split(Program program) {
|
||||||
|
parts.clear();
|
||||||
|
// TODO: implement splitting algorithm
|
||||||
|
partMap.clear();
|
||||||
|
}
|
||||||
|
|
||||||
|
public int size() {
|
||||||
|
return parts.size();
|
||||||
|
}
|
||||||
|
|
||||||
|
public Program getProgram(int index) {
|
||||||
|
return parts.get(index).program;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Integer getInput(int index) {
|
||||||
|
return parts.get(index).input;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static class Part {
|
||||||
|
Program program;
|
||||||
|
Integer input;
|
||||||
|
}
|
||||||
|
}
|
30
teavm-core/src/main/java/org/teavm/runtime/Async.java
Normal file
30
teavm-core/src/main/java/org/teavm/runtime/Async.java
Normal file
|
@ -0,0 +1,30 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.runtime;
|
||||||
|
|
||||||
|
import java.lang.annotation.ElementType;
|
||||||
|
import java.lang.annotation.Retention;
|
||||||
|
import java.lang.annotation.RetentionPolicy;
|
||||||
|
import java.lang.annotation.Target;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
|
@Target({ ElementType.CONSTRUCTOR, ElementType.METHOD })
|
||||||
|
public @interface Async {
|
||||||
|
}
|
|
@ -0,0 +1,26 @@
|
||||||
|
/*
|
||||||
|
* Copyright 2015 Alexey Andreev.
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
package org.teavm.runtime;
|
||||||
|
|
||||||
|
/**
|
||||||
|
*
|
||||||
|
* @author Alexey Andreev
|
||||||
|
*/
|
||||||
|
public interface AsyncCallback<T> {
|
||||||
|
void complete(T value);
|
||||||
|
|
||||||
|
void error(Exception e);
|
||||||
|
}
|
Loading…
Reference in New Issue
Block a user