Make async methods work in bootstrap TeaVM

This commit is contained in:
Alexey Andreev 2017-12-03 20:47:20 +03:00
parent 7a03bf795f
commit 82b11f285e
4 changed files with 48 additions and 10 deletions

View File

@ -0,0 +1,31 @@
/*
* Copyright 2017 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.platform.plugin;
import org.teavm.dependency.AbstractDependencyListener;
import org.teavm.dependency.DependencyAgent;
import org.teavm.dependency.MethodDependency;
import org.teavm.interop.Async;
import org.teavm.model.CallLocation;
public class AsyncDependencyListener extends AbstractDependencyListener {
@Override
public void methodReached(DependencyAgent agent, MethodDependency method, CallLocation location) {
if (method.getMethod() != null && method.getMethod().getAnnotations().get(Async.class.getName()) != null) {
new AsyncMethodGenerator().methodReached(agent, method, location);
}
}
}

View File

@ -16,11 +16,8 @@
package org.teavm.platform.plugin; package org.teavm.platform.plugin;
import org.teavm.backend.javascript.spi.GeneratedBy; import org.teavm.backend.javascript.spi.GeneratedBy;
import org.teavm.dependency.PluggableDependency;
import org.teavm.diagnostics.Diagnostics; import org.teavm.diagnostics.Diagnostics;
import org.teavm.interop.Async; import org.teavm.interop.Async;
import org.teavm.model.AnnotationHolder;
import org.teavm.model.AnnotationValue;
import org.teavm.model.CallLocation; import org.teavm.model.CallLocation;
import org.teavm.model.ClassHolder; import org.teavm.model.ClassHolder;
import org.teavm.model.ClassHolderTransformer; import org.teavm.model.ClassHolderTransformer;
@ -53,12 +50,6 @@ public class AsyncMethodProcessor implements ClassHolderTransformer {
+ "both be either static or non-static", + "both be either static or non-static",
method.getReference(), asyncMethod.getReference()); method.getReference(), asyncMethod.getReference());
} }
AnnotationHolder annot = new AnnotationHolder(GeneratedBy.class.getName());
annot.getValues().put("value", new AnnotationValue(ValueType.parse(AsyncMethodGenerator.class)));
method.getAnnotations().add(annot);
annot = new AnnotationHolder(PluggableDependency.class.getName());
annot.getValues().put("value", new AnnotationValue(ValueType.parse(AsyncMethodGenerator.class)));
method.getAnnotations().add(annot);
} }
} }
} }

View File

@ -166,7 +166,7 @@ public class PlatformGenerator implements Generator, Injector, DependencyPlugin
MethodReference launchRef = new MethodReference(Platform.class, "launchThread", MethodReference launchRef = new MethodReference(Platform.class, "launchThread",
PlatformRunnable.class, void.class); PlatformRunnable.class, void.class);
String runnable = context.getParameterName(1); String runnable = context.getParameterName(1);
writer.append("return window.setTimeout(function()").ws().append("{").indent().softNewLine(); writer.append("return setTimeout(function()").ws().append("{").indent().softNewLine();
if (timeout) { if (timeout) {
writer.appendMethodBody(launchRef); writer.appendMethodBody(launchRef);
} else { } else {

View File

@ -21,7 +21,10 @@ import org.teavm.backend.wasm.TeaVMWasmHost;
import org.teavm.backend.wasm.intrinsics.WasmIntrinsic; import org.teavm.backend.wasm.intrinsics.WasmIntrinsic;
import org.teavm.backend.wasm.intrinsics.WasmIntrinsicManager; import org.teavm.backend.wasm.intrinsics.WasmIntrinsicManager;
import org.teavm.backend.wasm.model.expression.WasmExpression; import org.teavm.backend.wasm.model.expression.WasmExpression;
import org.teavm.interop.Async;
import org.teavm.interop.PlatformMarker; import org.teavm.interop.PlatformMarker;
import org.teavm.model.ClassReader;
import org.teavm.model.MethodReader;
import org.teavm.model.MethodReference; import org.teavm.model.MethodReference;
import org.teavm.platform.Platform; import org.teavm.platform.Platform;
import org.teavm.platform.PlatformQueue; import org.teavm.platform.PlatformQueue;
@ -37,6 +40,18 @@ public class PlatformPlugin implements TeaVMPlugin {
host.add(new ResourceTransformer()); host.add(new ResourceTransformer());
host.add(new ResourceAccessorTransformer(host)); host.add(new ResourceAccessorTransformer(host));
host.add(new ResourceAccessorDependencyListener()); host.add(new ResourceAccessorDependencyListener());
host.getExtension(TeaVMJavaScriptHost.class).addGeneratorProvider(context -> {
ClassReader cls = context.getClassSource().get(context.getMethod().getClassName());
if (cls == null) {
return null;
}
MethodReader method = cls.getMethod(context.getMethod().getDescriptor());
if (method == null) {
return null;
}
return method.getAnnotations().get(Async.class.getName()) != null
? new AsyncMethodGenerator() : null;
});
} else if (!isBootstrap()) { } else if (!isBootstrap()) {
host.add(new StringAmplifierTransformer()); host.add(new StringAmplifierTransformer());
} }
@ -68,6 +83,7 @@ public class PlatformPlugin implements TeaVMPlugin {
host.add(new EnumDependencySupport()); host.add(new EnumDependencySupport());
host.add(new AnnotationDependencySupport()); host.add(new AnnotationDependencySupport());
host.add(new PlatformDependencyListener()); host.add(new PlatformDependencyListener());
host.add(new AsyncDependencyListener());
TeaVMPluginUtil.handleNatives(host, Platform.class); TeaVMPluginUtil.handleNatives(host, Platform.class);
TeaVMPluginUtil.handleNatives(host, PlatformQueue.class); TeaVMPluginUtil.handleNatives(host, PlatformQueue.class);