mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 08:14:09 -08:00
Fix private method call resolution in Java 11
This commit is contained in:
parent
5fb83ca2ac
commit
1fb70b0903
|
@ -22,6 +22,7 @@ import static org.teavm.dependency.AbstractInstructionAnalyzer.MONITOR_EXIT_SYNC
|
|||
import java.util.ArrayList;
|
||||
import java.util.Arrays;
|
||||
import java.util.List;
|
||||
import org.teavm.model.AccessLevel;
|
||||
import org.teavm.model.BasicBlockReader;
|
||||
import org.teavm.model.CallLocation;
|
||||
import org.teavm.model.ClassHierarchy;
|
||||
|
@ -31,6 +32,7 @@ import org.teavm.model.ElementModifier;
|
|||
import org.teavm.model.IncomingReader;
|
||||
import org.teavm.model.MethodDescriptor;
|
||||
import org.teavm.model.MethodHolder;
|
||||
import org.teavm.model.MethodReader;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.PhiReader;
|
||||
import org.teavm.model.Program;
|
||||
|
@ -368,6 +370,15 @@ class DependencyGraphBuilder {
|
|||
@Override
|
||||
protected void invokeVirtual(VariableReader receiver, VariableReader instance, MethodReference method,
|
||||
List<? extends VariableReader> arguments) {
|
||||
ClassReader cls = dependencyAnalyzer.getClassSource().get(method.getClassName());
|
||||
if (cls != null) {
|
||||
MethodReader methodHolder = cls.getMethod(method.getDescriptor());
|
||||
if (methodHolder != null && methodHolder.getLevel() == AccessLevel.PRIVATE) {
|
||||
invokeSpecial(receiver, instance, method, arguments);
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
if (handleSpecialMethod(receiver, instance, method)) {
|
||||
return;
|
||||
}
|
||||
|
@ -377,7 +388,7 @@ class DependencyGraphBuilder {
|
|||
actualArgs[i + 1] = nodes[arguments.get(i).getIndex()];
|
||||
}
|
||||
actualArgs[0] = getNode(instance);
|
||||
DependencyConsumer listener = new VirtualCallConsumer(getNode(instance),
|
||||
DependencyConsumer listener = new VirtualCallConsumer(
|
||||
method.getClassName(), method.getDescriptor(), dependencyAnalyzer, actualArgs,
|
||||
receiver != null ? getNode(receiver) : null, getCallLocation(),
|
||||
currentExceptionConsumer);
|
||||
|
|
|
@ -16,7 +16,10 @@
|
|||
package org.teavm.dependency;
|
||||
|
||||
import java.util.List;
|
||||
import org.teavm.model.AccessLevel;
|
||||
import org.teavm.model.CallLocation;
|
||||
import org.teavm.model.ClassReader;
|
||||
import org.teavm.model.MethodReader;
|
||||
import org.teavm.model.MethodReference;
|
||||
import org.teavm.model.VariableReader;
|
||||
|
||||
|
@ -46,6 +49,14 @@ class FastInstructionAnalyzer extends AbstractInstructionAnalyzer {
|
|||
@Override
|
||||
protected void invokeVirtual(VariableReader receiver, VariableReader instance, MethodReference method,
|
||||
List<? extends VariableReader> arguments) {
|
||||
ClassReader cls = dependencyAnalyzer.getClassSource().get(method.getClassName());
|
||||
if (cls != null) {
|
||||
MethodReader methodHolder = cls.getMethod(method.getDescriptor());
|
||||
if (methodHolder != null && methodHolder.getLevel() == AccessLevel.PRIVATE) {
|
||||
invokeSpecial(receiver, instance, method, arguments);
|
||||
return;
|
||||
}
|
||||
}
|
||||
invokeGetClass(method);
|
||||
FastVirtualCallConsumer consumer = dependencyAnalyzer.getVirtualCallConsumer(method);
|
||||
consumer.addLocation(impreciseLocation);
|
||||
|
|
|
@ -20,7 +20,6 @@ import org.teavm.model.CallLocation;
|
|||
import org.teavm.model.MethodDescriptor;
|
||||
|
||||
class VirtualCallConsumer implements DependencyConsumer {
|
||||
private final DependencyNode node;
|
||||
private final MethodDescriptor methodDesc;
|
||||
private final DependencyAnalyzer analyzer;
|
||||
private final DependencyNode[] parameters;
|
||||
|
@ -32,11 +31,9 @@ class VirtualCallConsumer implements DependencyConsumer {
|
|||
private boolean isPolymorphic;
|
||||
private MethodDependency monomorphicCall;
|
||||
|
||||
VirtualCallConsumer(DependencyNode node, String filterClass,
|
||||
MethodDescriptor methodDesc, DependencyAnalyzer analyzer, DependencyNode[] parameters,
|
||||
DependencyNode result, CallLocation location,
|
||||
VirtualCallConsumer(String filterClass, MethodDescriptor methodDesc, DependencyAnalyzer analyzer,
|
||||
DependencyNode[] parameters, DependencyNode result, CallLocation location,
|
||||
DependencyGraphBuilder.ExceptionConsumer exceptionConsumer) {
|
||||
this.node = node;
|
||||
this.filter = analyzer.getSuperClassFilter(filterClass);
|
||||
this.methodDesc = methodDesc;
|
||||
this.analyzer = analyzer;
|
||||
|
|
|
@ -634,4 +634,29 @@ public class VMTest {
|
|||
}
|
||||
return result;
|
||||
}
|
||||
|
||||
@Test
|
||||
public void virtualCallWithPrivateMethods() {
|
||||
assertEquals("ap", callA(new B()));
|
||||
}
|
||||
|
||||
private static String callA(A a) {
|
||||
return a.a();
|
||||
}
|
||||
|
||||
static class A {
|
||||
String a() {
|
||||
return "a" + p();
|
||||
}
|
||||
|
||||
private String p() {
|
||||
return "p";
|
||||
}
|
||||
}
|
||||
|
||||
static class B extends A {
|
||||
private String p() {
|
||||
return "q";
|
||||
}
|
||||
}
|
||||
}
|
Loading…
Reference in New Issue
Block a user