< prev index next >

src/java.base/share/classes/java/lang/invoke/MethodHandles.java

Print this page

   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.invoke;
  27 
  28 import jdk.internal.access.SharedSecrets;

  29 import jdk.internal.foreign.Utils;
  30 import jdk.internal.javac.PreviewFeature;
  31 import jdk.internal.misc.Unsafe;
  32 import jdk.internal.misc.VM;
  33 import jdk.internal.org.objectweb.asm.ClassReader;
  34 import jdk.internal.org.objectweb.asm.Opcodes;
  35 import jdk.internal.org.objectweb.asm.Type;
  36 import jdk.internal.reflect.CallerSensitive;
  37 import jdk.internal.reflect.CallerSensitiveAdapter;
  38 import jdk.internal.reflect.Reflection;
  39 import jdk.internal.vm.annotation.ForceInline;
  40 import sun.invoke.util.ValueConversions;
  41 import sun.invoke.util.VerifyAccess;
  42 import sun.invoke.util.Wrapper;
  43 import sun.reflect.misc.ReflectUtil;
  44 import sun.security.util.SecurityConstants;
  45 
  46 import java.lang.constant.ConstantDescs;
  47 import java.lang.foreign.GroupLayout;
  48 import java.lang.foreign.MemoryAddress;

 688      * If the desired member is {@code protected}, the usual JVM rules apply,
 689      * including the requirement that the lookup class must either be in the
 690      * same package as the desired member, or must inherit that member.
 691      * (See the Java Virtual Machine Specification, sections {@jvms
 692      * 4.9.2}, {@jvms 5.4.3.5}, and {@jvms 6.4}.)
 693      * In addition, if the desired member is a non-static field or method
 694      * in a different package, the resulting method handle may only be applied
 695      * to objects of the lookup class or one of its subclasses.
 696      * This requirement is enforced by narrowing the type of the leading
 697      * {@code this} parameter from {@code C}
 698      * (which will necessarily be a superclass of the lookup class)
 699      * to the lookup class itself.
 700      * <p>
 701      * The JVM imposes a similar requirement on {@code invokespecial} instruction,
 702      * that the receiver argument must match both the resolved method <em>and</em>
 703      * the current class.  Again, this requirement is enforced by narrowing the
 704      * type of the leading parameter to the resulting method handle.
 705      * (See the Java Virtual Machine Specification, section {@jvms 4.10.1.9}.)
 706      * <p>
 707      * The JVM represents constructors and static initializer blocks as internal methods
 708      * with special names ({@code "<init>"} and {@code "<clinit>"}).
 709      * The internal syntax of invocation instructions allows them to refer to such internal
 710      * methods as if they were normal methods, but the JVM bytecode verifier rejects them.
 711      * A lookup of such an internal method will produce a {@code NoSuchMethodException}.
 712      * <p>
 713      * If the relationship between nested types is expressed directly through the
 714      * {@code NestHost} and {@code NestMembers} attributes
 715      * (see the Java Virtual Machine Specification, sections {@jvms
 716      * 4.7.28} and {@jvms 4.7.29}),
 717      * then the associated {@code Lookup} object provides direct access to
 718      * the lookup class and all of its nestmates
 719      * (see {@link java.lang.Class#getNestHost Class.getNestHost}).
 720      * Otherwise, access between nested classes is obtained by the Java compiler creating
 721      * a wrapper method to access a private method of another class in the same nest.
 722      * For example, a nested class {@code C.D}
 723      * can access private members within other related classes such as
 724      * {@code C}, {@code C.D.E}, or {@code C.B},
 725      * but the Java compiler may need to generate wrapper methods in
 726      * those related classes.  In such cases, a {@code Lookup} object on
 727      * {@code C.E} would be unable to access those private members.
 728      * A workaround for this limitation is the {@link Lookup#in Lookup.in} method,

1606          *  @return the lookup modes, which limit the kinds of access performed by this lookup object
1607          *  @see #in
1608          *  @see #dropLookupMode
1609          *
1610          *  @revised 9
1611          */
1612         public int lookupModes() {
1613             return allowedModes & ALL_MODES;
1614         }
1615 
1616         /** Embody the current class (the lookupClass) as a lookup class
1617          * for method handle creation.
1618          * Must be called by from a method in this package,
1619          * which in turn is called by a method not in this package.
1620          */
1621         Lookup(Class<?> lookupClass) {
1622             this(lookupClass, null, FULL_POWER_MODES);
1623         }
1624 
1625         private Lookup(Class<?> lookupClass, Class<?> prevLookupClass, int allowedModes) {

1626             assert prevLookupClass == null || ((allowedModes & MODULE) == 0
1627                     && prevLookupClass.getModule() != lookupClass.getModule());
1628             assert !lookupClass.isArray() && !lookupClass.isPrimitive();
1629             this.lookupClass = lookupClass;
1630             this.prevLookupClass = prevLookupClass;
1631             this.allowedModes = allowedModes;
1632         }
1633 
1634         private static Lookup newLookup(Class<?> lookupClass, Class<?> prevLookupClass, int allowedModes) {
1635             // make sure we haven't accidentally picked up a privileged class:
1636             checkUnprivilegedlookupClass(lookupClass);
1637             return new Lookup(lookupClass, prevLookupClass, allowedModes);
1638         }
1639 
1640         /**
1641          * Creates a lookup on the specified new lookup class.
1642          * The resulting object will report the specified
1643          * class as its own {@link #lookupClass() lookupClass}.
1644          *
1645          * <p>

2723          * If the returned method handle is invoked, the constructor's class will
2724          * be initialized, if it has not already been initialized.
2725          * <p><b>Example:</b>
2726          * {@snippet lang="java" :
2727 import static java.lang.invoke.MethodHandles.*;
2728 import static java.lang.invoke.MethodType.*;
2729 ...
2730 MethodHandle MH_newArrayList = publicLookup().findConstructor(
2731   ArrayList.class, methodType(void.class, Collection.class));
2732 Collection orig = Arrays.asList("x", "y");
2733 Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
2734 assert(orig != copy);
2735 assertEquals(orig, copy);
2736 // a variable-arity constructor:
2737 MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
2738   ProcessBuilder.class, methodType(void.class, String[].class));
2739 ProcessBuilder pb = (ProcessBuilder)
2740   MH_newProcessBuilder.invoke("x", "y", "z");
2741 assertEquals("[x, y, z]", pb.command().toString());
2742          * }


2743          * @param refc the class or interface from which the method is accessed
2744          * @param type the type of the method, with the receiver argument omitted, and a void return type
2745          * @return the desired method handle
2746          * @throws NoSuchMethodException if the constructor does not exist
2747          * @throws IllegalAccessException if access checking fails
2748          *                                or if the method's variable arity modifier bit
2749          *                                is set and {@code asVarargsCollector} fails
2750          * @throws    SecurityException if a security manager is present and it
2751          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2752          * @throws NullPointerException if any argument is null
2753          */
2754         public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
2755             if (refc.isArray()) {
2756                 throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
2757             }



2758             String name = "<init>";
2759             MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
2760             return getDirectConstructor(refc, ctor);
2761         }
2762 
2763         /**
2764          * Looks up a class by name from the lookup context defined by this {@code Lookup} object,
2765          * <a href="MethodHandles.Lookup.html#equiv">as if resolved</a> by an {@code ldc} instruction.
2766          * Such a resolution, as specified in JVMS {@jvms 5.4.3.1}, attempts to locate and load the class,
2767          * and then determines whether the class is accessible to this lookup object.
2768          * <p>
2769          * The lookup context here is determined by the {@linkplain #lookupClass() lookup class},
2770          * its class loader, and the {@linkplain #lookupModes() lookup modes}.
2771          *
2772          * @param targetName the fully qualified name of the class to be looked up.
2773          * @return the requested class.
2774          * @throws SecurityException if a security manager is present and it
2775          *                           <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2776          * @throws LinkageError if the linkage fails
2777          * @throws ClassNotFoundException if the class cannot be loaded by the lookup class' loader.

3424          * arguments passed to the method handle.
3425          * <p>
3426          * If the constructor's {@code accessible} flag is not set,
3427          * access checking is performed immediately on behalf of the lookup class.
3428          * <p>
3429          * The returned method handle will have
3430          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
3431          * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
3432          * <p>
3433          * If the returned method handle is invoked, the constructor's class will
3434          * be initialized, if it has not already been initialized.
3435          * @param c the reflected constructor
3436          * @return a method handle which can invoke the reflected constructor
3437          * @throws IllegalAccessException if access checking fails
3438          *                                or if the method's variable arity modifier bit
3439          *                                is set and {@code asVarargsCollector} fails
3440          * @throws NullPointerException if the argument is null
3441          */
3442         public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException {
3443             MemberName ctor = new MemberName(c);
3444             assert(ctor.isConstructor());
3445             @SuppressWarnings("deprecation")
3446             Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this;
3447             return lookup.getDirectConstructorNoSecurityManager(ctor.getDeclaringClass(), ctor);









3448         }
3449 
3450         /**
3451          * Produces a method handle giving read access to a reflected field.
3452          * The type of the method handle will have a return type of the field's
3453          * value type.
3454          * If the field is {@code static}, the method handle will take no arguments.
3455          * Otherwise, its single argument will be the instance containing
3456          * the field.
3457          * If the {@code Field} object's {@code accessible} flag is not set,
3458          * access checking is performed immediately on behalf of the lookup class.
3459          * <p>
3460          * If the field is static, and
3461          * if the returned method handle is invoked, the field's class will
3462          * be initialized, if it has not already been initialized.
3463          * @param f the reflected field
3464          * @return a method handle which can load values from the reflected field
3465          * @throws IllegalAccessException if access checking fails
3466          * @throws NullPointerException if the argument is null
3467          */

3672                                             ReflectiveOperationException.class);
3673         }
3674 
3675         MemberName resolveOrNull(byte refKind, MemberName member) {
3676             // do this before attempting to resolve
3677             if (!isClassAccessible(member.getDeclaringClass())) {
3678                 return null;
3679             }
3680             Objects.requireNonNull(member.getName());
3681             Objects.requireNonNull(member.getType());
3682             return IMPL_NAMES.resolveOrNull(refKind, member, lookupClassOrNull(), allowedModes);
3683         }
3684 
3685         MemberName resolveOrNull(byte refKind, Class<?> refc, String name, MethodType type) {
3686             // do this before attempting to resolve
3687             if (!isClassAccessible(refc)) {
3688                 return null;
3689             }
3690             Objects.requireNonNull(type);
3691             // implicit null-check of name
3692             if (name.startsWith("<") && refKind != REF_newInvokeSpecial) {
3693                 return null;
3694             }

3695             return IMPL_NAMES.resolveOrNull(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), allowedModes);
3696         }
3697 
3698         void checkSymbolicClass(Class<?> refc) throws IllegalAccessException {
3699             if (!isClassAccessible(refc)) {
3700                 throw new MemberName(refc).makeAccessException("symbolic reference class is not accessible", this);
3701             }
3702         }
3703 
3704         boolean isClassAccessible(Class<?> refc) {
3705             Objects.requireNonNull(refc);
3706             Class<?> caller = lookupClassOrNull();
3707             Class<?> type = refc;
3708             while (type.isArray()) {
3709                 type = type.getComponentType();
3710             }
3711             return caller == null || VerifyAccess.isClassAccessible(type, caller, prevLookupClass, allowedModes);
3712         }
3713 












