mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -08:00
Further work on CPS generator
This commit is contained in:
parent
672de2f111
commit
3c9acd8fab
|
@ -15,6 +15,9 @@
|
|||
*/
|
||||
package org.teavm.classlib.java.lang;
|
||||
|
||||
import org.teavm.javascript.ni.GeneratedBy;
|
||||
import org.teavm.runtime.Async;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev
|
||||
|
@ -56,8 +59,9 @@ public class TThread extends TObject implements TRunnable {
|
|||
return name;
|
||||
}
|
||||
|
||||
public static void yield() {
|
||||
}
|
||||
@Async
|
||||
@GeneratedBy(ThreadNativeGenerator.class)
|
||||
public static native void yield();
|
||||
|
||||
public void interrupt() {
|
||||
}
|
||||
|
@ -81,4 +85,12 @@ public class TThread extends TObject implements TRunnable {
|
|||
public static boolean holdsLock(@SuppressWarnings("unused") TObject obj) {
|
||||
return true;
|
||||
}
|
||||
|
||||
public static void sleep(long millis) throws TInterruptedException {
|
||||
sleep((double)millis);
|
||||
}
|
||||
|
||||
@Async
|
||||
@GeneratedBy(ThreadNativeGenerator.class)
|
||||
private static native void sleep(double millis) throws TInterruptedException;
|
||||
}
|
||||
|
|
|
@ -0,0 +1,49 @@
|
|||
/*
|
||||
* 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.classlib.java.lang;
|
||||
|
||||
import java.io.IOException;
|
||||
import org.teavm.codegen.SourceWriter;
|
||||
import org.teavm.javascript.ni.Generator;
|
||||
import org.teavm.javascript.ni.GeneratorContext;
|
||||
import org.teavm.model.MethodReference;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||
*/
|
||||
public class ThreadNativeGenerator implements Generator {
|
||||
@Override
|
||||
public void generate(GeneratorContext context, SourceWriter writer, MethodReference methodRef) throws IOException {
|
||||
if (methodRef.getName().equals("sleep")) {
|
||||
generateSleep(context, writer);
|
||||
} else if (methodRef.getName().equals("yield")) {
|
||||
generateYield(context, writer);
|
||||
}
|
||||
}
|
||||
|
||||
private void generateSleep(GeneratorContext context, SourceWriter writer) throws IOException {
|
||||
writer.append("setTimer(function() {").indent().softNewLine();
|
||||
writer.append(context.getCompleteContinuation()).append("();").softNewLine();
|
||||
writer.outdent().append(',').ws().append(context.getParameterName(1)).append(");").softNewLine();
|
||||
}
|
||||
|
||||
private void generateYield(GeneratorContext context, SourceWriter writer) throws IOException {
|
||||
writer.append("setTimer(function() {").indent().softNewLine();
|
||||
writer.append(context.getCompleteContinuation()).append("();").softNewLine();
|
||||
writer.outdent().append(',').ws().append("0);").softNewLine();
|
||||
}
|
||||
}
|
|
@ -57,6 +57,15 @@ public class DefaultNamingStrategy implements NamingStrategy {
|
|||
|
||||
@Override
|
||||
public String getNameFor(MethodReference method) {
|
||||
return getNameFor(method, false);
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getNameForAsync(MethodReference method) throws NamingException {
|
||||
return getNameFor(method, true);
|
||||
}
|
||||
|
||||
private String getNameFor(MethodReference method, boolean async) {
|
||||
MethodReference origMethod = method;
|
||||
method = getRealMethod(method);
|
||||
if (method == null) {
|
||||
|
@ -67,7 +76,7 @@ public class DefaultNamingStrategy implements NamingStrategy {
|
|||
if (methodHolder.hasModifier(ElementModifier.STATIC) ||
|
||||
method.getDescriptor().getName().equals("<init>") ||
|
||||
methodHolder.getLevel() == AccessLevel.PRIVATE) {
|
||||
String key = method.toString();
|
||||
String key = (async ? "A" : "S") + method.toString();
|
||||
String alias = privateAliases.get(key);
|
||||
if (alias == null) {
|
||||
alias = aliasProvider.getAlias(method);
|
||||
|
@ -75,7 +84,7 @@ public class DefaultNamingStrategy implements NamingStrategy {
|
|||
}
|
||||
return alias;
|
||||
} else {
|
||||
String key = method.getDescriptor().toString();
|
||||
String key = (async ? "A" : "S") + method.getDescriptor().toString();
|
||||
String alias = aliases.get(key);
|
||||
if (alias == null) {
|
||||
alias = aliasProvider.getAlias(method);
|
||||
|
|
|
@ -27,6 +27,8 @@ public interface NamingStrategy {
|
|||
|
||||
String getNameFor(MethodReference method) throws NamingException;
|
||||
|
||||
String getNameForAsync(MethodReference method) throws NamingException;
|
||||
|
||||
String getFullNameFor(MethodReference method) throws NamingException;
|
||||
|
||||
String getNameFor(FieldReference field) throws NamingException;
|
||||
|
|
|
@ -149,7 +149,6 @@ public class Decompiler {
|
|||
if (method.getAnnotations().get(PreserveOriginalName.class.getName()) != null) {
|
||||
methodNode.setOriginalNamePreserved(true);
|
||||
}
|
||||
clsNode.getAsyncMethods().add(decompileAsync(method));
|
||||
}
|
||||
clsNode.getInterfaces().addAll(cls.getInterfaces());
|
||||
clsNode.getModifiers().addAll(mapModifiers(cls.getModifiers()));
|
||||
|
@ -158,12 +157,7 @@ public class Decompiler {
|
|||
|
||||
public MethodNode decompile(MethodHolder method) {
|
||||
return method.getModifiers().contains(ElementModifier.NATIVE) ? decompileNative(method, false) :
|
||||
decompileRegular(method);
|
||||
}
|
||||
|
||||
public MethodNode decompileAsync(MethodHolder method) {
|
||||
return method.getModifiers().contains(ElementModifier.NATIVE) ? decompileNative(method, true) :
|
||||
decompileRegularAsync(method);
|
||||
!asyncMethods.contains(method.getReference()) ? decompileRegular(method) : decompileAsync(method);
|
||||
}
|
||||
|
||||
public NativeMethodNode decompileNative(MethodHolder method, boolean async) {
|
||||
|
@ -204,7 +198,7 @@ public class Decompiler {
|
|||
return node;
|
||||
}
|
||||
|
||||
public AsyncMethodNode decompileRegularAsync(MethodHolder method) {
|
||||
public AsyncMethodNode decompileAsync(MethodHolder method) {
|
||||
AsyncMethodNode node = new AsyncMethodNode(method.getReference());
|
||||
AsyncProgramSplitter splitter = new AsyncProgramSplitter(asyncMethods);
|
||||
splitter.split(method.getProgram());
|
||||
|
|
|
@ -180,7 +180,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
|||
}
|
||||
|
||||
private boolean tryApplyConstructor(InvocationExpr expr) {
|
||||
if (!expr.getMethod().getName().equals("<init>")) {
|
||||
if (expr.getAsyncTarget() != null || !expr.getMethod().getName().equals("<init>")) {
|
||||
return false;
|
||||
}
|
||||
if (resultSequence == null || resultSequence.isEmpty()) {
|
||||
|
@ -211,7 +211,7 @@ class OptimizingVisitor implements StatementVisitor, ExprVisitor {
|
|||
}
|
||||
Expr[] args = expr.getArguments().toArray(new Expr[0]);
|
||||
args = Arrays.copyOfRange(args, 1, args.length);
|
||||
Expr constructrExpr = Expr.constructObject(expr.getMethod(), args);
|
||||
InvocationExpr constructrExpr = Expr.constructObject(expr.getMethod(), args);
|
||||
constructrExpr.setLocation(expr.getLocation());
|
||||
assignment.setRightValue(constructrExpr);
|
||||
stats.reads[var.getIndex()]--;
|
||||
|
|
|
@ -370,11 +370,6 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
for (MethodNode method : nonInitMethods) {
|
||||
renderBody(method, false);
|
||||
}
|
||||
for (MethodNode method : cls.getAsyncMethods()) {
|
||||
writer.append("/*").softNewLine();
|
||||
renderBody(method, false);
|
||||
writer.append("*/").softNewLine();
|
||||
}
|
||||
renderVirtualDeclarations(cls.getName(), virtualMethods);
|
||||
} catch (NamingException e) {
|
||||
throw new RenderingException("Error rendering class " + cls.getName() + ". See a cause for details", e);
|
||||
|
@ -475,6 +470,12 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
}
|
||||
writer.append(");").ws().append("}");
|
||||
debugEmitter.emitMethod(null);
|
||||
|
||||
if (!method.isAsync()) {
|
||||
writer.append(",").newLine();
|
||||
writer.append("\"").append(naming.getNameForAsync(ref)).append("\",").ws();
|
||||
writer.append("$rt_asyncAdapter(").appendMethodBody(ref).append(')');
|
||||
}
|
||||
}
|
||||
writer.append(");").newLine().outdent();
|
||||
}
|
||||
|
@ -524,6 +525,9 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
}
|
||||
writer.append(variableName(i));
|
||||
}
|
||||
if (method.isAsync()) {
|
||||
writer.append(',').ws().append("$return,").ws().append("$throw");
|
||||
}
|
||||
writer.append(")").ws().append("{").softNewLine().indent();
|
||||
method.acceptVisitor(new MethodBodyRenderer());
|
||||
writer.outdent().append("}").newLine();
|
||||
|
@ -531,9 +535,13 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
}
|
||||
|
||||
private class MethodBodyRenderer implements MethodNodeVisitor, GeneratorContext {
|
||||
private boolean async;
|
||||
|
||||
@Override
|
||||
public void visit(NativeMethodNode methodNode) {
|
||||
try {
|
||||
this.async = methodNode.isAsync();
|
||||
Renderer.this.async = methodNode.isAsync();
|
||||
methodNode.getGenerator().generate(this, writer, methodNode.getReference());
|
||||
} catch (IOException e) {
|
||||
throw new RenderingException("IO error occured", e);
|
||||
|
@ -544,6 +552,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
public void visit(RegularMethodNode method) {
|
||||
try {
|
||||
Renderer.this.async = false;
|
||||
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]),
|
||||
|
@ -583,6 +592,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
public void visit(AsyncMethodNode methodNode) {
|
||||
try {
|
||||
Renderer.this.async = true;
|
||||
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]),
|
||||
|
@ -607,8 +617,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
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();
|
||||
writer.append("function $part_").append(i).append("($input)").ws().append('{')
|
||||
.indent().softNewLine();
|
||||
AsyncMethodPart part = methodNode.getBody().get(i);
|
||||
if (part.getInputVariable() != null) {
|
||||
writer.append(variableName(part.getInputVariable())).ws().append('=').ws().append("$input;")
|
||||
|
@ -617,7 +627,7 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
part.getStatement().acceptVisitor(Renderer.this);
|
||||
writer.outdent().append('}').softNewLine();
|
||||
}
|
||||
writer.append("return $part_0;").softNewLine();
|
||||
writer.append("return $part_0();").softNewLine();
|
||||
} catch (IOException e) {
|
||||
throw new RenderingException("IO error occured", e);
|
||||
}
|
||||
|
@ -647,6 +657,21 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
public <T> T getService(Class<T> type) {
|
||||
return services.getService(type);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsync() {
|
||||
return async;
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getErrorContinuation() {
|
||||
return "$throw";
|
||||
}
|
||||
|
||||
@Override
|
||||
public String getCompleteContinuation() {
|
||||
return "$return";
|
||||
}
|
||||
}
|
||||
|
||||
private void pushLocation(NodeLocation location) {
|
||||
|
@ -1404,7 +1429,8 @@ public class Renderer implements ExprVisitor, StatementVisitor, RenderingContext
|
|||
expr.getArguments().get(0).acceptVisitor(this);
|
||||
}
|
||||
String className = naming.getNameFor(expr.getMethod().getClassName());
|
||||
String name = naming.getNameFor(expr.getMethod());
|
||||
String name = expr.getAsyncTarget() == null ? naming.getNameFor(expr.getMethod()) :
|
||||
naming.getNameForAsync(expr.getMethod());
|
||||
String fullName = naming.getFullNameFor(expr.getMethod());
|
||||
DeferredCallSite callSite = prevCallSite;
|
||||
boolean shouldEraseCallSite = lastCallSite == null;
|
||||
|
|
|
@ -49,4 +49,9 @@ public class AsyncMethodNode extends MethodNode {
|
|||
public void acceptVisitor(MethodNodeVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsync() {
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -30,7 +30,6 @@ public class ClassNode {
|
|||
private Set<NodeModifier> modifiers = EnumSet.noneOf(NodeModifier.class);
|
||||
private List<FieldNode> fields = new ArrayList<>();
|
||||
private List<MethodNode> methods = new ArrayList<>();
|
||||
private List<MethodNode> asyncMethods = new ArrayList<>();
|
||||
private List<String> interfaces = new ArrayList<>();
|
||||
|
||||
public ClassNode(String name, String parentName) {
|
||||
|
@ -54,10 +53,6 @@ public class ClassNode {
|
|||
return methods;
|
||||
}
|
||||
|
||||
public List<MethodNode> getAsyncMethods() {
|
||||
return asyncMethods;
|
||||
}
|
||||
|
||||
public List<String> getInterfaces() {
|
||||
return interfaces;
|
||||
}
|
||||
|
|
|
@ -104,7 +104,7 @@ public abstract class Expr implements Cloneable {
|
|||
return expr;
|
||||
}
|
||||
|
||||
public static Expr constructObject(MethodReference method, Expr[] arguments) {
|
||||
public static InvocationExpr constructObject(MethodReference method, Expr[] arguments) {
|
||||
InvocationExpr expr = new InvocationExpr();
|
||||
expr.setMethod(method);
|
||||
expr.setType(InvocationType.CONSTRUCTOR);
|
||||
|
|
|
@ -50,4 +50,6 @@ public abstract class MethodNode {
|
|||
}
|
||||
|
||||
public abstract void acceptVisitor(MethodNodeVisitor visitor);
|
||||
|
||||
public abstract boolean isAsync();
|
||||
}
|
||||
|
|
|
@ -38,6 +38,7 @@ public class NativeMethodNode extends MethodNode {
|
|||
this.generator = generator;
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsync() {
|
||||
return async;
|
||||
}
|
||||
|
|
|
@ -53,4 +53,9 @@ public class RegularMethodNode extends MethodNode {
|
|||
public void acceptVisitor(MethodNodeVisitor visitor) {
|
||||
visitor.visit(this);
|
||||
}
|
||||
|
||||
@Override
|
||||
public boolean isAsync() {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
|
|
@ -31,4 +31,10 @@ public interface GeneratorContext extends ServiceRepository {
|
|||
ClassLoader getClassLoader();
|
||||
|
||||
Properties getProperties();
|
||||
|
||||
boolean isAsync();
|
||||
|
||||
String getErrorContinuation();
|
||||
|
||||
String getCompleteContinuation();
|
||||
}
|
||||
|
|
|
@ -16,9 +16,7 @@
|
|||
package org.teavm.model.instructions;
|
||||
|
||||
import java.util.ArrayList;
|
||||
import java.util.HashSet;
|
||||
import java.util.List;
|
||||
import java.util.Set;
|
||||
import org.teavm.model.Instruction;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.Variable;
|
||||
|
@ -32,8 +30,6 @@ 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() {
|
||||
|
@ -72,18 +68,6 @@ 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,89 @@
|
|||
/*
|
||||
* 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.HashSet;
|
||||
import java.util.Set;
|
||||
import org.teavm.callgraph.CallGraph;
|
||||
import org.teavm.callgraph.CallGraphNode;
|
||||
import org.teavm.callgraph.CallSite;
|
||||
import org.teavm.diagnostics.Diagnostics;
|
||||
import org.teavm.javascript.ni.InjectedBy;
|
||||
import org.teavm.model.*;
|
||||
import org.teavm.runtime.Async;
|
||||
import org.teavm.runtime.Sync;
|
||||
|
||||
/**
|
||||
*
|
||||
* @author Alexey Andreev <konsoletyper@gmail.com>
|
||||
*/
|
||||
public class AsyncMethodFinder {
|
||||
private Set<MethodReference> asyncMethods = new HashSet<>();
|
||||
private CallGraph callGraph;
|
||||
private Diagnostics diagnostics;
|
||||
private ListableClassReaderSource classSource;
|
||||
|
||||
public AsyncMethodFinder(CallGraph callGraph, Diagnostics diagnostics) {
|
||||
this.callGraph = callGraph;
|
||||
this.diagnostics = diagnostics;
|
||||
}
|
||||
|
||||
public Set<MethodReference> getAsyncMethods() {
|
||||
return asyncMethods;
|
||||
}
|
||||
|
||||
public void find(ListableClassReaderSource classSource) {
|
||||
this.classSource = classSource;
|
||||
for (String clsName : classSource.getClassNames()) {
|
||||
ClassReader cls = classSource.get(clsName);
|
||||
for (MethodReader method : cls.getMethods()) {
|
||||
if (asyncMethods.contains(method.getReference())) {
|
||||
continue;
|
||||
}
|
||||
if (method.getAnnotations().get(Async.class.getName()) != null) {
|
||||
add(method.getReference());
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void add(MethodReference methodRef) {
|
||||
if (!asyncMethods.add(methodRef)) {
|
||||
return;
|
||||
}
|
||||
CallGraphNode node = callGraph.getNode(methodRef);
|
||||
if (node == null) {
|
||||
return;
|
||||
}
|
||||
ClassReader cls = classSource.get(methodRef.getClassName());
|
||||
if (cls == null) {
|
||||
return;
|
||||
}
|
||||
MethodReader method = cls.getMethod(methodRef.getDescriptor());
|
||||
if (method == null) {
|
||||
return;
|
||||
}
|
||||
if (method.getAnnotations().get(Sync.class.getName()) != null ||
|
||||
method.getAnnotations().get(InjectedBy.class.getName()) != null) {
|
||||
diagnostics.error(new CallLocation(methodRef), "Method {{m0}} is claimed to be synchronous, " +
|
||||
"but it is has invocations of asynchronous methods", methodRef);
|
||||
return;
|
||||
}
|
||||
for (CallSite callSite : node.getCallerCallSites()) {
|
||||
add(callSite.getCaller().getMethod());
|
||||
}
|
||||
}
|
||||
}
|
|
@ -61,7 +61,7 @@ public class AsyncProgramSplitter {
|
|||
Instruction insn = sourceBlock.getInstructions().get(i);
|
||||
if (insn instanceof InvokeInstruction) {
|
||||
InvokeInstruction invoke = (InvokeInstruction)insn;
|
||||
if (true) { //asyncMethods.contains(invoke)) {
|
||||
if (asyncMethods.contains(invoke.getMethod())) {
|
||||
asyncOccured = true;
|
||||
long key = ((long)step.source << 32) | i;
|
||||
if (partMap.containsKey(key)) {
|
||||
|
|
30
teavm-core/src/main/java/org/teavm/runtime/Sync.java
Normal file
30
teavm-core/src/main/java/org/teavm/runtime/Sync.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 <konsoletyper@gmail.com>
|
||||
*/
|
||||
@Retention(RetentionPolicy.RUNTIME)
|
||||
@Target(ElementType.METHOD)
|
||||
public @interface Sync {
|
||||
}
|
|
@ -526,8 +526,11 @@ public class TeaVM implements TeaVMHost, ServiceRepository {
|
|||
}
|
||||
|
||||
private List<ClassNode> modelToAst(ListableClassHolderSource classes) {
|
||||
AsyncMethodFinder asyncFinder = new AsyncMethodFinder(dependencyChecker.getCallGraph(), diagnostics);
|
||||
asyncFinder.find(classes);
|
||||
|
||||
progressListener.phaseStarted(TeaVMPhase.DECOMPILATION, classes.getClassNames().size());
|
||||
Decompiler decompiler = new Decompiler(classes, classLoader, new HashSet<MethodReference>());
|
||||
Decompiler decompiler = new Decompiler(classes, classLoader, asyncFinder.getAsyncMethods());
|
||||
decompiler.setRegularMethodCache(incremental ? astCache : null);
|
||||
|
||||
for (Map.Entry<MethodReference, Generator> entry : methodGenerators.entrySet()) {
|
||||
|
|
|
@ -392,6 +392,20 @@ function $rt_virtualMethods(cls) {
|
|||
}
|
||||
}
|
||||
}
|
||||
function $rt_asyncAdapter(f) {
|
||||
return function() {
|
||||
var e;
|
||||
var args = Array.prototype.slice.apply(arguments);
|
||||
var $throw = args.pop();
|
||||
var $return args.pop();
|
||||
try {
|
||||
var result = f.apply(this, args);
|
||||
} catch (e) {
|
||||
return $throw(e);
|
||||
}
|
||||
return $return(result);
|
||||
}
|
||||
}
|
||||
var $rt_stringPool_instance;
|
||||
function $rt_stringPool(strings) {
|
||||
$rt_stringPool_instance = new Array(strings.length);
|
||||
|
|
Loading…
Reference in New Issue
Block a user