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.PreserveOriginalName;
|
||||
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) {
|
||||
return method.getModifiers().contains(ElementModifier.NATIVE) ? decompileNative(method) :
|
||||
return method.getModifiers().contains(ElementModifier.NATIVE) ? decompileNative(method, false) :
|
||||
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());
|
||||
if (generator == null) {
|
||||
AnnotationHolder annotHolder = method.getAnnotations().get(GeneratedBy.class.getName());
|
||||
|
@ -179,10 +184,12 @@ public class Decompiler {
|
|||
method.getDescriptor()));
|
||||
methodNode.getModifiers().addAll(mapModifiers(method.getModifiers()));
|
||||
methodNode.setGenerator(generator);
|
||||
methodNode.setAsync(async);
|
||||
return methodNode;
|
||||
}
|
||||
|
||||
public RegularMethodNode decompileRegular(MethodHolder method) {
|
||||
// TODO: add caching in case of incremental build
|
||||
if (regularMethodCache == null) {
|
||||
return decompileRegularCacheMiss(method);
|
||||
}
|
||||
|
@ -191,17 +198,52 @@ public class Decompiler {
|
|||
node = decompileRegularCacheMiss(method);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
graph = ProgramUtils.buildControlFlowGraph(method.getProgram());
|
||||
indexer = new GraphIndexer(graph);
|
||||
graph = indexer.getGraph();
|
||||
loopGraph = new LoopGraph(this.graph);
|
||||
unflatCode();
|
||||
Program program = method.getProgram();
|
||||
blockMap = new Block[program.basicBlockCount() * 2 + 1];
|
||||
Deque<Block> stack = new ArrayDeque<>();
|
||||
BlockStatement rootStmt = new BlockStatement();
|
||||
|
@ -276,22 +318,7 @@ public class Decompiler {
|
|||
}
|
||||
SequentialStatement result = new SequentialStatement();
|
||||
result.getSequence().addAll(rootStmt.getBody());
|
||||
MethodReference reference = new MethodReference(method.getOwnerName(), method.getDescriptor());
|
||||
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;
|
||||
return result;
|
||||
}
|
||||
|
||||
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 DeferredCallSite lastCallSite;
|
||||
private DeferredCallSite prevCallSite;
|
||||
private boolean async;
|
||||
|
||||
private static class InjectorHolder {
|
||||
public final Injector injector;
|
||||
|
@ -537,6 +538,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
@Override
|
||||
public void visit(RegularMethodNode method) {
|
||||
try {
|
||||
Renderer.this.async = false;
|
||||
MethodReference ref = method.getReference();
|
||||
for (int i = 0; i < method.getParameterDebugNames().size(); ++i) {
|
||||
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
|
||||
public String getParameterName(int index) {
|
||||
return variableName(index);
|
||||
|
@ -832,12 +878,18 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
pushLocation(statement.getLocation());
|
||||
}
|
||||
writer.append("return");
|
||||
if (async) {
|
||||
writer.append(" $return(");
|
||||
}
|
||||
if (statement.getResult() != null) {
|
||||
writer.append(' ');
|
||||
prevCallSite = debugEmitter.emitCallSite();
|
||||
statement.getResult().acceptVisitor(this);
|
||||
debugEmitter.emitCallSite();
|
||||
}
|
||||
if (async) {
|
||||
writer.append(')');
|
||||
}
|
||||
writer.append(";").softNewLine();
|
||||
if (statement.getLocation() != null) {
|
||||
popLocation();
|
||||
|
@ -854,7 +906,11 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
if (statement.getLocation() != null) {
|
||||
pushLocation(statement.getLocation());
|
||||
}
|
||||
writer.append("$rt_throw(");
|
||||
if (!async) {
|
||||
writer.append("$rt_throw(");
|
||||
} else {
|
||||
writer.append("return $throw(");
|
||||
}
|
||||
prevCallSite = debugEmitter.emitCallSite();
|
||||
statement.getException().acceptVisitor(this);
|
||||
writer.append(");").softNewLine();
|
||||
|
@ -1336,6 +1392,9 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
if (injector != null) {
|
||||
injector.generate(new InjectorContextImpl(expr.getArguments()), expr.getMethod());
|
||||
} else {
|
||||
if (expr.getAsyncTarget() != null) {
|
||||
writer.append("return ");
|
||||
}
|
||||
if (expr.getType() == InvocationType.DYNAMIC) {
|
||||
expr.getArguments().get(0).acceptVisitor(this);
|
||||
}
|
||||
|
@ -1358,7 +1417,6 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
}
|
||||
expr.getArguments().get(i).acceptVisitor(this);
|
||||
}
|
||||
writer.append(')');
|
||||
break;
|
||||
case SPECIAL:
|
||||
writer.append(fullName).append("(");
|
||||
|
@ -1368,7 +1426,6 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
writer.append(",").ws();
|
||||
expr.getArguments().get(i).acceptVisitor(this);
|
||||
}
|
||||
writer.append(")");
|
||||
break;
|
||||
case DYNAMIC:
|
||||
writer.append(".").append(name).append("(");
|
||||
|
@ -1379,7 +1436,6 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
}
|
||||
expr.getArguments().get(i).acceptVisitor(this);
|
||||
}
|
||||
writer.append(')');
|
||||
virtual = true;
|
||||
break;
|
||||
case CONSTRUCTOR:
|
||||
|
@ -1391,9 +1447,12 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
}
|
||||
expr.getArguments().get(i).acceptVisitor(this);
|
||||
}
|
||||
writer.append(')');
|
||||
break;
|
||||
}
|
||||
if (expr.getAsyncTarget() != null) {
|
||||
writer.append(',').ws().append("$part_").append(expr.getAsyncTarget());
|
||||
}
|
||||
writer.append(')');
|
||||
if (lastCallSite != null) {
|
||||
if (virtual) {
|
||||
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 InvocationType type;
|
||||
private List<Expr> arguments = new ArrayList<>();
|
||||
private Integer asyncTarget;
|
||||
|
||||
public MethodReference getMethod() {
|
||||
return method;
|
||||
|
@ -49,6 +50,14 @@ public class InvocationExpr extends Expr {
|
|||
return arguments;
|
||||
}
|
||||
|
||||
public Integer getAsyncTarget() {
|
||||
return asyncTarget;
|
||||
}
|
||||
|
||||
public void setAsyncTarget(Integer asyncTarget) {
|
||||
this.asyncTarget = asyncTarget;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptVisitor(ExprVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
|
@ -63,6 +72,7 @@ public class InvocationExpr extends Expr {
|
|||
InvocationExpr copy = new InvocationExpr();
|
||||
cache.put(this, copy);
|
||||
copy.setMethod(method);
|
||||
copy.setAsyncTarget(asyncTarget);
|
||||
for (Expr arg : arguments) {
|
||||
copy.getArguments().add(arg.clone(cache));
|
||||
}
|
||||
|
|
|
@ -22,5 +22,7 @@ package org.teavm.javascript.ast;
|
|||
public interface MethodNodeVisitor {
|
||||
void visit(RegularMethodNode methodNode);
|
||||
|
||||
void visit(AsyncMethodNode methodNode);
|
||||
|
||||
void visit(NativeMethodNode methodNode);
|
||||
}
|
||||
|
|
|
@ -24,6 +24,7 @@ import org.teavm.model.MethodReference;
|
|||
*/
|
||||
public class NativeMethodNode extends MethodNode {
|
||||
private Generator generator;
|
||||
private boolean async;
|
||||
|
||||
public NativeMethodNode(MethodReference reference) {
|
||||
super(reference);
|
||||
|
@ -37,6 +38,14 @@ public class NativeMethodNode extends MethodNode {
|
|||
this.generator = generator;
|
||||
}
|
||||
|
||||
public boolean isAsync() {
|
||||
return async;
|
||||
}
|
||||
|
||||
public void setAsync(boolean async) {
|
||||
this.async = async;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptVisitor(MethodNodeVisitor visitor) {
|
||||
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;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
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 Variable instance;
|
||||
private List<Variable> arguments = new ArrayList<>();
|
||||
private Set<MethodReference> implemenetations = new HashSet<MethodReference>();
|
||||
private boolean resolved;
|
||||
private Variable receiver;
|
||||
|
||||
public InvocationType getType() {
|
||||
|
@ -66,6 +72,18 @@ public class InvokeInstruction extends Instruction {
|
|||
this.receiver = receiver;
|
||||
}
|
||||
|
||||
public Set<MethodReference> getImplemenetations() {
|
||||
return implemenetations;
|
||||
}
|
||||
|
||||
public boolean isResolved() {
|
||||
return resolved;
|
||||
}
|
||||
|
||||
public void setResolved(boolean resolved) {
|
||||
this.resolved = resolved;
|
||||
}
|
||||
|
||||
@Override
|
||||
public void acceptVisitor(InstructionVisitor visitor) {
|
||||
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