3714         /** Check name for an illegal leading "&lt;" character. */
3715         void checkMethodName(byte refKind, String name) throws NoSuchMethodException {
3716             if (name.startsWith("<") && refKind != REF_newInvokeSpecial)
3717                 throw new NoSuchMethodException("illegal method name: "+name);

3718         }
3719 
3720         /**
3721          * Find my trustable caller class if m is a caller sensitive method.
3722          * If this lookup object has original full privilege access, then the caller class is the lookupClass.
3723          * Otherwise, if m is caller-sensitive, throw IllegalAccessException.
3724          */
3725         Lookup findBoundCallerLookup(MemberName m) throws IllegalAccessException {
3726             if (MethodHandleNatives.isCallerSensitive(m) && (lookupModes() & ORIGINAL) == 0) {
3727                 // Only lookups with full privilege access are allowed to resolve caller-sensitive methods
3728                 throw new IllegalAccessException("Attempt to lookup caller-sensitive method using restricted lookup object");
3729             }
3730             return this;
3731         }
3732 
3733         /**
3734          * Returns {@code true} if this lookup has {@code PRIVATE} and {@code MODULE} access.
3735          * @return {@code true} if this lookup has {@code PRIVATE} and {@code MODULE} access.
3736          *
3737          * @deprecated This method was originally designed to test {@code PRIVATE} access

3801 
3802             @SuppressWarnings("removal")
3803             SecurityManager smgr = System.getSecurityManager();
3804             if (smgr == null)  return;
3805 
3806             // Step 1:
3807             boolean fullPrivilegeLookup = hasFullPrivilegeAccess();
3808             if (!fullPrivilegeLookup ||
3809                 !VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
3810                 ReflectUtil.checkPackageAccess(refc);
3811             }
3812 
3813             // Step 2a:
3814             if (m.isPublic()) return;
3815             if (!fullPrivilegeLookup) {
3816                 smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
3817             }
3818 
3819             // Step 3:
3820             Class<?> defc = m.getDeclaringClass();
3821             if (!fullPrivilegeLookup && defc != refc) {
3822                 ReflectUtil.checkPackageAccess(defc);
3823             }
3824         }
3825 
3826         void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
3827             boolean wantStatic = (refKind == REF_invokeStatic);
3828             String message;
3829             if (m.isConstructor())
3830                 message = "expected a method, not a constructor";
3831             else if (!m.isMethod())
3832                 message = "expected a method";
3833             else if (wantStatic != m.isStatic())
3834                 message = wantStatic ? "expected a static method" : "expected a non-static method";
3835             else
3836                 { checkAccess(refKind, refc, m); return; }
3837             throw m.makeAccessException(message, this);
3838         }
3839 
3840         void checkField(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
3841             boolean wantStatic = !MethodHandleNatives.refKindHasReceiver(refKind);
3842             String message;
3843             if (wantStatic != m.isStatic())
3844                 message = wantStatic ? "expected a static field" : "expected a non-static field";
3845             else
3846                 { checkAccess(refKind, refc, m); return; }
3847             throw m.makeAccessException(message, this);
3848         }
3849 

3884                 throw m.makeAccessException("unexpected set of a final field", this);
3885             int requestedModes = fixmods(mods);  // adjust 0 => PACKAGE
3886             if ((requestedModes & allowedModes) != 0) {
3887                 if (VerifyAccess.isMemberAccessible(refc, m.getDeclaringClass(),
3888                                                     mods, lookupClass(), previousLookupClass(), allowedModes))
3889                     return;
3890             } else {
3891                 // Protected members can also be checked as if they were package-private.
3892                 if ((requestedModes & PROTECTED) != 0 && (allowedModes & PACKAGE) != 0
3893                         && VerifyAccess.isSamePackage(m.getDeclaringClass(), lookupClass()))
3894                     return;
3895             }
3896             throw m.makeAccessException(accessFailedMessage(refc, m), this);
3897         }
3898 
3899         String accessFailedMessage(Class<?> refc, MemberName m) {
3900             Class<?> defc = m.getDeclaringClass();
3901             int mods = m.getModifiers();
3902             // check the class first:
3903             boolean classOK = (Modifier.isPublic(defc.getModifiers()) &&
3904                                (defc == refc ||
3905                                 Modifier.isPublic(refc.getModifiers())));
3906             if (!classOK && (allowedModes & PACKAGE) != 0) {
3907                 // ignore previous lookup class to check if default package access
3908                 classOK = (VerifyAccess.isClassAccessible(defc, lookupClass(), null, FULL_POWER_MODES) &&
3909                            (defc == refc ||
3910                             VerifyAccess.isClassAccessible(refc, lookupClass(), null, FULL_POWER_MODES)));
3911             }
3912             if (!classOK)
3913                 return "class is not public";
3914             if (Modifier.isPublic(mods))
3915                 return "access to public member failed";  // (how?, module not readable?)
3916             if (Modifier.isPrivate(mods))
3917                 return "member is private";
3918             if (Modifier.isProtected(mods))
3919                 return "member is protected";
3920             return "member is private to package";
3921         }
3922 
3923         private void checkSpecialCaller(Class<?> specialCaller, Class<?> refc) throws IllegalAccessException {
3924             int allowedModes = this.allowedModes;
3925             if (allowedModes == TRUSTED)  return;
3926             if ((lookupModes() & PRIVATE) == 0
3927                 || (specialCaller != lookupClass()
3928                        // ensure non-abstract methods in superinterfaces can be special-invoked
3929                     && !(refc != null && refc.isInterface() && refc.isAssignableFrom(specialCaller))))

3966             final boolean doRestrict    = false;
3967             final boolean checkSecurity = true;
3968             return getDirectMethodCommon(REF_invokeSpecial, refc, method, checkSecurity, doRestrict, callerLookup);
3969         }
3970         /** Check access and get the requested method, eliding security manager checks. */
3971         private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Lookup callerLookup) throws IllegalAccessException {
3972             final boolean doRestrict    = true;
3973             final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
3974             return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerLookup);
3975         }
3976         /** Common code for all methods; do not call directly except from immediately above. */
3977         private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
3978                                                    boolean checkSecurity,
3979                                                    boolean doRestrict,
3980                                                    Lookup boundCaller) throws IllegalAccessException {
3981             checkMethod(refKind, refc, method);
3982             // Optionally check with the security manager; this isn't needed for unreflect* calls.
3983             if (checkSecurity)
3984                 checkSecurityManager(refc, method);
3985             assert(!method.isMethodHandleInvoke());
3986 
3987             if (refKind == REF_invokeSpecial &&
3988                 refc != lookupClass() &&
3989                 !refc.isInterface() &&
3990                 refc != lookupClass().getSuperclass() &&
3991                 refc.isAssignableFrom(lookupClass())) {
3992                 assert(!method.getName().equals("<init>"));  // not this code path
3993 
3994                 // Per JVMS 6.5, desc. of invokespecial instruction:
3995                 // If the method is in a superclass of the LC,
3996                 // and if our original search was above LC.super,
3997                 // repeat the search (symbolic lookup) from LC.super
3998                 // and continue with the direct superclass of that class,
3999                 // and so forth, until a match is found or no further superclasses exist.
4000                 // FIXME: MemberName.resolve should handle this instead.
4001                 Class<?> refcAsSuper = lookupClass();
4002                 MemberName m2;
4003                 do {
4004                     refcAsSuper = refcAsSuper.getSuperclass();
4005                     m2 = new MemberName(refcAsSuper,
4006                                         method.getName(),

4110                     throw getField.makeAccessException("caller class must be a subclass below the method", lookupClass());
4111                 }
4112                 refc = lookupClass();
4113             }
4114             return VarHandles.makeFieldHandle(getField, refc, getField.getFieldType(),
4115                                               this.allowedModes == TRUSTED && !getField.isTrustedFinalField());
4116         }
4117         /** Check access and get the requested constructor. */
4118         private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
4119             final boolean checkSecurity = true;
4120             return getDirectConstructorCommon(refc, ctor, checkSecurity);
4121         }
4122         /** Check access and get the requested constructor, eliding security manager checks. */
4123         private MethodHandle getDirectConstructorNoSecurityManager(Class<?> refc, MemberName ctor) throws IllegalAccessException {
4124             final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
4125             return getDirectConstructorCommon(refc, ctor, checkSecurity);
4126         }
4127         /** Common code for all constructors; do not call directly except from immediately above. */
4128         private MethodHandle getDirectConstructorCommon(Class<?> refc, MemberName ctor,
4129                                                   boolean checkSecurity) throws IllegalAccessException {
4130             assert(ctor.isConstructor());
4131             checkAccess(REF_newInvokeSpecial, refc, ctor);
4132             // Optionally check with the security manager; this isn't needed for unreflect* calls.
4133             if (checkSecurity)
4134                 checkSecurityManager(refc, ctor);
4135             assert(!MethodHandleNatives.isCallerSensitive(ctor));  // maybeBindCaller not relevant here
4136             return DirectMethodHandle.make(ctor).setVarargs(ctor);
4137         }
4138 
4139         /** Hook called from the JVM (via MethodHandleNatives) to link MH constants:
4140          */
4141         /*non-public*/
4142         MethodHandle linkMethodHandleConstant(byte refKind, Class<?> defc, String name, Object type)
4143                 throws ReflectiveOperationException {
4144             if (!(type instanceof Class || type instanceof MethodType))
4145                 throw new InternalError("unresolved MemberName");
4146             MemberName member = new MemberName(refKind, defc, name, type);
4147             MethodHandle mh = LOOKASIDE_TABLE.get(member);
4148             if (mh != null) {
4149                 checkSymbolicClass(defc);
4150                 return mh;

5016      * If the requested type is primitive, widening primitive conversions are attempted,
5017      * else reference conversions are attempted.
5018      * <p>The returned method handle is equivalent to {@code identity(type).bindTo(value)}.
5019      * @param type the return type of the desired method handle
5020      * @param value the value to return
5021      * @return a method handle of the given return type and no arguments, which always returns the given value
5022      * @throws NullPointerException if the {@code type} argument is null
5023      * @throws ClassCastException if the value cannot be converted to the required return type
5024      * @throws IllegalArgumentException if the given type is {@code void.class}
5025      */
5026     public static MethodHandle constant(Class<?> type, Object value) {
5027         if (type.isPrimitive()) {
5028             if (type == void.class)
5029                 throw newIllegalArgumentException("void type");
5030             Wrapper w = Wrapper.forPrimitiveType(type);
5031             value = w.convert(value, type);
5032             if (w.zero().equals(value))
5033                 return zero(w, type);
5034             return insertArguments(identity(type), 0, value);
5035         } else {
5036             if (value == null)
5037                 return zero(Wrapper.OBJECT, type);
5038             return identity(type).bindTo(value);
5039         }
5040     }
5041 
5042     /**
5043      * Produces a method handle which returns its sole argument when invoked.
5044      * @param type the type of the sole parameter and return value of the desired method handle
5045      * @return a unary method handle which accepts and returns the given type
5046      * @throws NullPointerException if the argument is null
5047      * @throws IllegalArgumentException if the given type is {@code void.class}
5048      */
5049     public static MethodHandle identity(Class<?> type) {
5050         Wrapper btw = (type.isPrimitive() ? Wrapper.forPrimitiveType(type) : Wrapper.OBJECT);
5051         int pos = btw.ordinal();
5052         MethodHandle ident = IDENTITY_MHS[pos];
5053         if (ident == null) {
5054             ident = setCachedMethodHandle(IDENTITY_MHS, pos, makeIdentity(btw.primitiveType()));
5055         }
5056         if (ident.type().returnType() == type)

5061     }
5062 
5063     /**
5064      * Produces a constant method handle of the requested return type which
5065      * returns the default value for that type every time it is invoked.
5066      * The resulting constant method handle will have no side effects.
5067      * <p>The returned method handle is equivalent to {@code empty(methodType(type))}.
5068      * It is also equivalent to {@code explicitCastArguments(constant(Object.class, null), methodType(type))},
5069      * since {@code explicitCastArguments} converts {@code null} to default values.
5070      * @param type the expected return type of the desired method handle
5071      * @return a constant method handle that takes no arguments
5072      *         and returns the default value of the given type (or void, if the type is void)
5073      * @throws NullPointerException if the argument is null
5074      * @see MethodHandles#constant
5075      * @see MethodHandles#empty
5076      * @see MethodHandles#explicitCastArguments
5077      * @since 9
5078      */
5079     public static MethodHandle zero(Class<?> type) {
5080         Objects.requireNonNull(type);
5081         return type.isPrimitive() ?  zero(Wrapper.forPrimitiveType(type), type) : zero(Wrapper.OBJECT, type);








5082     }
5083 
5084     private static MethodHandle identityOrVoid(Class<?> type) {
5085         return type == void.class ? zero(type) : identity(type);
5086     }
5087 
5088     /**
5089      * Produces a method handle of the requested type which ignores any arguments, does nothing,
5090      * and returns a suitable default depending on the return type.
5091      * That is, it returns a zero primitive value, a {@code null}, or {@code void}.
5092      * <p>The returned method handle is equivalent to
5093      * {@code dropArguments(zero(type.returnType()), 0, type.parameterList())}.
5094      *
5095      * @apiNote Given a predicate and target, a useful "if-then" construct can be produced as
5096      * {@code guardWithTest(pred, target, empty(target.type())}.
5097      * @param type the type of the desired method handle
5098      * @return a constant method handle of the given type, which returns a default value of the given return type
5099      * @throws NullPointerException if the argument is null
5100      * @see MethodHandles#zero
5101      * @see MethodHandles#constant
5102      * @since 9
5103      */
5104     public static  MethodHandle empty(MethodType type) {
5105         Objects.requireNonNull(type);
5106         return dropArgumentsTrusted(zero(type.returnType()), 0, type.ptypes());
5107     }
5108 
5109     private static final MethodHandle[] IDENTITY_MHS = new MethodHandle[Wrapper.COUNT];
5110     private static MethodHandle makeIdentity(Class<?> ptype) {
5111         MethodType mtype = methodType(ptype, ptype);
5112         LambdaForm lform = LambdaForm.identityForm(BasicType.basicType(ptype));
5113         return MethodHandleImpl.makeIntrinsic(mtype, lform, Intrinsic.IDENTITY);
5114     }
5115 
5116     private static MethodHandle zero(Wrapper btw, Class<?> rtype) {
5117         int pos = btw.ordinal();
5118         MethodHandle zero = ZERO_MHS[pos];
5119         if (zero == null) {
5120             zero = setCachedMethodHandle(ZERO_MHS, pos, makeZero(btw.primitiveType()));
5121         }
5122         if (zero.type().returnType() == rtype)
5123             return zero;
5124         assert(btw == Wrapper.OBJECT);
5125         return makeZero(rtype);
5126     }
5127     private static final MethodHandle[] ZERO_MHS = new MethodHandle[Wrapper.COUNT];
5128     private static MethodHandle makeZero(Class<?> rtype) {
5129         MethodType mtype = methodType(rtype);
5130         LambdaForm lform = LambdaForm.zeroForm(BasicType.basicType(rtype));
5131         return MethodHandleImpl.makeIntrinsic(mtype, lform, Intrinsic.ZERO);

   9  * by Oracle in the LICENSE file that accompanied this code.
  10  *
  11  * This code is distributed in the hope that it will be useful, but WITHOUT
  12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
  13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
  14  * version 2 for more details (a copy is included in the LICENSE file that
  15  * accompanied this code).
  16  *
  17  * You should have received a copy of the GNU General Public License version
  18  * 2 along with this work; if not, write to the Free Software Foundation,
  19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
  20  *
  21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
  22  * or visit www.oracle.com if you need additional information or have any
  23  * questions.
  24  */
  25 
  26 package java.lang.invoke;
  27 
  28 import jdk.internal.access.SharedSecrets;
  29 import jdk.internal.value.PrimitiveClass;
  30 import jdk.internal.foreign.Utils;
  31 import jdk.internal.javac.PreviewFeature;
  32 import jdk.internal.misc.Unsafe;
  33 import jdk.internal.misc.VM;
  34 import jdk.internal.org.objectweb.asm.ClassReader;
  35 import jdk.internal.org.objectweb.asm.Opcodes;
  36 import jdk.internal.org.objectweb.asm.Type;
  37 import jdk.internal.reflect.CallerSensitive;
  38 import jdk.internal.reflect.CallerSensitiveAdapter;
  39 import jdk.internal.reflect.Reflection;
  40 import jdk.internal.vm.annotation.ForceInline;
  41 import sun.invoke.util.ValueConversions;
  42 import sun.invoke.util.VerifyAccess;
  43 import sun.invoke.util.Wrapper;
  44 import sun.reflect.misc.ReflectUtil;
  45 import sun.security.util.SecurityConstants;
  46 
  47 import java.lang.constant.ConstantDescs;
  48 import java.lang.foreign.GroupLayout;
  49 import java.lang.foreign.MemoryAddress;

 689      * If the desired member is {@code protected}, the usual JVM rules apply,
 690      * including the requirement that the lookup class must either be in the
 691      * same package as the desired member, or must inherit that member.
 692      * (See the Java Virtual Machine Specification, sections {@jvms
 693      * 4.9.2}, {@jvms 5.4.3.5}, and {@jvms 6.4}.)
 694      * In addition, if the desired member is a non-static field or method
 695      * in a different package, the resulting method handle may only be applied
 696      * to objects of the lookup class or one of its subclasses.
 697      * This requirement is enforced by narrowing the type of the leading
 698      * {@code this} parameter from {@code C}
 699      * (which will necessarily be a superclass of the lookup class)
 700      * to the lookup class itself.
 701      * <p>
 702      * The JVM imposes a similar requirement on {@code invokespecial} instruction,
 703      * that the receiver argument must match both the resolved method <em>and</em>
 704      * the current class.  Again, this requirement is enforced by narrowing the
 705      * type of the leading parameter to the resulting method handle.
 706      * (See the Java Virtual Machine Specification, section {@jvms 4.10.1.9}.)
 707      * <p>
 708      * The JVM represents constructors and static initializer blocks as internal methods
 709      * with special names ({@code "<init>"}, {@code "<vnew>"} and {@code "<clinit>"}).
 710      * The internal syntax of invocation instructions allows them to refer to such internal
 711      * methods as if they were normal methods, but the JVM bytecode verifier rejects them.
 712      * A lookup of such an internal method will produce a {@code NoSuchMethodException}.
 713      * <p>
 714      * If the relationship between nested types is expressed directly through the
 715      * {@code NestHost} and {@code NestMembers} attributes
 716      * (see the Java Virtual Machine Specification, sections {@jvms
 717      * 4.7.28} and {@jvms 4.7.29}),
 718      * then the associated {@code Lookup} object provides direct access to
 719      * the lookup class and all of its nestmates
 720      * (see {@link java.lang.Class#getNestHost Class.getNestHost}).
 721      * Otherwise, access between nested classes is obtained by the Java compiler creating
 722      * a wrapper method to access a private method of another class in the same nest.
 723      * For example, a nested class {@code C.D}
 724      * can access private members within other related classes such as
 725      * {@code C}, {@code C.D.E}, or {@code C.B},
 726      * but the Java compiler may need to generate wrapper methods in
 727      * those related classes.  In such cases, a {@code Lookup} object on
 728      * {@code C.E} would be unable to access those private members.
 729      * A workaround for this limitation is the {@link Lookup#in Lookup.in} method,

1607          *  @return the lookup modes, which limit the kinds of access performed by this lookup object
1608          *  @see #in
1609          *  @see #dropLookupMode
1610          *
1611          *  @revised 9
1612          */
1613         public int lookupModes() {
1614             return allowedModes & ALL_MODES;
1615         }
1616 
1617         /** Embody the current class (the lookupClass) as a lookup class
1618          * for method handle creation.
1619          * Must be called by from a method in this package,
1620          * which in turn is called by a method not in this package.
1621          */
1622         Lookup(Class<?> lookupClass) {
1623             this(lookupClass, null, FULL_POWER_MODES);
1624         }
1625 
1626         private Lookup(Class<?> lookupClass, Class<?> prevLookupClass, int allowedModes) {
1627             assert PrimitiveClass.isPrimaryType(lookupClass);
1628             assert prevLookupClass == null || ((allowedModes & MODULE) == 0
1629                     && prevLookupClass.getModule() != lookupClass.getModule());
1630             assert !lookupClass.isArray() && !lookupClass.isPrimitive();
1631             this.lookupClass = lookupClass;
1632             this.prevLookupClass = prevLookupClass;
1633             this.allowedModes = allowedModes;
1634         }
1635 
1636         private static Lookup newLookup(Class<?> lookupClass, Class<?> prevLookupClass, int allowedModes) {
1637             // make sure we haven't accidentally picked up a privileged class:
1638             checkUnprivilegedlookupClass(lookupClass);
1639             return new Lookup(lookupClass, prevLookupClass, allowedModes);
1640         }
1641 
1642         /**
1643          * Creates a lookup on the specified new lookup class.
1644          * The resulting object will report the specified
1645          * class as its own {@link #lookupClass() lookupClass}.
1646          *
1647          * <p>

2725          * If the returned method handle is invoked, the constructor's class will
2726          * be initialized, if it has not already been initialized.
2727          * <p><b>Example:</b>
2728          * {@snippet lang="java" :
2729 import static java.lang.invoke.MethodHandles.*;
2730 import static java.lang.invoke.MethodType.*;
2731 ...
2732 MethodHandle MH_newArrayList = publicLookup().findConstructor(
2733   ArrayList.class, methodType(void.class, Collection.class));
2734 Collection orig = Arrays.asList("x", "y");
2735 Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
2736 assert(orig != copy);
2737 assertEquals(orig, copy);
2738 // a variable-arity constructor:
2739 MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
2740   ProcessBuilder.class, methodType(void.class, String[].class));
2741 ProcessBuilder pb = (ProcessBuilder)
2742   MH_newProcessBuilder.invoke("x", "y", "z");
2743 assertEquals("[x, y, z]", pb.command().toString());
2744          * }
2745          *
2746          *
2747          * @param refc the class or interface from which the method is accessed
2748          * @param type the type of the method, with the receiver argument omitted, and a void return type
2749          * @return the desired method handle
2750          * @throws NoSuchMethodException if the constructor does not exist
2751          * @throws IllegalAccessException if access checking fails
2752          *                                or if the method's variable arity modifier bit
2753          *                                is set and {@code asVarargsCollector} fails
2754          * @throws    SecurityException if a security manager is present and it
2755          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2756          * @throws NullPointerException if any argument is null
2757          */
2758         public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
2759             if (refc.isArray()) {
2760                 throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
2761             }
2762             if (type.returnType() != void.class) {
2763                 throw new NoSuchMethodException("Constructors must have void return type: " + refc.getName());
2764             }
2765             String name = "<init>";
2766             MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
2767             return getDirectConstructor(refc, ctor);
2768         }
2769 
2770         /**
2771          * Looks up a class by name from the lookup context defined by this {@code Lookup} object,
2772          * <a href="MethodHandles.Lookup.html#equiv">as if resolved</a> by an {@code ldc} instruction.
2773          * Such a resolution, as specified in JVMS {@jvms 5.4.3.1}, attempts to locate and load the class,
2774          * and then determines whether the class is accessible to this lookup object.
2775          * <p>
2776          * The lookup context here is determined by the {@linkplain #lookupClass() lookup class},
2777          * its class loader, and the {@linkplain #lookupModes() lookup modes}.
2778          *
2779          * @param targetName the fully qualified name of the class to be looked up.
2780          * @return the requested class.
2781          * @throws SecurityException if a security manager is present and it
2782          *                           <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2783          * @throws LinkageError if the linkage fails
2784          * @throws ClassNotFoundException if the class cannot be loaded by the lookup class' loader.

3431          * arguments passed to the method handle.
3432          * <p>
3433          * If the constructor's {@code accessible} flag is not set,
3434          * access checking is performed immediately on behalf of the lookup class.
3435          * <p>
3436          * The returned method handle will have
3437          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
3438          * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
3439          * <p>
3440          * If the returned method handle is invoked, the constructor's class will
3441          * be initialized, if it has not already been initialized.
3442          * @param c the reflected constructor
3443          * @return a method handle which can invoke the reflected constructor
3444          * @throws IllegalAccessException if access checking fails
3445          *                                or if the method's variable arity modifier bit
3446          *                                is set and {@code asVarargsCollector} fails
3447          * @throws NullPointerException if the argument is null
3448          */
3449         public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException {
3450             MemberName ctor = new MemberName(c);
3451             assert(ctor.isObjectConstructor() || ctor.isStaticValueFactoryMethod());
3452             @SuppressWarnings("deprecation")
3453             Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this;
3454             Class<?> defc = c.getDeclaringClass();
3455             if (ctor.isObjectConstructor()) {
3456                 assert(ctor.getReturnType() == void.class);
3457                 return lookup.getDirectConstructorNoSecurityManager(defc, ctor);
3458             } else {
3459                 // static init factory is a static method
3460                 assert(ctor.isMethod() && ctor.getReturnType() == defc && ctor.getReferenceKind() == REF_invokeStatic) : ctor.toString();
3461                 assert(!MethodHandleNatives.isCallerSensitive(ctor));  // must not be caller-sensitive
3462                 return lookup.getDirectMethodNoSecurityManager(ctor.getReferenceKind(), defc, ctor, lookup);
3463             }
3464         }
3465 
3466         /**
3467          * Produces a method handle giving read access to a reflected field.
3468          * The type of the method handle will have a return type of the field's
3469          * value type.
3470          * If the field is {@code static}, the method handle will take no arguments.
3471          * Otherwise, its single argument will be the instance containing
3472          * the field.
3473          * If the {@code Field} object's {@code accessible} flag is not set,
3474          * access checking is performed immediately on behalf of the lookup class.
3475          * <p>
3476          * If the field is static, and
3477          * if the returned method handle is invoked, the field's class will
3478          * be initialized, if it has not already been initialized.
3479          * @param f the reflected field
3480          * @return a method handle which can load values from the reflected field
3481          * @throws IllegalAccessException if access checking fails
3482          * @throws NullPointerException if the argument is null
3483          */

3688                                             ReflectiveOperationException.class);
3689         }
3690 
3691         MemberName resolveOrNull(byte refKind, MemberName member) {
3692             // do this before attempting to resolve
3693             if (!isClassAccessible(member.getDeclaringClass())) {
3694                 return null;
3695             }
3696             Objects.requireNonNull(member.getName());
3697             Objects.requireNonNull(member.getType());
3698             return IMPL_NAMES.resolveOrNull(refKind, member, lookupClassOrNull(), allowedModes);
3699         }
3700 
3701         MemberName resolveOrNull(byte refKind, Class<?> refc, String name, MethodType type) {
3702             // do this before attempting to resolve
3703             if (!isClassAccessible(refc)) {
3704                 return null;
3705             }
3706             Objects.requireNonNull(type);
3707             // implicit null-check of name
3708             if (isIllegalMethodName(refKind, name)) {
3709                 return null;
3710             }
3711 
3712             return IMPL_NAMES.resolveOrNull(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), allowedModes);
3713         }
3714 
3715         void checkSymbolicClass(Class<?> refc) throws IllegalAccessException {
3716             if (!isClassAccessible(refc)) {
3717                 throw new MemberName(refc).makeAccessException("symbolic reference class is not accessible", this);
3718             }
3719         }
3720 
3721         boolean isClassAccessible(Class<?> refc) {
3722             Objects.requireNonNull(refc);
3723             Class<?> caller = lookupClassOrNull();
3724             Class<?> type = refc;
3725             while (type.isArray()) {
3726                 type = type.getComponentType();
3727             }
3728             return caller == null || VerifyAccess.isClassAccessible(type, caller, prevLookupClass, allowedModes);
3729         }
3730 
3731         /*
3732          * "<init>" can only be invoked via invokespecial
3733          * "<vnew>" factory can only invoked via invokestatic
3734          */
3735         boolean isIllegalMethodName(byte refKind, String name) {
3736             if (name.startsWith("<")) {
3737                 return MemberName.VALUE_FACTORY_NAME.equals(name) ? refKind != REF_invokeStatic
3738                                                                   : refKind != REF_newInvokeSpecial;
3739             }
3740             return false;
3741         }
3742 
3743         /** Check name for an illegal leading "&lt;" character. */
3744         void checkMethodName(byte refKind, String name) throws NoSuchMethodException {
3745             if (isIllegalMethodName(refKind, name)) {
3746                 throw new NoSuchMethodException("illegal method name: " + name + " " + refKind);
3747             }
3748         }
3749 
3750         /**
3751          * Find my trustable caller class if m is a caller sensitive method.
3752          * If this lookup object has original full privilege access, then the caller class is the lookupClass.
3753          * Otherwise, if m is caller-sensitive, throw IllegalAccessException.
3754          */
3755         Lookup findBoundCallerLookup(MemberName m) throws IllegalAccessException {
3756             if (MethodHandleNatives.isCallerSensitive(m) && (lookupModes() & ORIGINAL) == 0) {
3757                 // Only lookups with full privilege access are allowed to resolve caller-sensitive methods
3758                 throw new IllegalAccessException("Attempt to lookup caller-sensitive method using restricted lookup object");
3759             }
3760             return this;
3761         }
3762 
3763         /**
3764          * Returns {@code true} if this lookup has {@code PRIVATE} and {@code MODULE} access.
3765          * @return {@code true} if this lookup has {@code PRIVATE} and {@code MODULE} access.
3766          *
3767          * @deprecated This method was originally designed to test {@code PRIVATE} access

3831 
3832             @SuppressWarnings("removal")
3833             SecurityManager smgr = System.getSecurityManager();
3834             if (smgr == null)  return;
3835 
3836             // Step 1:
3837             boolean fullPrivilegeLookup = hasFullPrivilegeAccess();
3838             if (!fullPrivilegeLookup ||
3839                 !VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
3840                 ReflectUtil.checkPackageAccess(refc);
3841             }
3842 
3843             // Step 2a:
3844             if (m.isPublic()) return;
3845             if (!fullPrivilegeLookup) {
3846                 smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
3847             }
3848 
3849             // Step 3:
3850             Class<?> defc = m.getDeclaringClass();
3851             if (!fullPrivilegeLookup && PrimitiveClass.asPrimaryType(defc) != PrimitiveClass.asPrimaryType(refc)) {
3852                 ReflectUtil.checkPackageAccess(defc);
3853             }
3854         }
3855 
3856         void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
3857             boolean wantStatic = (refKind == REF_invokeStatic);
3858             String message;
3859             if (m.isObjectConstructor())
3860                 message = "expected a method, not a constructor";
3861             else if (!m.isMethod())
3862                 message = "expected a method";
3863             else if (wantStatic != m.isStatic())
3864                 message = wantStatic ? "expected a static method" : "expected a non-static method";
3865             else
3866                 { checkAccess(refKind, refc, m); return; }
3867             throw m.makeAccessException(message, this);
3868         }
3869 
3870         void checkField(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
3871             boolean wantStatic = !MethodHandleNatives.refKindHasReceiver(refKind);
3872             String message;
3873             if (wantStatic != m.isStatic())
3874                 message = wantStatic ? "expected a static field" : "expected a non-static field";
3875             else
3876                 { checkAccess(refKind, refc, m); return; }
3877             throw m.makeAccessException(message, this);
3878         }
3879 

3914                 throw m.makeAccessException("unexpected set of a final field", this);
3915             int requestedModes = fixmods(mods);  // adjust 0 => PACKAGE
3916             if ((requestedModes & allowedModes) != 0) {
3917                 if (VerifyAccess.isMemberAccessible(refc, m.getDeclaringClass(),
3918                                                     mods, lookupClass(), previousLookupClass(), allowedModes))
3919                     return;
3920             } else {
3921                 // Protected members can also be checked as if they were package-private.
3922                 if ((requestedModes & PROTECTED) != 0 && (allowedModes & PACKAGE) != 0
3923                         && VerifyAccess.isSamePackage(m.getDeclaringClass(), lookupClass()))
3924                     return;
3925             }
3926             throw m.makeAccessException(accessFailedMessage(refc, m), this);
3927         }
3928 
3929         String accessFailedMessage(Class<?> refc, MemberName m) {
3930             Class<?> defc = m.getDeclaringClass();
3931             int mods = m.getModifiers();
3932             // check the class first:
3933             boolean classOK = (Modifier.isPublic(defc.getModifiers()) &&
3934                                (PrimitiveClass.asPrimaryType(defc) == PrimitiveClass.asPrimaryType(refc) ||
3935                                 Modifier.isPublic(refc.getModifiers())));
3936             if (!classOK && (allowedModes & PACKAGE) != 0) {
3937                 // ignore previous lookup class to check if default package access
3938                 classOK = (VerifyAccess.isClassAccessible(defc, lookupClass(), null, FULL_POWER_MODES) &&
3939                            (PrimitiveClass.asPrimaryType(defc) == PrimitiveClass.asPrimaryType(refc) ||
3940                             VerifyAccess.isClassAccessible(refc, lookupClass(), null, FULL_POWER_MODES)));
3941             }
3942             if (!classOK)
3943                 return "class is not public";
3944             if (Modifier.isPublic(mods))
3945                 return "access to public member failed";  // (how?, module not readable?)
3946             if (Modifier.isPrivate(mods))
3947                 return "member is private";
3948             if (Modifier.isProtected(mods))
3949                 return "member is protected";
3950             return "member is private to package";
3951         }
3952 
3953         private void checkSpecialCaller(Class<?> specialCaller, Class<?> refc) throws IllegalAccessException {
3954             int allowedModes = this.allowedModes;
3955             if (allowedModes == TRUSTED)  return;
3956             if ((lookupModes() & PRIVATE) == 0
3957                 || (specialCaller != lookupClass()
3958                        // ensure non-abstract methods in superinterfaces can be special-invoked
3959                     && !(refc != null && refc.isInterface() && refc.isAssignableFrom(specialCaller))))

3996             final boolean doRestrict    = false;
3997             final boolean checkSecurity = true;
3998             return getDirectMethodCommon(REF_invokeSpecial, refc, method, checkSecurity, doRestrict, callerLookup);
3999         }
4000         /** Check access and get the requested method, eliding security manager checks. */
4001         private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Lookup callerLookup) throws IllegalAccessException {
4002             final boolean doRestrict    = true;
4003             final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
4004             return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerLookup);
4005         }
4006         /** Common code for all methods; do not call directly except from immediately above. */
4007         private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
4008                                                    boolean checkSecurity,
4009                                                    boolean doRestrict,
4010                                                    Lookup boundCaller) throws IllegalAccessException {
4011             checkMethod(refKind, refc, method);
4012             // Optionally check with the security manager; this isn't needed for unreflect* calls.
4013             if (checkSecurity)
4014                 checkSecurityManager(refc, method);
4015             assert(!method.isMethodHandleInvoke());

4016             if (refKind == REF_invokeSpecial &&
4017                 refc != lookupClass() &&
4018                 !refc.isInterface() &&
4019                 refc != lookupClass().getSuperclass() &&
4020                 refc.isAssignableFrom(lookupClass())) {
4021                 assert(!method.getName().equals("<init>"));  // not this code path
4022 
4023                 // Per JVMS 6.5, desc. of invokespecial instruction:
4024                 // If the method is in a superclass of the LC,
4025                 // and if our original search was above LC.super,
4026                 // repeat the search (symbolic lookup) from LC.super
4027                 // and continue with the direct superclass of that class,
4028                 // and so forth, until a match is found or no further superclasses exist.
4029                 // FIXME: MemberName.resolve should handle this instead.
4030                 Class<?> refcAsSuper = lookupClass();
4031                 MemberName m2;
4032                 do {
4033                     refcAsSuper = refcAsSuper.getSuperclass();
4034                     m2 = new MemberName(refcAsSuper,
4035                                         method.getName(),

4139                     throw getField.makeAccessException("caller class must be a subclass below the method", lookupClass());
4140                 }
4141                 refc = lookupClass();
4142             }
4143             return VarHandles.makeFieldHandle(getField, refc, getField.getFieldType(),
4144                                               this.allowedModes == TRUSTED && !getField.isTrustedFinalField());
4145         }
4146         /** Check access and get the requested constructor. */
4147         private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
4148             final boolean checkSecurity = true;
4149             return getDirectConstructorCommon(refc, ctor, checkSecurity);
4150         }
4151         /** Check access and get the requested constructor, eliding security manager checks. */
4152         private MethodHandle getDirectConstructorNoSecurityManager(Class<?> refc, MemberName ctor) throws IllegalAccessException {
4153             final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
4154             return getDirectConstructorCommon(refc, ctor, checkSecurity);
4155         }
4156         /** Common code for all constructors; do not call directly except from immediately above. */
4157         private MethodHandle getDirectConstructorCommon(Class<?> refc, MemberName ctor,
4158                                                   boolean checkSecurity) throws IllegalAccessException {
4159             assert(ctor.isObjectConstructor());
4160             checkAccess(REF_newInvokeSpecial, refc, ctor);
4161             // Optionally check with the security manager; this isn't needed for unreflect* calls.
4162             if (checkSecurity)
4163                 checkSecurityManager(refc, ctor);
4164             assert(!MethodHandleNatives.isCallerSensitive(ctor));  // maybeBindCaller not relevant here
4165             return DirectMethodHandle.make(ctor).setVarargs(ctor);
4166         }
4167 
4168         /** Hook called from the JVM (via MethodHandleNatives) to link MH constants:
4169          */
4170         /*non-public*/
4171         MethodHandle linkMethodHandleConstant(byte refKind, Class<?> defc, String name, Object type)
4172                 throws ReflectiveOperationException {
4173             if (!(type instanceof Class || type instanceof MethodType))
4174                 throw new InternalError("unresolved MemberName");
4175             MemberName member = new MemberName(refKind, defc, name, type);
4176             MethodHandle mh = LOOKASIDE_TABLE.get(member);
4177             if (mh != null) {
4178                 checkSymbolicClass(defc);
4179                 return mh;

5045      * If the requested type is primitive, widening primitive conversions are attempted,
5046      * else reference conversions are attempted.
5047      * <p>The returned method handle is equivalent to {@code identity(type).bindTo(value)}.
5048      * @param type the return type of the desired method handle
5049      * @param value the value to return
5050      * @return a method handle of the given return type and no arguments, which always returns the given value
5051      * @throws NullPointerException if the {@code type} argument is null
5052      * @throws ClassCastException if the value cannot be converted to the required return type
5053      * @throws IllegalArgumentException if the given type is {@code void.class}
5054      */
5055     public static MethodHandle constant(Class<?> type, Object value) {
5056         if (type.isPrimitive()) {
5057             if (type == void.class)
5058                 throw newIllegalArgumentException("void type");
5059             Wrapper w = Wrapper.forPrimitiveType(type);
5060             value = w.convert(value, type);
5061             if (w.zero().equals(value))
5062                 return zero(w, type);
5063             return insertArguments(identity(type), 0, value);
5064         } else {
5065             if (!PrimitiveClass.isPrimitiveValueType(type) && value == null)
5066                 return zero(Wrapper.OBJECT, type);
5067             return identity(type).bindTo(value);
5068         }
5069     }
5070 
5071     /**
5072      * Produces a method handle which returns its sole argument when invoked.
5073      * @param type the type of the sole parameter and return value of the desired method handle
5074      * @return a unary method handle which accepts and returns the given type
5075      * @throws NullPointerException if the argument is null
5076      * @throws IllegalArgumentException if the given type is {@code void.class}
5077      */
5078     public static MethodHandle identity(Class<?> type) {
5079         Wrapper btw = (type.isPrimitive() ? Wrapper.forPrimitiveType(type) : Wrapper.OBJECT);
5080         int pos = btw.ordinal();
5081         MethodHandle ident = IDENTITY_MHS[pos];
5082         if (ident == null) {
5083             ident = setCachedMethodHandle(IDENTITY_MHS, pos, makeIdentity(btw.primitiveType()));
5084         }
5085         if (ident.type().returnType() == type)

5090     }
5091 
5092     /**
5093      * Produces a constant method handle of the requested return type which
5094      * returns the default value for that type every time it is invoked.
5095      * The resulting constant method handle will have no side effects.
5096      * <p>The returned method handle is equivalent to {@code empty(methodType(type))}.
5097      * It is also equivalent to {@code explicitCastArguments(constant(Object.class, null), methodType(type))},
5098      * since {@code explicitCastArguments} converts {@code null} to default values.
5099      * @param type the expected return type of the desired method handle
5100      * @return a constant method handle that takes no arguments
5101      *         and returns the default value of the given type (or void, if the type is void)
5102      * @throws NullPointerException if the argument is null
5103      * @see MethodHandles#constant
5104      * @see MethodHandles#empty
5105      * @see MethodHandles#explicitCastArguments
5106      * @since 9
5107      */
5108     public static MethodHandle zero(Class<?> type) {
5109         Objects.requireNonNull(type);
5110         if (type.isPrimitive()) {
5111             return zero(Wrapper.forPrimitiveType(type), type);
5112         } else if (PrimitiveClass.isPrimitiveValueType(type)) {
5113             // singleton default value
5114             Object value = UNSAFE.uninitializedDefaultValue(type);
5115             return identity(type).bindTo(value);
5116         } else {
5117             return zero(Wrapper.OBJECT, type);
5118         }
5119     }
5120 
5121     private static MethodHandle identityOrVoid(Class<?> type) {
5122         return type == void.class ? zero(type) : identity(type);
5123     }
5124 
5125     /**
5126      * Produces a method handle of the requested type which ignores any arguments, does nothing,
5127      * and returns a suitable default depending on the return type.
5128      * That is, it returns a zero primitive value, a {@code null}, or {@code void}.
5129      * <p>The returned method handle is equivalent to
5130      * {@code dropArguments(zero(type.returnType()), 0, type.parameterList())}.
5131      *
5132      * @apiNote Given a predicate and target, a useful "if-then" construct can be produced as
5133      * {@code guardWithTest(pred, target, empty(target.type())}.
5134      * @param type the type of the desired method handle
5135      * @return a constant method handle of the given type, which returns a default value of the given return type
5136      * @throws NullPointerException if the argument is null
5137      * @see MethodHandles#zero
5138      * @see MethodHandles#constant
5139      * @since 9
5140      */
5141     public static  MethodHandle empty(MethodType type) {
5142         Objects.requireNonNull(type);
5143         return dropArgumentsTrusted(zero(type.returnType()), 0, type.ptypes());
5144     }
5145 
5146     private static final MethodHandle[] IDENTITY_MHS = new MethodHandle[Wrapper.COUNT];
5147     private static MethodHandle makeIdentity(Class<?> ptype) {
5148         MethodType mtype = MethodType.methodType(ptype, ptype);
5149         LambdaForm lform = LambdaForm.identityForm(BasicType.basicType(ptype));
5150         return MethodHandleImpl.makeIntrinsic(mtype, lform, Intrinsic.IDENTITY);
5151     }
5152 
5153     private static MethodHandle zero(Wrapper btw, Class<?> rtype) {
5154         int pos = btw.ordinal();
5155         MethodHandle zero = ZERO_MHS[pos];
5156         if (zero == null) {
5157             zero = setCachedMethodHandle(ZERO_MHS, pos, makeZero(btw.primitiveType()));
5158         }
5159         if (zero.type().returnType() == rtype)
5160             return zero;
5161         assert(btw == Wrapper.OBJECT);
5162         return makeZero(rtype);
5163     }
5164     private static final MethodHandle[] ZERO_MHS = new MethodHandle[Wrapper.COUNT];
5165     private static MethodHandle makeZero(Class<?> rtype) {
5166         MethodType mtype = methodType(rtype);
5167         LambdaForm lform = LambdaForm.zeroForm(BasicType.basicType(rtype));
5168         return MethodHandleImpl.makeIntrinsic(mtype, lform, Intrinsic.ZERO);
< prev index next >