mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Don't report compile-0time error when there's possible way to reach suspension point. Generate runtime error instead.
This commit is contained in:
parent
c28d9ef68d
commit
62b3c68a5b
|
@ -25,7 +25,6 @@ import org.teavm.interop.NoSideEffects;
|
||||||
import org.teavm.interop.Rename;
|
import org.teavm.interop.Rename;
|
||||||
import org.teavm.interop.Structure;
|
import org.teavm.interop.Structure;
|
||||||
import org.teavm.interop.Superclass;
|
import org.teavm.interop.Superclass;
|
||||||
import org.teavm.interop.Sync;
|
|
||||||
import org.teavm.interop.Unmanaged;
|
import org.teavm.interop.Unmanaged;
|
||||||
import org.teavm.jso.browser.TimerHandler;
|
import org.teavm.jso.browser.TimerHandler;
|
||||||
import org.teavm.platform.Platform;
|
import org.teavm.platform.Platform;
|
||||||
|
@ -141,12 +140,10 @@ public class TObject {
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@Sync
|
|
||||||
static void monitorExit(TObject o) {
|
static void monitorExit(TObject o) {
|
||||||
monitorExit(o, 1);
|
monitorExit(o, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@Sync
|
|
||||||
static void monitorExit(TObject o, int count) {
|
static void monitorExit(TObject o, int count) {
|
||||||
if (o.isEmptyMonitor() || o.monitor.owner != TThread.currentThread()) {
|
if (o.isEmptyMonitor() || o.monitor.owner != TThread.currentThread()) {
|
||||||
throw new TIllegalMonitorStateException();
|
throw new TIllegalMonitorStateException();
|
||||||
|
@ -353,7 +350,6 @@ public class TObject {
|
||||||
return copy;
|
return copy;
|
||||||
}
|
}
|
||||||
|
|
||||||
@Sync
|
|
||||||
@Rename("notify")
|
@Rename("notify")
|
||||||
public final void notify0() {
|
public final void notify0() {
|
||||||
if (!holdsLock(this)) {
|
if (!holdsLock(this)) {
|
||||||
|
@ -379,7 +375,6 @@ public class TObject {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Sync
|
|
||||||
@Rename("notifyAll")
|
@Rename("notifyAll")
|
||||||
public final void notifyAll0() {
|
public final void notifyAll0() {
|
||||||
if (!holdsLock(this)) {
|
if (!holdsLock(this)) {
|
||||||
|
|
|
@ -29,7 +29,6 @@ import org.teavm.classlib.java.util.TCollection;
|
||||||
import org.teavm.classlib.java.util.TIterator;
|
import org.teavm.classlib.java.util.TIterator;
|
||||||
import org.teavm.interop.Async;
|
import org.teavm.interop.Async;
|
||||||
import org.teavm.interop.AsyncCallback;
|
import org.teavm.interop.AsyncCallback;
|
||||||
import org.teavm.interop.Sync;
|
|
||||||
import org.teavm.platform.Platform;
|
import org.teavm.platform.Platform;
|
||||||
import org.teavm.platform.PlatformQueue;
|
import org.teavm.platform.PlatformQueue;
|
||||||
import org.teavm.platform.PlatformRunnable;
|
import org.teavm.platform.PlatformRunnable;
|
||||||
|
@ -392,7 +391,6 @@ public class TArrayBlockingQueue<E> extends TAbstractQueue<E> implements TBlocki
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Sync
|
|
||||||
private void addImpl(E e) {
|
private void addImpl(E e) {
|
||||||
array[tail++] = e;
|
array[tail++] = e;
|
||||||
if (tail == array.length) {
|
if (tail == array.length) {
|
||||||
|
@ -401,7 +399,6 @@ public class TArrayBlockingQueue<E> extends TAbstractQueue<E> implements TBlocki
|
||||||
notifyChange();
|
notifyChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
@Sync
|
|
||||||
private E removeImpl() {
|
private E removeImpl() {
|
||||||
@SuppressWarnings("unchecked")
|
@SuppressWarnings("unchecked")
|
||||||
E result = (E) array[head];
|
E result = (E) array[head];
|
||||||
|
|
|
@ -22,15 +22,11 @@ import java.util.HashSet;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
import java.util.Map;
|
import java.util.Map;
|
||||||
import java.util.Set;
|
import java.util.Set;
|
||||||
import org.teavm.backend.javascript.spi.InjectedBy;
|
|
||||||
import org.teavm.callgraph.CallGraph;
|
import org.teavm.callgraph.CallGraph;
|
||||||
import org.teavm.callgraph.CallGraphNode;
|
import org.teavm.callgraph.CallGraphNode;
|
||||||
import org.teavm.callgraph.CallSite;
|
import org.teavm.callgraph.CallSite;
|
||||||
import org.teavm.diagnostics.Diagnostics;
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
import org.teavm.interop.Async;
|
import org.teavm.interop.Async;
|
||||||
import org.teavm.interop.SuppressSyncErrors;
|
|
||||||
import org.teavm.interop.Sync;
|
|
||||||
import org.teavm.model.CallLocation;
|
|
||||||
import org.teavm.model.ClassReader;
|
import org.teavm.model.ClassReader;
|
||||||
import org.teavm.model.ElementModifier;
|
import org.teavm.model.ElementModifier;
|
||||||
import org.teavm.model.ListableClassReaderSource;
|
import org.teavm.model.ListableClassReaderSource;
|
||||||
|
@ -162,20 +158,6 @@ public class AsyncMethodFinder {
|
||||||
if (method == null) {
|
if (method == null) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
if (method.getAnnotations().get(Sync.class.getName()) != null
|
|
||||||
|| method.getAnnotations().get(InjectedBy.class.getName()) != null) {
|
|
||||||
if (method.getAnnotations().get(SuppressSyncErrors.class.getName()) == null) {
|
|
||||||
diagnostics.error(new CallLocation(methodRef), "Method {{m0}} is claimed to be "
|
|
||||||
+ "synchronous, but it is has invocations of asynchronous methods:"
|
|
||||||
+ stack.toString(), methodRef);
|
|
||||||
return;
|
|
||||||
} else {
|
|
||||||
diagnostics.warning(new CallLocation(methodRef), "Error as Warning because "
|
|
||||||
+ " Method {{m0}} has @SuppressSyncErrors annotation. Method {{m0}} "
|
|
||||||
+ "is claimed to be synchronous, but it is has invocations of "
|
|
||||||
+ "asynchronous methods:" + stack.toString(), methodRef);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
if (!hasAsyncMethods && methodRef.getClassName().equals("java.lang.Object")
|
if (!hasAsyncMethods && methodRef.getClassName().equals("java.lang.Object")
|
||||||
&& (methodRef.getName().equals("monitorEnter") || methodRef.getName().equals("monitorExit"))) {
|
&& (methodRef.getName().equals("monitorEnter") || methodRef.getName().equals("monitorExit"))) {
|
||||||
|
|
|
@ -97,7 +97,11 @@ function $rt_resuming() {
|
||||||
return thread != null && thread.isResuming();
|
return thread != null && thread.isResuming();
|
||||||
}
|
}
|
||||||
function $rt_suspend(callback) {
|
function $rt_suspend(callback) {
|
||||||
return $rt_nativeThread().suspend(callback);
|
var nativeThread = $rt_nativeThread();
|
||||||
|
if (nativeThread === null) {
|
||||||
|
throw new Error("Suspension point reached from non-threading context (perhaps, from native JS method).");
|
||||||
|
}
|
||||||
|
return nativeThread.suspend(callback);
|
||||||
}
|
}
|
||||||
function $rt_startThread(runner, callback) {
|
function $rt_startThread(runner, callback) {
|
||||||
new TeaVMThread(runner).start(callback);
|
new TeaVMThread(runner).start(callback);
|
||||||
|
|
|
@ -23,6 +23,7 @@ import java.lang.annotation.*;
|
||||||
*/
|
*/
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.METHOD)
|
@Target(ElementType.METHOD)
|
||||||
|
@Deprecated
|
||||||
public @interface SuppressSyncErrors {
|
public @interface SuppressSyncErrors {
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -20,5 +20,6 @@ import java.lang.annotation.*;
|
||||||
@Retention(RetentionPolicy.RUNTIME)
|
@Retention(RetentionPolicy.RUNTIME)
|
||||||
@Target(ElementType.METHOD)
|
@Target(ElementType.METHOD)
|
||||||
@Inherited
|
@Inherited
|
||||||
|
@Deprecated
|
||||||
public @interface Sync {
|
public @interface Sync {
|
||||||
}
|
}
|
||||||
|
|
|
@ -33,7 +33,6 @@ import org.teavm.backend.javascript.rendering.JSParser;
|
||||||
import org.teavm.cache.IncrementalDependencyRegistration;
|
import org.teavm.cache.IncrementalDependencyRegistration;
|
||||||
import org.teavm.diagnostics.Diagnostics;
|
import org.teavm.diagnostics.Diagnostics;
|
||||||
import org.teavm.interop.NoSideEffects;
|
import org.teavm.interop.NoSideEffects;
|
||||||
import org.teavm.interop.Sync;
|
|
||||||
import org.teavm.jso.JSBody;
|
import org.teavm.jso.JSBody;
|
||||||
import org.teavm.jso.JSByRef;
|
import org.teavm.jso.JSByRef;
|
||||||
import org.teavm.jso.JSFunctor;
|
import org.teavm.jso.JSFunctor;
|
||||||
|
@ -41,7 +40,6 @@ import org.teavm.jso.JSIndexer;
|
||||||
import org.teavm.jso.JSMethod;
|
import org.teavm.jso.JSMethod;
|
||||||
import org.teavm.jso.JSObject;
|
import org.teavm.jso.JSObject;
|
||||||
import org.teavm.jso.JSProperty;
|
import org.teavm.jso.JSProperty;
|
||||||
import org.teavm.model.AccessLevel;
|
|
||||||
import org.teavm.model.AnnotationContainerReader;
|
import org.teavm.model.AnnotationContainerReader;
|
||||||
import org.teavm.model.AnnotationHolder;
|
import org.teavm.model.AnnotationHolder;
|
||||||
import org.teavm.model.AnnotationReader;
|
import org.teavm.model.AnnotationReader;
|
||||||
|
@ -191,50 +189,6 @@ class JSClassProcessor {
|
||||||
.orElse(null);
|
.orElse(null);
|
||||||
}
|
}
|
||||||
|
|
||||||
void makeSync(ClassHolder cls) {
|
|
||||||
Set<MethodDescriptor> methods = new HashSet<>();
|
|
||||||
findInheritedMethods(cls, methods, new HashSet<>());
|
|
||||||
for (MethodHolder method : cls.getMethods()) {
|
|
||||||
if (methods.contains(method.getDescriptor())) {
|
|
||||||
makeSync(method);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
static void makeSync(MethodHolder method) {
|
|
||||||
if (method.getAnnotations().get(Sync.class.getName()) == null) {
|
|
||||||
AnnotationHolder annot = new AnnotationHolder(Sync.class.getName());
|
|
||||||
method.getAnnotations().add(annot);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void findInheritedMethods(ClassReader cls, Set<MethodDescriptor> methods, Set<String> visited) {
|
|
||||||
if (!visited.add(cls.getName())) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (typeHelper.isJavaScriptClass(cls.getName())) {
|
|
||||||
for (MethodReader method : cls.getMethods()) {
|
|
||||||
if (!method.hasModifier(ElementModifier.STATIC) && !method.hasModifier(ElementModifier.FINAL)
|
|
||||||
&& method.getLevel() != AccessLevel.PRIVATE) {
|
|
||||||
methods.add(method.getDescriptor());
|
|
||||||
}
|
|
||||||
}
|
|
||||||
} else if (typeHelper.isJavaScriptImplementation(cls.getName())) {
|
|
||||||
if (cls.getParent() != null) {
|
|
||||||
ClassReader parentCls = classSource.get(cls.getParent());
|
|
||||||
if (parentCls != null) {
|
|
||||||
findInheritedMethods(parentCls, methods, visited);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
for (String iface : cls.getInterfaces()) {
|
|
||||||
ClassReader parentCls = classSource.get(iface);
|
|
||||||
if (parentCls != null) {
|
|
||||||
findInheritedMethods(parentCls, methods, visited);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private static ValueType[] getStaticSignature(MethodReference method) {
|
private static ValueType[] getStaticSignature(MethodReference method) {
|
||||||
ValueType[] signature = method.getSignature();
|
ValueType[] signature = method.getSignature();
|
||||||
ValueType[] staticSignature = new ValueType[signature.length + 1];
|
ValueType[] staticSignature = new ValueType[signature.length + 1];
|
||||||
|
|
|
@ -73,9 +73,6 @@ class JSObjectClassTransformer implements ClassHolderTransformer {
|
||||||
if (typeHelper.isJavaScriptClass(cls.getName())) {
|
if (typeHelper.isJavaScriptClass(cls.getName())) {
|
||||||
processor.processMemberMethods(cls);
|
processor.processMemberMethods(cls);
|
||||||
}
|
}
|
||||||
if (typeHelper.isJavaScriptImplementation(cls.getName())) {
|
|
||||||
processor.makeSync(cls);
|
|
||||||
}
|
|
||||||
|
|
||||||
for (MethodHolder method : cls.getMethods().toArray(new MethodHolder[0])) {
|
for (MethodHolder method : cls.getMethods().toArray(new MethodHolder[0])) {
|
||||||
if (method.getProgram() != null) {
|
if (method.getProgram() != null) {
|
||||||
|
@ -156,8 +153,6 @@ class JSObjectClassTransformer implements ClassHolderTransformer {
|
||||||
basicBlock.add(exit);
|
basicBlock.add(exit);
|
||||||
|
|
||||||
classHolder.addMethod(exportedMethod);
|
classHolder.addMethod(exportedMethod);
|
||||||
MethodHolder methodToCall = classHolder.getMethod(method);
|
|
||||||
JSClassProcessor.makeSync(methodToCall != null ? methodToCall : exportedMethod);
|
|
||||||
|
|
||||||
String publicAlias = classToExpose.methods.get(method);
|
String publicAlias = classToExpose.methods.get(method);
|
||||||
AnnotationHolder annot = new AnnotationHolder(JSMethodToExpose.class.getName());
|
AnnotationHolder annot = new AnnotationHolder(JSMethodToExpose.class.getName());
|
||||||
|
|
Loading…
Reference in New Issue
Block a user