mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8244090: public lookup should find public members of public exported types
Reviewed-by: lfoltan, psandoz
This commit is contained in:
parent
49a9d49dbd
commit
4e6a4af186
24 changed files with 369 additions and 75 deletions
|
@ -28,7 +28,7 @@ package java.lang.invoke;
|
|||
import java.util.Arrays;
|
||||
import static java.lang.invoke.LambdaForm.*;
|
||||
import static java.lang.invoke.LambdaForm.Kind.*;
|
||||
import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeVirtual;
|
||||
import static java.lang.invoke.MethodHandleNatives.Constants.*;
|
||||
import static java.lang.invoke.MethodHandleStatics.*;
|
||||
|
||||
/**
|
||||
|
@ -177,7 +177,7 @@ abstract class DelegatingMethodHandle extends MethodHandle {
|
|||
MethodType.methodType(MethodHandle.class), REF_invokeVirtual);
|
||||
NF_getTarget = new NamedFunction(
|
||||
MemberName.getFactory()
|
||||
.resolveOrFail(REF_invokeVirtual, member, DelegatingMethodHandle.class, NoSuchMethodException.class));
|
||||
.resolveOrFail(REF_invokeVirtual, member, DelegatingMethodHandle.class, LM_TRUSTED, NoSuchMethodException.class));
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw newInternalError(ex);
|
||||
}
|
||||
|
|
|
@ -63,7 +63,7 @@ class DirectMethodHandle extends MethodHandle {
|
|||
member.isMethod() && !member.isAbstract()) {
|
||||
// Check for corner case: invokeinterface of Object method
|
||||
MemberName m = new MemberName(Object.class, member.getName(), member.getMethodType(), member.getReferenceKind());
|
||||
m = MemberName.getFactory().resolveOrNull(m.getReferenceKind(), m, null);
|
||||
m = MemberName.getFactory().resolveOrNull(m.getReferenceKind(), m, null, LM_TRUSTED);
|
||||
if (m != null && m.isPublic()) {
|
||||
assert(member.getReferenceKind() == m.getReferenceKind()); // else this.form is wrong
|
||||
member = m;
|
||||
|
@ -260,7 +260,8 @@ class DirectMethodHandle extends MethodHandle {
|
|||
.changeReturnType(void.class); // <init> returns void
|
||||
MemberName linker = new MemberName(MethodHandle.class, linkerName, mtypeWithArg, REF_invokeStatic);
|
||||
try {
|
||||
linker = IMPL_NAMES.resolveOrFail(REF_invokeStatic, linker, null, NoSuchMethodException.class);
|
||||
linker = IMPL_NAMES.resolveOrFail(REF_invokeStatic, linker, null, LM_TRUSTED,
|
||||
NoSuchMethodException.class);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw newInternalError(ex);
|
||||
}
|
||||
|
@ -771,7 +772,8 @@ class DirectMethodHandle extends MethodHandle {
|
|||
linkerType = MethodType.methodType(void.class, Object.class, long.class, ft);
|
||||
MemberName linker = new MemberName(Unsafe.class, kind.methodName, linkerType, REF_invokeVirtual);
|
||||
try {
|
||||
linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, NoSuchMethodException.class);
|
||||
linker = IMPL_NAMES.resolveOrFail(REF_invokeVirtual, linker, null, LM_TRUSTED,
|
||||
NoSuchMethodException.class);
|
||||
} catch (ReflectiveOperationException ex) {
|
||||
throw newInternalError(ex);
|
||||
}
|
||||
|
@ -914,13 +916,15 @@ class DirectMethodHandle extends MethodHandle {
|
|||
case NF_UNSAFE:
|
||||
MemberName member = new MemberName(MethodHandleStatics.class, "UNSAFE", Unsafe.class, REF_getField);
|
||||
return new NamedFunction(
|
||||
MemberName.getFactory()
|
||||
.resolveOrFail(REF_getField, member, DirectMethodHandle.class, NoSuchMethodException.class));
|
||||
MemberName.getFactory().resolveOrFail(REF_getField, member,
|
||||
DirectMethodHandle.class, LM_TRUSTED,
|
||||
NoSuchMethodException.class));
|
||||
case NF_checkReceiver:
|
||||
member = new MemberName(DirectMethodHandle.class, "checkReceiver", OBJ_OBJ_TYPE, REF_invokeVirtual);
|
||||
return new NamedFunction(
|
||||
MemberName.getFactory()
|
||||
.resolveOrFail(REF_invokeVirtual, member, DirectMethodHandle.class, NoSuchMethodException.class));
|
||||
MemberName.getFactory().resolveOrFail(REF_invokeVirtual, member,
|
||||
DirectMethodHandle.class, LM_TRUSTED,
|
||||
NoSuchMethodException.class));
|
||||
default:
|
||||
throw newInternalError("Unknown function: " + func);
|
||||
}
|
||||
|
@ -934,8 +938,9 @@ class DirectMethodHandle extends MethodHandle {
|
|||
{
|
||||
MemberName member = new MemberName(DirectMethodHandle.class, name, type, REF_invokeStatic);
|
||||
return new NamedFunction(
|
||||
MemberName.getFactory()
|
||||
.resolveOrFail(REF_invokeStatic, member, DirectMethodHandle.class, NoSuchMethodException.class));
|
||||
MemberName.getFactory().resolveOrFail(REF_invokeStatic, member,
|
||||
DirectMethodHandle.class, LM_TRUSTED,
|
||||
NoSuchMethodException.class));
|
||||
}
|
||||
|
||||
static {
|
||||
|
|
|
@ -322,7 +322,9 @@ class InvokerBytecodeGenerator {
|
|||
private static MemberName resolveInvokerMember(Class<?> invokerClass, String name, MethodType type) {
|
||||
MemberName member = new MemberName(invokerClass, name, type, REF_invokeStatic);
|
||||
try {
|
||||
member = MEMBERNAME_FACTORY.resolveOrFail(REF_invokeStatic, member, HOST_CLASS, ReflectiveOperationException.class);
|
||||
member = MEMBERNAME_FACTORY.resolveOrFail(REF_invokeStatic, member,
|
||||
HOST_CLASS, LM_TRUSTED,
|
||||
ReflectiveOperationException.class);
|
||||
} catch (ReflectiveOperationException e) {
|
||||
throw newInternalError(e);
|
||||
}
|
||||
|
@ -693,7 +695,7 @@ class InvokerBytecodeGenerator {
|
|||
|
||||
private static MemberName resolveFrom(String name, MethodType type, Class<?> holder) {
|
||||
MemberName member = new MemberName(holder, name, type, REF_invokeStatic);
|
||||
MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, holder);
|
||||
MemberName resolvedMember = MemberName.getFactory().resolveOrNull(REF_invokeStatic, member, holder, LM_TRUSTED);
|
||||
if (TRACE_RESOLVE) {
|
||||
System.out.println("[LF_RESOLVE] " + holder.getName() + " " + name + " " +
|
||||
shortenSignature(basicTypeSignature(type)) + (resolvedMember != null ? " (success)" : " (fail)") );
|
||||
|
|
|
@ -661,7 +661,7 @@ class Invokers {
|
|||
MemberName member = new MemberName(Invokers.class, name, type, REF_invokeStatic);
|
||||
return new NamedFunction(
|
||||
MemberName.getFactory()
|
||||
.resolveOrFail(REF_invokeStatic, member, Invokers.class, NoSuchMethodException.class));
|
||||
.resolveOrFail(REF_invokeStatic, member, Invokers.class, LM_TRUSTED, NoSuchMethodException.class));
|
||||
}
|
||||
|
||||
private static class Lazy {
|
||||
|
|
|
@ -40,7 +40,7 @@ import java.util.Arrays;
|
|||
import java.util.HashMap;
|
||||
|
||||
import static java.lang.invoke.LambdaForm.BasicType.*;
|
||||
import static java.lang.invoke.MethodHandleNatives.Constants.REF_invokeStatic;
|
||||
import static java.lang.invoke.MethodHandleNatives.Constants.*;
|
||||
import static java.lang.invoke.MethodHandleStatics.*;
|
||||
|
||||
/**
|
||||
|
@ -1758,10 +1758,10 @@ class LambdaForm {
|
|||
MemberName idMem = new MemberName(LambdaForm.class, "identity_"+btChar, idType, REF_invokeStatic);
|
||||
MemberName zeMem = null;
|
||||
try {
|
||||
idMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, idMem, null, NoSuchMethodException.class);
|
||||
idMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, idMem, null, LM_TRUSTED, NoSuchMethodException.class);
|
||||
if (!isVoid) {
|
||||
zeMem = new MemberName(LambdaForm.class, "zero_"+btChar, zeType, REF_invokeStatic);
|
||||
zeMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, zeMem, null, NoSuchMethodException.class);
|
||||
zeMem = IMPL_NAMES.resolveOrFail(REF_invokeStatic, zeMem, null, LM_TRUSTED, NoSuchMethodException.class);
|
||||
}
|
||||
} catch (IllegalAccessException|NoSuchMethodException ex) {
|
||||
throw newInternalError(ex);
|
||||
|
|
|
@ -1064,7 +1064,7 @@ final class MemberName implements Member, Cloneable {
|
|||
* If lookup fails or access is not permitted, null is returned.
|
||||
* Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
|
||||
*/
|
||||
private MemberName resolve(byte refKind, MemberName ref, Class<?> lookupClass,
|
||||
private MemberName resolve(byte refKind, MemberName ref, Class<?> lookupClass, int allowedModes,
|
||||
boolean speculativeResolve) {
|
||||
MemberName m = ref.clone(); // JVM will side-effect the ref
|
||||
assert(refKind == m.getReferenceKind());
|
||||
|
@ -1084,7 +1084,7 @@ final class MemberName implements Member, Cloneable {
|
|||
//
|
||||
// REFC view on PTYPES doesn't matter, since it is used only as a starting point for resolution and doesn't
|
||||
// participate in method selection.
|
||||
m = MethodHandleNatives.resolve(m, lookupClass, speculativeResolve);
|
||||
m = MethodHandleNatives.resolve(m, lookupClass, allowedModes, speculativeResolve);
|
||||
if (m == null && speculativeResolve) {
|
||||
return null;
|
||||
}
|
||||
|
@ -1108,10 +1108,12 @@ final class MemberName implements Member, Cloneable {
|
|||
* Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
|
||||
*/
|
||||
public <NoSuchMemberException extends ReflectiveOperationException>
|
||||
MemberName resolveOrFail(byte refKind, MemberName m, Class<?> lookupClass,
|
||||
Class<NoSuchMemberException> nsmClass)
|
||||
MemberName resolveOrFail(byte refKind, MemberName m,
|
||||
Class<?> lookupClass, int allowedModes,
|
||||
Class<NoSuchMemberException> nsmClass)
|
||||
throws IllegalAccessException, NoSuchMemberException {
|
||||
MemberName result = resolve(refKind, m, lookupClass, false);
|
||||
assert lookupClass != null || allowedModes == LM_TRUSTED;
|
||||
MemberName result = resolve(refKind, m, lookupClass, allowedModes, false);
|
||||
if (result.isResolved())
|
||||
return result;
|
||||
ReflectiveOperationException ex = result.makeAccessException();
|
||||
|
@ -1124,8 +1126,9 @@ final class MemberName implements Member, Cloneable {
|
|||
* If lookup fails or access is not permitted, return null.
|
||||
* Otherwise a fresh copy of the given member is returned, with modifier bits filled in.
|
||||
*/
|
||||
public MemberName resolveOrNull(byte refKind, MemberName m, Class<?> lookupClass) {
|
||||
MemberName result = resolve(refKind, m, lookupClass, true);
|
||||
public MemberName resolveOrNull(byte refKind, MemberName m, Class<?> lookupClass, int allowedModes) {
|
||||
assert lookupClass != null || allowedModes == LM_TRUSTED;
|
||||
MemberName result = resolve(refKind, m, lookupClass, allowedModes, true);
|
||||
if (result != null && result.isResolved())
|
||||
return result;
|
||||
return null;
|
||||
|
|
|
@ -51,7 +51,7 @@ class MethodHandleNatives {
|
|||
|
||||
static native void init(MemberName self, Object ref);
|
||||
static native void expand(MemberName self);
|
||||
static native MemberName resolve(MemberName self, Class<?> caller,
|
||||
static native MemberName resolve(MemberName self, Class<?> caller, int lookupMode,
|
||||
boolean speculativeResolve) throws LinkageError, ClassNotFoundException;
|
||||
static native int getMembers(Class<?> defc, String matchName, String matchSig,
|
||||
int matchFlags, Class<?> caller, int skip, MemberName[] results);
|
||||
|
@ -149,6 +149,15 @@ class MethodHandleNatives {
|
|||
HIDDEN_CLASS = 0x00000002,
|
||||
STRONG_LOADER_LINK = 0x00000004,
|
||||
ACCESS_VM_ANNOTATIONS = 0x00000008;
|
||||
|
||||
/**
|
||||
* Lookup modes
|
||||
*/
|
||||
static final int
|
||||
LM_MODULE = Lookup.MODULE,
|
||||
LM_UNCONDITIONAL = Lookup.UNCONDITIONAL,
|
||||
LM_TRUSTED = -1;
|
||||
|
||||
}
|
||||
|
||||
static boolean refKindIsValid(int refKind) {
|
||||
|
@ -561,7 +570,7 @@ class MethodHandleNatives {
|
|||
guardType, REF_invokeStatic);
|
||||
|
||||
linker = MemberName.getFactory().resolveOrNull(REF_invokeStatic, linker,
|
||||
VarHandleGuards.class);
|
||||
VarHandleGuards.class, LM_TRUSTED);
|
||||
if (linker != null) {
|
||||
return linker;
|
||||
}
|
||||
|
|
|
@ -1409,14 +1409,7 @@ public class MethodHandles {
|
|||
|
||||
// This is just for calling out to MethodHandleImpl.
|
||||
private Class<?> lookupClassOrNull() {
|
||||
if (allowedModes == TRUSTED) {
|
||||
return null;
|
||||
}
|
||||
if (allowedModes == UNCONDITIONAL) {
|
||||
// use Object as the caller to pass to VM doing resolution
|
||||
return Object.class;
|
||||
}
|
||||
return lookupClass;
|
||||
return (allowedModes == TRUSTED) ? null : lookupClass;
|
||||
}
|
||||
|
||||
/** Tells which access-protection classes of members this lookup object can produce.
|
||||
|
@ -3442,7 +3435,7 @@ return mh1;
|
|||
checkSymbolicClass(refc); // do this before attempting to resolve
|
||||
Objects.requireNonNull(name);
|
||||
Objects.requireNonNull(type);
|
||||
return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(),
|
||||
return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), allowedModes,
|
||||
NoSuchFieldException.class);
|
||||
}
|
||||
|
||||
|
@ -3451,7 +3444,7 @@ return mh1;
|
|||
Objects.requireNonNull(name);
|
||||
Objects.requireNonNull(type);
|
||||
checkMethodName(refKind, name); // NPE check on name
|
||||
return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(),
|
||||
return IMPL_NAMES.resolveOrFail(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), allowedModes,
|
||||
NoSuchMethodException.class);
|
||||
}
|
||||
|
||||
|
@ -3459,7 +3452,7 @@ return mh1;
|
|||
checkSymbolicClass(member.getDeclaringClass()); // do this before attempting to resolve
|
||||
Objects.requireNonNull(member.getName());
|
||||
Objects.requireNonNull(member.getType());
|
||||
return IMPL_NAMES.resolveOrFail(refKind, member, lookupClassOrNull(),
|
||||
return IMPL_NAMES.resolveOrFail(refKind, member, lookupClassOrNull(), allowedModes,
|
||||
ReflectiveOperationException.class);
|
||||
}
|
||||
|
||||
|
@ -3470,7 +3463,7 @@ return mh1;
|
|||
}
|
||||
Objects.requireNonNull(member.getName());
|
||||
Objects.requireNonNull(member.getType());
|
||||
return IMPL_NAMES.resolveOrNull(refKind, member, lookupClassOrNull());
|
||||
return IMPL_NAMES.resolveOrNull(refKind, member, lookupClassOrNull(), allowedModes);
|
||||
}
|
||||
|
||||
void checkSymbolicClass(Class<?> refc) throws IllegalAccessException {
|
||||
|
@ -3774,7 +3767,7 @@ return mh1;
|
|||
method.getName(),
|
||||
method.getMethodType(),
|
||||
REF_invokeSpecial);
|
||||
m2 = IMPL_NAMES.resolveOrNull(refKind, m2, lookupClassOrNull());
|
||||
m2 = IMPL_NAMES.resolveOrNull(refKind, m2, lookupClassOrNull(), allowedModes);
|
||||
} while (m2 == null && // no method is found yet
|
||||
refc != refcAsSuper); // search up to refc
|
||||
if (m2 == null) throw new InternalError(method.toString());
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue