mirror of
https://github.com/Eaglercraft-TeaVM-Fork/eagler-teavm.git
synced 2024-12-22 16:14:10 -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.ArrayList;
|
||||||
import java.util.Arrays;
|
import java.util.Arrays;
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.teavm.model.AccessLevel;
|
||||||
import org.teavm.model.BasicBlockReader;
|
import org.teavm.model.BasicBlockReader;
|
||||||
import org.teavm.model.CallLocation;
|
import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.ClassHierarchy;
|
import org.teavm.model.ClassHierarchy;
|
||||||
|
@ -31,6 +32,7 @@ import org.teavm.model.ElementModifier;
|
||||||
import org.teavm.model.IncomingReader;
|
import org.teavm.model.IncomingReader;
|
||||||
import org.teavm.model.MethodDescriptor;
|
import org.teavm.model.MethodDescriptor;
|
||||||
import org.teavm.model.MethodHolder;
|
import org.teavm.model.MethodHolder;
|
||||||
|
import org.teavm.model.MethodReader;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
import org.teavm.model.PhiReader;
|
import org.teavm.model.PhiReader;
|
||||||
import org.teavm.model.Program;
|
import org.teavm.model.Program;
|
||||||
|
@ -368,6 +370,15 @@ class DependencyGraphBuilder {
|
||||||
@Override
|
@Override
|
||||||
protected void invokeVirtual(VariableReader receiver, VariableReader instance, MethodReference method,
|
protected void invokeVirtual(VariableReader receiver, VariableReader instance, MethodReference method,
|
||||||
List<? extends VariableReader> arguments) {
|
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)) {
|
if (handleSpecialMethod(receiver, instance, method)) {
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
@ -377,7 +388,7 @@ class DependencyGraphBuilder {
|
||||||
actualArgs[i + 1] = nodes[arguments.get(i).getIndex()];
|
actualArgs[i + 1] = nodes[arguments.get(i).getIndex()];
|
||||||
}
|
}
|
||||||
actualArgs[0] = getNode(instance);
|
actualArgs[0] = getNode(instance);
|
||||||
DependencyConsumer listener = new VirtualCallConsumer(getNode(instance),
|
DependencyConsumer listener = new VirtualCallConsumer(
|
||||||
method.getClassName(), method.getDescriptor(), dependencyAnalyzer, actualArgs,
|
method.getClassName(), method.getDescriptor(), dependencyAnalyzer, actualArgs,
|
||||||
receiver != null ? getNode(receiver) : null, getCallLocation(),
|
receiver != null ? getNode(receiver) : null, getCallLocation(),
|
||||||
currentExceptionConsumer);
|
currentExceptionConsumer);
|
||||||
|
|
|
@ -16,7 +16,10 @@
|
||||||
package org.teavm.dependency;
|
package org.teavm.dependency;
|
||||||
|
|
||||||
import java.util.List;
|
import java.util.List;
|
||||||
|
import org.teavm.model.AccessLevel;
|
||||||
import org.teavm.model.CallLocation;
|
import org.teavm.model.CallLocation;
|
||||||
|
import org.teavm.model.ClassReader;
|
||||||
|
import org.teavm.model.MethodReader;
|
||||||
import org.teavm.model.MethodReference;
|
import org.teavm.model.MethodReference;
|
||||||
import org.teavm.model.VariableReader;
|
import org.teavm.model.VariableReader;
|
||||||
|
|
||||||
|
@ -46,6 +49,14 @@ class FastInstructionAnalyzer extends AbstractInstructionAnalyzer {
|
||||||
@Override
|
@Override
|
||||||
protected void invokeVirtual(VariableReader receiver, VariableReader instance, MethodReference method,
|
protected void invokeVirtual(VariableReader receiver, VariableReader instance, MethodReference method,
|
||||||
List<? extends VariableReader> arguments) {
|
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);
|
invokeGetClass(method);
|
||||||
FastVirtualCallConsumer consumer = dependencyAnalyzer.getVirtualCallConsumer(method);
|
FastVirtualCallConsumer consumer = dependencyAnalyzer.getVirtualCallConsumer(method);
|
||||||
consumer.addLocation(impreciseLocation);
|
consumer.addLocation(impreciseLocation);
|
||||||
|
|
|
@ -20,7 +20,6 @@ import org.teavm.model.CallLocation;
|
||||||
import org.teavm.model.MethodDescriptor;
|
import org.teavm.model.MethodDescriptor;
|
||||||
|
|
||||||
class VirtualCallConsumer implements DependencyConsumer {
|
class VirtualCallConsumer implements DependencyConsumer {
|
||||||
private final DependencyNode node;
|
|
||||||
private final MethodDescriptor methodDesc;
|
private final MethodDescriptor methodDesc;
|
||||||
private final DependencyAnalyzer analyzer;
|
private final DependencyAnalyzer analyzer;
|
||||||
private final DependencyNode[] parameters;
|
private final DependencyNode[] parameters;
|
||||||
|
@ -32,11 +31,9 @@ class VirtualCallConsumer implements DependencyConsumer {
|
||||||
private boolean isPolymorphic;
|
private boolean isPolymorphic;
|
||||||
private MethodDependency monomorphicCall;
|
private MethodDependency monomorphicCall;
|
||||||
|
|
||||||
VirtualCallConsumer(DependencyNode node, String filterClass,
|
VirtualCallConsumer(String filterClass, MethodDescriptor methodDesc, DependencyAnalyzer analyzer,
|
||||||
MethodDescriptor methodDesc, DependencyAnalyzer analyzer, DependencyNode[] parameters,
|
DependencyNode[] parameters, DependencyNode result, CallLocation location,
|
||||||
DependencyNode result, CallLocation location,
|
|
||||||
DependencyGraphBuilder.ExceptionConsumer exceptionConsumer) {
|
DependencyGraphBuilder.ExceptionConsumer exceptionConsumer) {
|
||||||
this.node = node;
|
|
||||||
this.filter = analyzer.getSuperClassFilter(filterClass);
|
this.filter = analyzer.getSuperClassFilter(filterClass);
|
||||||
this.methodDesc = methodDesc;
|
this.methodDesc = methodDesc;
|
||||||
this.analyzer = analyzer;
|
this.analyzer = analyzer;
|
||||||
|
|
|
@ -634,4 +634,29 @@ public class VMTest {
|
||||||
}
|
}
|
||||||
return result;
|
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