mirror of
https://github.com/openjdk/jdk.git
synced 2025-08-27 06:45:07 +02:00
8271820: Implementation of JEP 416: Reimplement Core Reflection with Method Handle
8013527: calling MethodHandles.lookup on itself leads to errors Co-authored-by: Peter Levart <plevart@openjdk.org> Co-authored-by: Claes Redestad <redestad@openjdk.org> Co-authored-by: Mandy Chung <mchung@openjdk.org> Reviewed-by: mcimadamore, plevart, egahlin, redestad, cjplummer, alanb
This commit is contained in:
parent
5a768f75c9
commit
c6339cb8a2
78 changed files with 6118 additions and 544 deletions
|
@ -32,6 +32,7 @@ import jdk.internal.org.objectweb.asm.ClassReader;
|
|||
import jdk.internal.org.objectweb.asm.Opcodes;
|
||||
import jdk.internal.org.objectweb.asm.Type;
|
||||
import jdk.internal.reflect.CallerSensitive;
|
||||
import jdk.internal.reflect.CallerSensitiveAdapter;
|
||||
import jdk.internal.reflect.Reflection;
|
||||
import jdk.internal.vm.annotation.ForceInline;
|
||||
import sun.invoke.util.ValueConversions;
|
||||
|
@ -63,7 +64,9 @@ import java.util.stream.Stream;
|
|||
import static java.lang.invoke.LambdaForm.BasicType.V_TYPE;
|
||||
import static java.lang.invoke.MethodHandleImpl.Intrinsic;
|
||||
import static java.lang.invoke.MethodHandleNatives.Constants.*;
|
||||
import static java.lang.invoke.MethodHandleStatics.UNSAFE;
|
||||
import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
|
||||
import static java.lang.invoke.MethodHandleStatics.newInternalError;
|
||||
import static java.lang.invoke.MethodType.methodType;
|
||||
|
||||
/**
|
||||
|
@ -117,14 +120,15 @@ public class MethodHandles {
|
|||
}
|
||||
|
||||
/**
|
||||
* This reflected$lookup method is the alternate implementation of
|
||||
* the lookup method when being invoked by reflection.
|
||||
* This lookup method is the alternate implementation of
|
||||
* the lookup method with a leading caller class argument which is
|
||||
* non-caller-sensitive. This method is only invoked by reflection
|
||||
* and method handle.
|
||||
*/
|
||||
@CallerSensitive
|
||||
private static Lookup reflected$lookup() {
|
||||
Class<?> caller = Reflection.getCallerClass();
|
||||
@CallerSensitiveAdapter
|
||||
private static Lookup lookup(Class<?> caller) {
|
||||
if (caller.getClassLoader() == null) {
|
||||
throw newIllegalArgumentException("illegal lookupClass: "+caller);
|
||||
throw newInternalError("calling lookup() reflectively is not supported: "+caller);
|
||||
}
|
||||
return new Lookup(caller);
|
||||
}
|
||||
|
@ -329,7 +333,7 @@ public class MethodHandles {
|
|||
throw new IllegalAccessException(caller + " does not have ORIGINAL access");
|
||||
}
|
||||
|
||||
Object classdata = MethodHandleNatives.classData(caller.lookupClass());
|
||||
Object classdata = classData(caller.lookupClass());
|
||||
if (classdata == null) return null;
|
||||
|
||||
try {
|
||||
|
@ -341,6 +345,17 @@ public class MethodHandles {
|
|||
}
|
||||
}
|
||||
|
||||
/*
|
||||
* Returns the class data set by the VM in the Class::classData field.
|
||||
*
|
||||
* This is also invoked by LambdaForms as it cannot use condy via
|
||||
* MethodHandles::classData due to bootstrapping issue.
|
||||
*/
|
||||
static Object classData(Class<?> c) {
|
||||
UNSAFE.ensureClassInitialized(c);
|
||||
return SharedSecrets.getJavaLangAccess().classData(c);
|
||||
}
|
||||
|
||||
/**
|
||||
* Returns the element at the specified index in the
|
||||
* {@linkplain #classData(Lookup, String, Class) class data},
|
||||
|
@ -2359,15 +2374,16 @@ public class MethodHandles {
|
|||
|
||||
/**
|
||||
* Returns a ClassDefiner that creates a {@code Class} object of a hidden class
|
||||
* from the given bytes. No package name check on the given name.
|
||||
* from the given bytes and the given options. No package name check on the given name.
|
||||
*
|
||||
* @param name fully-qualified name that specifies the prefix of the hidden class
|
||||
* @param bytes class bytes
|
||||
* @return ClassDefiner that defines a hidden class of the given bytes.
|
||||
* @param options class options
|
||||
* @return ClassDefiner that defines a hidden class of the given bytes and options.
|
||||
*/
|
||||
ClassDefiner makeHiddenClassDefiner(String name, byte[] bytes) {
|
||||
ClassDefiner makeHiddenClassDefiner(String name, byte[] bytes, Set<ClassOption> options) {
|
||||
// skip name and access flags validation
|
||||
return makeHiddenClassDefiner(ClassFile.newInstanceNoCheck(name, bytes), Set.of(), false);
|
||||
return makeHiddenClassDefiner(ClassFile.newInstanceNoCheck(name, bytes), options, false);
|
||||
}
|
||||
|
||||
/**
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue