diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java index 8ca881bd5..dbaf4aa14 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyChecker.java @@ -252,6 +252,10 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { if (methodRef == null) { throw new IllegalArgumentException(); } + MethodReader methodReader = methodReaderCache.map(methodRef); + if (methodReader != null) { + methodRef = methodReader.getReference(); + } callGraph.getNode(methodRef); boolean added = true; if (callLocation != null && callLocation.getMethod() != null) { @@ -472,6 +476,12 @@ public class DependencyChecker implements DependencyInfo, DependencyAgent { return methodCache.getKnown(methodRef); } + @Override + public MethodDependency getMethodImplementation(MethodReference methodRef) { + MethodReader method = methodReaderCache.map(methodRef); + return method != null ? methodCache.getKnown(method.getReference()) : null; + } + public void processDependencies() { interrupted = false; int index = 0; diff --git a/teavm-core/src/main/java/org/teavm/dependency/DependencyInfo.java b/teavm-core/src/main/java/org/teavm/dependency/DependencyInfo.java index c2a8916e3..fd0c9b19b 100644 --- a/teavm-core/src/main/java/org/teavm/dependency/DependencyInfo.java +++ b/teavm-core/src/main/java/org/teavm/dependency/DependencyInfo.java @@ -40,6 +40,8 @@ public interface DependencyInfo { MethodDependencyInfo getMethod(MethodReference methodRef); + MethodDependencyInfo getMethodImplementation(MethodReference methodRef); + ClassDependencyInfo getClass(String className); CallGraph getCallGraph(); diff --git a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java index 9567a7060..33d3c3311 100644 --- a/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java +++ b/teavm-core/src/main/java/org/teavm/javascript/Decompiler.java @@ -46,14 +46,15 @@ public class Decompiler { private Set methodsToPass = new HashSet<>(); private RegularMethodNodeCache regularMethodCache; private Set asyncMethods; - private Set asyncFamilyMethods; + private Set splitMethods = new HashSet<>(); public Decompiler(ClassHolderSource classSource, ClassLoader classLoader, Set asyncMethods, Set asyncFamilyMethods) { this.classSource = classSource; this.classLoader = classLoader; this.asyncMethods = asyncMethods; - this.asyncFamilyMethods = asyncFamilyMethods; + splitMethods.addAll(asyncMethods); + splitMethods.addAll(asyncFamilyMethods); } public RegularMethodNodeCache getRegularMethodCache() { @@ -199,10 +200,7 @@ public class Decompiler { public AsyncMethodNode decompileAsync(MethodHolder method) { AsyncMethodNode node = new AsyncMethodNode(method.getReference()); - Set splitMethods = new HashSet<>(); - splitMethods.addAll(asyncMethods); - splitMethods.addAll(asyncFamilyMethods); - AsyncProgramSplitter splitter = new AsyncProgramSplitter(splitMethods); + AsyncProgramSplitter splitter = new AsyncProgramSplitter(classSource, splitMethods); splitter.split(method.getProgram()); for (int i = 0; i < splitter.size(); ++i) { Integer input = null; diff --git a/teavm-core/src/main/java/org/teavm/model/util/AsyncProgramSplitter.java b/teavm-core/src/main/java/org/teavm/model/util/AsyncProgramSplitter.java index 16c02e49d..a657c2c45 100644 --- a/teavm-core/src/main/java/org/teavm/model/util/AsyncProgramSplitter.java +++ b/teavm-core/src/main/java/org/teavm/model/util/AsyncProgramSplitter.java @@ -28,9 +28,11 @@ import org.teavm.model.instructions.MonitorEnterInstruction; public class AsyncProgramSplitter { private List parts = new ArrayList<>(); private Map partMap = new HashMap<>(); + private ClassReaderSource classSource; private Set asyncMethods = new HashSet<>(); - public AsyncProgramSplitter(Set asyncMethods) { + public AsyncProgramSplitter(ClassReaderSource classSource, Set asyncMethods) { + this.classSource = classSource; this.asyncMethods = asyncMethods; } @@ -62,7 +64,7 @@ public class AsyncProgramSplitter { Integer receiver; if (insn instanceof InvokeInstruction) { InvokeInstruction invoke = (InvokeInstruction)insn; - if (!asyncMethods.contains(invoke.getMethod())) { + if (!asyncMethods.contains(findRealMethod(invoke.getMethod()))) { continue; } receiver = invoke.getReceiver() != null ? invoke.getReceiver().getIndex() : null; @@ -148,6 +150,25 @@ public class AsyncProgramSplitter { partMap.clear(); } + private MethodReference findRealMethod(MethodReference method) { + String clsName = method.getClassName(); + while (clsName != null) { + ClassReader cls = classSource.get(clsName); + if (cls == null) { + break; + } + MethodReader methodReader = cls.getMethod(method.getDescriptor()); + if (methodReader != null) { + return new MethodReference(clsName, method.getDescriptor()); + } + clsName = cls.getParent(); + if (clsName != null && clsName.equals(cls.getName())) { + break; + } + } + return method; + } + private Program createStubCopy(Program program) { Program copy = new Program(); for (int i = 0; i < program.basicBlockCount(); ++i) { diff --git a/teavm-core/src/main/java/org/teavm/optimization/Devirtualization.java b/teavm-core/src/main/java/org/teavm/optimization/Devirtualization.java index f031a9650..994a77b67 100644 --- a/teavm-core/src/main/java/org/teavm/optimization/Devirtualization.java +++ b/teavm-core/src/main/java/org/teavm/optimization/Devirtualization.java @@ -74,7 +74,8 @@ public class Devirtualization { if (cls == null || !isAssignable(ref.getClassName(), cls)) { continue; } - MethodDependencyInfo methodDep = dependency.getMethod(new MethodReference(className, ref.getDescriptor())); + MethodDependencyInfo methodDep = dependency.getMethodImplementation(new MethodReference( + className, ref.getDescriptor())); if (methodDep != null) { methods.add(methodDep.getReference()); } diff --git a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js index 92fd02fc9..40ee7774d 100644 --- a/teavm-core/src/main/resources/org/teavm/javascript/runtime.js +++ b/teavm-core/src/main/resources/org/teavm/javascript/runtime.js @@ -558,6 +558,9 @@ function $rt_guardAsync(f, continuation) { function TeaVMAsyncError(cause) { this.message = "Async error occured"; this.cause = cause; + if (cause) { + this.$javaException = cause.$javaException; + } } TeaVMAsyncError.prototype = new Error(); TeaVMAsyncError.prototype.constructor = TeaVMAsyncError;