< 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.util.ClassFileDumper;
  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;

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

1621          *  @return the lookup modes, which limit the kinds of access performed by this lookup object
1622          *  @see #in
1623          *  @see #dropLookupMode
1624          *
1625          *  @revised 9
1626          */
1627         public int lookupModes() {
1628             return allowedModes & ALL_MODES;
1629         }
1630 
1631         /** Embody the current class (the lookupClass) as a lookup class
1632          * for method handle creation.
1633          * Must be called by from a method in this package,
1634          * which in turn is called by a method not in this package.
1635          */
1636         Lookup(Class<?> lookupClass) {
1637             this(lookupClass, null, FULL_POWER_MODES);
1638         }
1639 
1640         private Lookup(Class<?> lookupClass, Class<?> prevLookupClass, int allowedModes) {

1641             assert prevLookupClass == null || ((allowedModes & MODULE) == 0
1642                     && prevLookupClass.getModule() != lookupClass.getModule());
1643             assert !lookupClass.isArray() && !lookupClass.isPrimitive();
1644             this.lookupClass = lookupClass;
1645             this.prevLookupClass = prevLookupClass;
1646             this.allowedModes = allowedModes;
1647         }
1648 
1649         private static Lookup newLookup(Class<?> lookupClass, Class<?> prevLookupClass, int allowedModes) {
1650             // make sure we haven't accidentally picked up a privileged class:
1651             checkUnprivilegedlookupClass(lookupClass);
1652             return new Lookup(lookupClass, prevLookupClass, allowedModes);
1653         }
1654 
1655         /**
1656          * Creates a lookup on the specified new lookup class.
1657          * The resulting object will report the specified
1658          * class as its own {@link #lookupClass() lookupClass}.
1659          *
1660          * <p>

2801          * If the returned method handle is invoked, the constructor's class will
2802          * be initialized, if it has not already been initialized.
2803          * <p><b>Example:</b>
2804          * {@snippet lang="java" :
2805 import static java.lang.invoke.MethodHandles.*;
2806 import static java.lang.invoke.MethodType.*;
2807 ...
2808 MethodHandle MH_newArrayList = publicLookup().findConstructor(
2809   ArrayList.class, methodType(void.class, Collection.class));
2810 Collection orig = Arrays.asList("x", "y");
2811 Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
2812 assert(orig != copy);
2813 assertEquals(orig, copy);
2814 // a variable-arity constructor:
2815 MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
2816   ProcessBuilder.class, methodType(void.class, String[].class));
2817 ProcessBuilder pb = (ProcessBuilder)
2818   MH_newProcessBuilder.invoke("x", "y", "z");
2819 assertEquals("[x, y, z]", pb.command().toString());
2820          * }


2821          * @param refc the class or interface from which the method is accessed
2822          * @param type the type of the method, with the receiver argument omitted, and a void return type
2823          * @return the desired method handle
2824          * @throws NoSuchMethodException if the constructor does not exist
2825          * @throws IllegalAccessException if access checking fails
2826          *                                or if the method's variable arity modifier bit
2827          *                                is set and {@code asVarargsCollector} fails
2828          * @throws    SecurityException if a security manager is present and it
2829          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2830          * @throws NullPointerException if any argument is null
2831          */
2832         public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
2833             if (refc.isArray()) {
2834                 throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
2835             }



2836             String name = ConstantDescs.INIT_NAME;
2837             MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
2838             return getDirectConstructor(refc, ctor);
2839         }
2840 
2841         /**
2842          * Looks up a class by name from the lookup context defined by this {@code Lookup} object,
2843          * <a href="MethodHandles.Lookup.html#equiv">as if resolved</a> by an {@code ldc} instruction.
2844          * Such a resolution, as specified in JVMS {@jvms 5.4.3.1}, attempts to locate and load the class,
2845          * and then determines whether the class is accessible to this lookup object.
2846          * <p>
2847          * For a class or an interface, the name is the {@linkplain ClassLoader##binary-name binary name}.
2848          * For an array class of {@code n} dimensions, the name begins with {@code n} occurrences
2849          * of {@code '['} and followed by the element type as encoded in the
2850          * {@linkplain Class##nameFormat table} specified in {@link Class#getName}.
2851          * <p>
2852          * The lookup context here is determined by the {@linkplain #lookupClass() lookup class},
2853          * its class loader, and the {@linkplain #lookupModes() lookup modes}.
2854          *
2855          * @param targetName the {@linkplain ClassLoader##binary-name binary name} of the class

3511          * arguments passed to the method handle.
3512          * <p>
3513          * If the constructor's {@code accessible} flag is not set,
3514          * access checking is performed immediately on behalf of the lookup class.
3515          * <p>
3516          * The returned method handle will have
3517          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
3518          * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
3519          * <p>
3520          * If the returned method handle is invoked, the constructor's class will
3521          * be initialized, if it has not already been initialized.
3522          * @param c the reflected constructor
3523          * @return a method handle which can invoke the reflected constructor
3524          * @throws IllegalAccessException if access checking fails
3525          *                                or if the method's variable arity modifier bit
3526          *                                is set and {@code asVarargsCollector} fails
3527          * @throws NullPointerException if the argument is null
3528          */
3529         public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException {
3530             MemberName ctor = new MemberName(c);
3531             assert(ctor.isConstructor());
3532             @SuppressWarnings("deprecation")
3533             Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this;
3534             return lookup.getDirectConstructorNoSecurityManager(ctor.getDeclaringClass(), ctor);









3535         }
3536 
3537         /**
3538          * Produces a method handle giving read access to a reflected field.
3539          * The type of the method handle will have a return type of the field's
3540          * value type.
3541          * If the field is {@code static}, the method handle will take no arguments.
3542          * Otherwise, its single argument will be the instance containing
3543          * the field.
3544          * If the {@code Field} object's {@code accessible} flag is not set,
3545          * access checking is performed immediately on behalf of the lookup class.
3546          * <p>
3547          * If the field is static, and
3548          * if the returned method handle is invoked, the field's class will
3549          * be initialized, if it has not already been initialized.
3550          * @param f the reflected field
3551          * @return a method handle which can load values from the reflected field
3552          * @throws IllegalAccessException if access checking fails
3553          * @throws NullPointerException if the argument is null
3554          */

3759                                             ReflectiveOperationException.class);
3760         }
3761 
3762         MemberName resolveOrNull(byte refKind, MemberName member) {
3763             // do this before attempting to resolve
3764             if (!isClassAccessible(member.getDeclaringClass())) {
3765                 return null;
3766             }
3767             Objects.requireNonNull(member.getName());
3768             Objects.requireNonNull(member.getType());
3769             return IMPL_NAMES.resolveOrNull(refKind, member, lookupClassOrNull(), allowedModes);
3770         }
3771 
3772         MemberName resolveOrNull(byte refKind, Class<?> refc, String name, MethodType type) {
3773             // do this before attempting to resolve
3774             if (!isClassAccessible(refc)) {
3775                 return null;
3776             }
3777             Objects.requireNonNull(type);
3778             // implicit null-check of name
3779             if (name.startsWith("<") && refKind != REF_newInvokeSpecial) {
3780                 return null;
3781             }

3782             return IMPL_NAMES.resolveOrNull(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), allowedModes);
3783         }
3784 
3785         void checkSymbolicClass(Class<?> refc) throws IllegalAccessException {
3786             if (!isClassAccessible(refc)) {
3787                 throw new MemberName(refc).makeAccessException("symbolic reference class is not accessible", this);
3788             }
3789         }
3790 
3791         boolean isClassAccessible(Class<?> refc) {
3792             Objects.requireNonNull(refc);
3793             Class<?> caller = lookupClassOrNull();
3794             Class<?> type = refc;
3795             while (type.isArray()) {
3796                 type = type.getComponentType();
3797             }
3798             return caller == null || VerifyAccess.isClassAccessible(type, caller, prevLookupClass, allowedModes);
3799         }
3800 












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

3805         }
3806 
3807         /**
3808          * Find my trustable caller class if m is a caller sensitive method.
3809          * If this lookup object has original full privilege access, then the caller class is the lookupClass.
3810          * Otherwise, if m is caller-sensitive, throw IllegalAccessException.
3811          */
3812         Lookup findBoundCallerLookup(MemberName m) throws IllegalAccessException {
3813             if (MethodHandleNatives.isCallerSensitive(m) && (lookupModes() & ORIGINAL) == 0) {
3814                 // Only lookups with full privilege access are allowed to resolve caller-sensitive methods
3815                 throw new IllegalAccessException("Attempt to lookup caller-sensitive method using restricted lookup object");
3816             }
3817             return this;
3818         }
3819 
3820         /**
3821          * Returns {@code true} if this lookup has {@code PRIVATE} and {@code MODULE} access.
3822          * @return {@code true} if this lookup has {@code PRIVATE} and {@code MODULE} access.
3823          *
3824          * @deprecated This method was originally designed to test {@code PRIVATE} access

3888 
3889             @SuppressWarnings("removal")
3890             SecurityManager smgr = System.getSecurityManager();
3891             if (smgr == null)  return;
3892 
3893             // Step 1:
3894             boolean fullPrivilegeLookup = hasFullPrivilegeAccess();
3895             if (!fullPrivilegeLookup ||
3896                 !VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
3897                 ReflectUtil.checkPackageAccess(refc);
3898             }
3899 
3900             // Step 2a:
3901             if (m.isPublic()) return;
3902             if (!fullPrivilegeLookup) {
3903                 smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
3904             }
3905 
3906             // Step 3:
3907             Class<?> defc = m.getDeclaringClass();
3908             if (!fullPrivilegeLookup && defc != refc) {
3909                 ReflectUtil.checkPackageAccess(defc);
3910             }
3911         }
3912 
3913         void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
3914             boolean wantStatic = (refKind == REF_invokeStatic);
3915             String message;
3916             if (m.isConstructor())
3917                 message = "expected a method, not a constructor";
3918             else if (!m.isMethod())
3919                 message = "expected a method";
3920             else if (wantStatic != m.isStatic())
3921                 message = wantStatic ? "expected a static method" : "expected a non-static method";
3922             else
3923                 { checkAccess(refKind, refc, m); return; }
3924             throw m.makeAccessException(message, this);
3925         }
3926 
3927         void checkField(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
3928             boolean wantStatic = !MethodHandleNatives.refKindHasReceiver(refKind);
3929             String message;
3930             if (wantStatic != m.isStatic())
3931                 message = wantStatic ? "expected a static field" : "expected a non-static field";
3932             else
3933                 { checkAccess(refKind, refc, m); return; }
3934             throw m.makeAccessException(message, this);
3935         }
3936 

3975                 throw m.makeAccessException("unexpected set of a final field", this);
3976             int requestedModes = fixmods(mods);  // adjust 0 => PACKAGE
3977             if ((requestedModes & allowedModes) != 0) {
3978                 if (VerifyAccess.isMemberAccessible(refc, m.getDeclaringClass(),
3979                                                     mods, lookupClass(), previousLookupClass(), allowedModes))
3980                     return;
3981             } else {
3982                 // Protected members can also be checked as if they were package-private.
3983                 if ((requestedModes & PROTECTED) != 0 && (allowedModes & PACKAGE) != 0
3984                         && VerifyAccess.isSamePackage(m.getDeclaringClass(), lookupClass()))
3985                     return;
3986             }
3987             throw m.makeAccessException(accessFailedMessage(refc, m), this);
3988         }
3989 
3990         String accessFailedMessage(Class<?> refc, MemberName m) {
3991             Class<?> defc = m.getDeclaringClass();
3992             int mods = m.getModifiers();
3993             // check the class first:
3994             boolean classOK = (Modifier.isPublic(defc.getModifiers()) &&
3995                                (defc == refc ||
3996                                 Modifier.isPublic(refc.getModifiers())));
3997             if (!classOK && (allowedModes & PACKAGE) != 0) {
3998                 // ignore previous lookup class to check if default package access
3999                 classOK = (VerifyAccess.isClassAccessible(defc, lookupClass(), null, FULL_POWER_MODES) &&
4000                            (defc == refc ||
4001                             VerifyAccess.isClassAccessible(refc, lookupClass(), null, FULL_POWER_MODES)));
4002             }
4003             if (!classOK)
4004                 return "class is not public";
4005             if (Modifier.isPublic(mods))
4006                 return "access to public member failed";  // (how?, module not readable?)
4007             if (Modifier.isPrivate(mods))
4008                 return "member is private";
4009             if (Modifier.isProtected(mods))
4010                 return "member is protected";
4011             return "member is private to package";
4012         }
4013 
4014         private void checkSpecialCaller(Class<?> specialCaller, Class<?> refc) throws IllegalAccessException {
4015             int allowedModes = this.allowedModes;
4016             if (allowedModes == TRUSTED)  return;
4017             if ((lookupModes() & PRIVATE) == 0
4018                 || (specialCaller != lookupClass()
4019                        // ensure non-abstract methods in superinterfaces can be special-invoked
4020                     && !(refc != null && refc.isInterface() && refc.isAssignableFrom(specialCaller))))

4057             final boolean doRestrict    = false;
4058             final boolean checkSecurity = true;
4059             return getDirectMethodCommon(REF_invokeSpecial, refc, method, checkSecurity, doRestrict, callerLookup);
4060         }
4061         /** Check access and get the requested method, eliding security manager checks. */
4062         private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Lookup callerLookup) throws IllegalAccessException {
4063             final boolean doRestrict    = true;
4064             final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
4065             return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerLookup);
4066         }
4067         /** Common code for all methods; do not call directly except from immediately above. */
4068         private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
4069                                                    boolean checkSecurity,
4070                                                    boolean doRestrict,
4071                                                    Lookup boundCaller) throws IllegalAccessException {
4072             checkMethod(refKind, refc, method);
4073             // Optionally check with the security manager; this isn't needed for unreflect* calls.
4074             if (checkSecurity)
4075                 checkSecurityManager(refc, method);
4076             assert(!method.isMethodHandleInvoke());
4077 
4078             if (refKind == REF_invokeSpecial &&
4079                 refc != lookupClass() &&
4080                 !refc.isInterface() && !lookupClass().isInterface() &&
4081                 refc != lookupClass().getSuperclass() &&
4082                 refc.isAssignableFrom(lookupClass())) {
4083                 assert(!method.getName().equals(ConstantDescs.INIT_NAME));  // not this code path
4084 
4085                 // Per JVMS 6.5, desc. of invokespecial instruction:
4086                 // If the method is in a superclass of the LC,
4087                 // and if our original search was above LC.super,
4088                 // repeat the search (symbolic lookup) from LC.super
4089                 // and continue with the direct superclass of that class,
4090                 // and so forth, until a match is found or no further superclasses exist.
4091                 // FIXME: MemberName.resolve should handle this instead.
4092                 Class<?> refcAsSuper = lookupClass();
4093                 MemberName m2;
4094                 do {
4095                     refcAsSuper = refcAsSuper.getSuperclass();
4096                     m2 = new MemberName(refcAsSuper,
4097                                         method.getName(),

4206                     throw getField.makeAccessException("caller class must be a subclass below the method", lookupClass());
4207                 }
4208                 refc = lookupClass();
4209             }
4210             return VarHandles.makeFieldHandle(getField, refc,
4211                                               this.allowedModes == TRUSTED && !getField.isTrustedFinalField());
4212         }
4213         /** Check access and get the requested constructor. */
4214         private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
4215             final boolean checkSecurity = true;
4216             return getDirectConstructorCommon(refc, ctor, checkSecurity);
4217         }
4218         /** Check access and get the requested constructor, eliding security manager checks. */
4219         private MethodHandle getDirectConstructorNoSecurityManager(Class<?> refc, MemberName ctor) throws IllegalAccessException {
4220             final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
4221             return getDirectConstructorCommon(refc, ctor, checkSecurity);
4222         }
4223         /** Common code for all constructors; do not call directly except from immediately above. */
4224         private MethodHandle getDirectConstructorCommon(Class<?> refc, MemberName ctor,
4225                                                   boolean checkSecurity) throws IllegalAccessException {
4226             assert(ctor.isConstructor());
4227             checkAccess(REF_newInvokeSpecial, refc, ctor);
4228             // Optionally check with the security manager; this isn't needed for unreflect* calls.
4229             if (checkSecurity)
4230                 checkSecurityManager(refc, ctor);
4231             assert(!MethodHandleNatives.isCallerSensitive(ctor));  // maybeBindCaller not relevant here
4232             return DirectMethodHandle.make(ctor).setVarargs(ctor);
4233         }
4234 
4235         /** Hook called from the JVM (via MethodHandleNatives) to link MH constants:
4236          */
4237         /*non-public*/
4238         MethodHandle linkMethodHandleConstant(byte refKind, Class<?> defc, String name, Object type)
4239                 throws ReflectiveOperationException {
4240             if (!(type instanceof Class || type instanceof MethodType))
4241                 throw new InternalError("unresolved MemberName");
4242             MemberName member = new MemberName(refKind, defc, name, type);
4243             MethodHandle mh = LOOKASIDE_TABLE.get(member);
4244             if (mh != null) {
4245                 checkSymbolicClass(defc);
4246                 return mh;

5112      * If the requested type is primitive, widening primitive conversions are attempted,
5113      * else reference conversions are attempted.
5114      * <p>The returned method handle is equivalent to {@code identity(type).bindTo(value)}.
5115      * @param type the return type of the desired method handle
5116      * @param value the value to return
5117      * @return a method handle of the given return type and no arguments, which always returns the given value
5118      * @throws NullPointerException if the {@code type} argument is null
5119      * @throws ClassCastException if the value cannot be converted to the required return type
5120      * @throws IllegalArgumentException if the given type is {@code void.class}
5121      */
5122     public static MethodHandle constant(Class<?> type, Object value) {
5123         if (type.isPrimitive()) {
5124             if (type == void.class)
5125                 throw newIllegalArgumentException("void type");
5126             Wrapper w = Wrapper.forPrimitiveType(type);
5127             value = w.convert(value, type);
5128             if (w.zero().equals(value))
5129                 return zero(w, type);
5130             return insertArguments(identity(type), 0, value);
5131         } else {
5132             if (value == null)
5133                 return zero(Wrapper.OBJECT, type);
5134             return identity(type).bindTo(value);
5135         }
5136     }
5137 
5138     /**
5139      * Produces a method handle which returns its sole argument when invoked.
5140      * @param type the type of the sole parameter and return value of the desired method handle
5141      * @return a unary method handle which accepts and returns the given type
5142      * @throws NullPointerException if the argument is null
5143      * @throws IllegalArgumentException if the given type is {@code void.class}
5144      */
5145     public static MethodHandle identity(Class<?> type) {
5146         Wrapper btw = (type.isPrimitive() ? Wrapper.forPrimitiveType(type) : Wrapper.OBJECT);
5147         int pos = btw.ordinal();
5148         MethodHandle ident = IDENTITY_MHS[pos];
5149         if (ident == null) {
5150             ident = setCachedMethodHandle(IDENTITY_MHS, pos, makeIdentity(btw.primitiveType()));
5151         }
5152         if (ident.type().returnType() == type)

5157     }
5158 
5159     /**
5160      * Produces a constant method handle of the requested return type which
5161      * returns the default value for that type every time it is invoked.
5162      * The resulting constant method handle will have no side effects.
5163      * <p>The returned method handle is equivalent to {@code empty(methodType(type))}.
5164      * It is also equivalent to {@code explicitCastArguments(constant(Object.class, null), methodType(type))},
5165      * since {@code explicitCastArguments} converts {@code null} to default values.
5166      * @param type the expected return type of the desired method handle
5167      * @return a constant method handle that takes no arguments
5168      *         and returns the default value of the given type (or void, if the type is void)
5169      * @throws NullPointerException if the argument is null
5170      * @see MethodHandles#constant
5171      * @see MethodHandles#empty
5172      * @see MethodHandles#explicitCastArguments
5173      * @since 9
5174      */
5175     public static MethodHandle zero(Class<?> type) {
5176         Objects.requireNonNull(type);
5177         return type.isPrimitive() ?  zero(Wrapper.forPrimitiveType(type), type) : zero(Wrapper.OBJECT, type);








5178     }
5179 
5180     private static MethodHandle identityOrVoid(Class<?> type) {
5181         return type == void.class ? zero(type) : identity(type);
5182     }
5183 
5184     /**
5185      * Produces a method handle of the requested type which ignores any arguments, does nothing,
5186      * and returns a suitable default depending on the return type.
5187      * That is, it returns a zero primitive value, a {@code null}, or {@code void}.
5188      * <p>The returned method handle is equivalent to
5189      * {@code dropArguments(zero(type.returnType()), 0, type.parameterList())}.
5190      *
5191      * @apiNote Given a predicate and target, a useful "if-then" construct can be produced as
5192      * {@code guardWithTest(pred, target, empty(target.type())}.
5193      * @param type the type of the desired method handle
5194      * @return a constant method handle of the given type, which returns a default value of the given return type
5195      * @throws NullPointerException if the argument is null
5196      * @see MethodHandles#zero
5197      * @see MethodHandles#constant
5198      * @since 9
5199      */
5200     public static  MethodHandle empty(MethodType type) {
5201         Objects.requireNonNull(type);
5202         return dropArgumentsTrusted(zero(type.returnType()), 0, type.ptypes());
5203     }
5204 
5205     private static final MethodHandle[] IDENTITY_MHS = new MethodHandle[Wrapper.COUNT];
5206     private static MethodHandle makeIdentity(Class<?> ptype) {
5207         MethodType mtype = methodType(ptype, ptype);
5208         LambdaForm lform = LambdaForm.identityForm(BasicType.basicType(ptype));
5209         return MethodHandleImpl.makeIntrinsic(mtype, lform, Intrinsic.IDENTITY);
5210     }
5211 
5212     private static MethodHandle zero(Wrapper btw, Class<?> rtype) {
5213         int pos = btw.ordinal();
5214         MethodHandle zero = ZERO_MHS[pos];
5215         if (zero == null) {
5216             zero = setCachedMethodHandle(ZERO_MHS, pos, makeZero(btw.primitiveType()));
5217         }
5218         if (zero.type().returnType() == rtype)
5219             return zero;
5220         assert(btw == Wrapper.OBJECT);
5221         return makeZero(rtype);
5222     }
5223     private static final MethodHandle[] ZERO_MHS = new MethodHandle[Wrapper.COUNT];
5224     private static MethodHandle makeZero(Class<?> rtype) {
5225         MethodType mtype = methodType(rtype);
5226         LambdaForm lform = LambdaForm.zeroForm(BasicType.basicType(rtype));
5227         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.util.ClassFileDumper;
  41 import jdk.internal.vm.annotation.ForceInline;
  42 import sun.invoke.util.ValueConversions;
  43 import sun.invoke.util.VerifyAccess;
  44 import sun.invoke.util.Wrapper;
  45 import sun.reflect.misc.ReflectUtil;
  46 import sun.security.util.SecurityConstants;
  47 
  48 import java.lang.constant.ConstantDescs;
  49 import java.lang.foreign.GroupLayout;

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

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

2803          * If the returned method handle is invoked, the constructor's class will
2804          * be initialized, if it has not already been initialized.
2805          * <p><b>Example:</b>
2806          * {@snippet lang="java" :
2807 import static java.lang.invoke.MethodHandles.*;
2808 import static java.lang.invoke.MethodType.*;
2809 ...
2810 MethodHandle MH_newArrayList = publicLookup().findConstructor(
2811   ArrayList.class, methodType(void.class, Collection.class));
2812 Collection orig = Arrays.asList("x", "y");
2813 Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
2814 assert(orig != copy);
2815 assertEquals(orig, copy);
2816 // a variable-arity constructor:
2817 MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
2818   ProcessBuilder.class, methodType(void.class, String[].class));
2819 ProcessBuilder pb = (ProcessBuilder)
2820   MH_newProcessBuilder.invoke("x", "y", "z");
2821 assertEquals("[x, y, z]", pb.command().toString());
2822          * }
2823          *
2824          *
2825          * @param refc the class or interface from which the method is accessed
2826          * @param type the type of the method, with the receiver argument omitted, and a void return type
2827          * @return the desired method handle
2828          * @throws NoSuchMethodException if the constructor does not exist
2829          * @throws IllegalAccessException if access checking fails
2830          *                                or if the method's variable arity modifier bit
2831          *                                is set and {@code asVarargsCollector} fails
2832          * @throws    SecurityException if a security manager is present and it
2833          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2834          * @throws NullPointerException if any argument is null
2835          */
2836         public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
2837             if (refc.isArray()) {
2838                 throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
2839             }
2840             if (type.returnType() != void.class) {
2841                 throw new NoSuchMethodException("Constructors must have void return type: " + refc.getName());
2842             }
2843             String name = ConstantDescs.INIT_NAME;
2844             MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
2845             return getDirectConstructor(refc, ctor);
2846         }
2847 
2848         /**
2849          * Looks up a class by name from the lookup context defined by this {@code Lookup} object,
2850          * <a href="MethodHandles.Lookup.html#equiv">as if resolved</a> by an {@code ldc} instruction.
2851          * Such a resolution, as specified in JVMS {@jvms 5.4.3.1}, attempts to locate and load the class,
2852          * and then determines whether the class is accessible to this lookup object.
2853          * <p>
2854          * For a class or an interface, the name is the {@linkplain ClassLoader##binary-name binary name}.
2855          * For an array class of {@code n} dimensions, the name begins with {@code n} occurrences
2856          * of {@code '['} and followed by the element type as encoded in the
2857          * {@linkplain Class##nameFormat table} specified in {@link Class#getName}.
2858          * <p>
2859          * The lookup context here is determined by the {@linkplain #lookupClass() lookup class},
2860          * its class loader, and the {@linkplain #lookupModes() lookup modes}.
2861          *
2862          * @param targetName the {@linkplain ClassLoader##binary-name binary name} of the class

3518          * arguments passed to the method handle.
3519          * <p>
3520          * If the constructor's {@code accessible} flag is not set,
3521          * access checking is performed immediately on behalf of the lookup class.
3522          * <p>
3523          * The returned method handle will have
3524          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
3525          * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
3526          * <p>
3527          * If the returned method handle is invoked, the constructor's class will
3528          * be initialized, if it has not already been initialized.
3529          * @param c the reflected constructor
3530          * @return a method handle which can invoke the reflected constructor
3531          * @throws IllegalAccessException if access checking fails
3532          *                                or if the method's variable arity modifier bit
3533          *                                is set and {@code asVarargsCollector} fails
3534          * @throws NullPointerException if the argument is null
3535          */
3536         public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException {
3537             MemberName ctor = new MemberName(c);
3538             assert(ctor.isObjectConstructor() || ctor.isStaticValueFactoryMethod());
3539             @SuppressWarnings("deprecation")
3540             Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this;
3541             Class<?> defc = c.getDeclaringClass();
3542             if (ctor.isObjectConstructor()) {
3543                 assert(ctor.getMethodType().returnType() == void.class);
3544                 return lookup.getDirectConstructorNoSecurityManager(defc, ctor);
3545             } else {
3546                 // static init factory is a static method
3547                 assert(ctor.isMethod() && ctor.getMethodType().returnType() == defc && ctor.getReferenceKind() == REF_invokeStatic) : ctor.toString();
3548                 assert(!MethodHandleNatives.isCallerSensitive(ctor));  // must not be caller-sensitive
3549                 return lookup.getDirectMethodNoSecurityManager(ctor.getReferenceKind(), defc, ctor, lookup);
3550             }
3551         }
3552 
3553         /**
3554          * Produces a method handle giving read access to a reflected field.
3555          * The type of the method handle will have a return type of the field's
3556          * value type.
3557          * If the field is {@code static}, the method handle will take no arguments.
3558          * Otherwise, its single argument will be the instance containing
3559          * the field.
3560          * If the {@code Field} object's {@code accessible} flag is not set,
3561          * access checking is performed immediately on behalf of the lookup class.
3562          * <p>
3563          * If the field is static, and
3564          * if the returned method handle is invoked, the field's class will
3565          * be initialized, if it has not already been initialized.
3566          * @param f the reflected field
3567          * @return a method handle which can load values from the reflected field
3568          * @throws IllegalAccessException if access checking fails
3569          * @throws NullPointerException if the argument is null
3570          */

3775                                             ReflectiveOperationException.class);
3776         }
3777 
3778         MemberName resolveOrNull(byte refKind, MemberName member) {
3779             // do this before attempting to resolve
3780             if (!isClassAccessible(member.getDeclaringClass())) {
3781                 return null;
3782             }
3783             Objects.requireNonNull(member.getName());
3784             Objects.requireNonNull(member.getType());
3785             return IMPL_NAMES.resolveOrNull(refKind, member, lookupClassOrNull(), allowedModes);
3786         }
3787 
3788         MemberName resolveOrNull(byte refKind, Class<?> refc, String name, MethodType type) {
3789             // do this before attempting to resolve
3790             if (!isClassAccessible(refc)) {
3791                 return null;
3792             }
3793             Objects.requireNonNull(type);
3794             // implicit null-check of name
3795             if (isIllegalMethodName(refKind, name)) {
3796                 return null;
3797             }
3798 
3799             return IMPL_NAMES.resolveOrNull(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), allowedModes);
3800         }
3801 
3802         void checkSymbolicClass(Class<?> refc) throws IllegalAccessException {
3803             if (!isClassAccessible(refc)) {
3804                 throw new MemberName(refc).makeAccessException("symbolic reference class is not accessible", this);
3805             }
3806         }
3807 
3808         boolean isClassAccessible(Class<?> refc) {
3809             Objects.requireNonNull(refc);
3810             Class<?> caller = lookupClassOrNull();
3811             Class<?> type = refc;
3812             while (type.isArray()) {
3813                 type = type.getComponentType();
3814             }
3815             return caller == null || VerifyAccess.isClassAccessible(type, caller, prevLookupClass, allowedModes);
3816         }
3817 
3818         /*
3819          * "<init>" can only be invoked via invokespecial
3820          * "<vnew>" factory can only invoked via invokestatic
3821          */
3822         boolean isIllegalMethodName(byte refKind, String name) {
3823             if (name.startsWith("<")) {
3824                 return MemberName.VALUE_FACTORY_NAME.equals(name) ? refKind != REF_invokeStatic
3825                                                                   : refKind != REF_newInvokeSpecial;
3826             }
3827             return false;
3828         }
3829 
3830         /** Check name for an illegal leading "&lt;" character. */
3831         void checkMethodName(byte refKind, String name) throws NoSuchMethodException {
3832             if (isIllegalMethodName(refKind, name)) {
3833                 throw new NoSuchMethodException("illegal method name: " + name + " " + refKind);
3834             }
3835         }
3836 
3837         /**
3838          * Find my trustable caller class if m is a caller sensitive method.
3839          * If this lookup object has original full privilege access, then the caller class is the lookupClass.
3840          * Otherwise, if m is caller-sensitive, throw IllegalAccessException.
3841          */
3842         Lookup findBoundCallerLookup(MemberName m) throws IllegalAccessException {
3843             if (MethodHandleNatives.isCallerSensitive(m) && (lookupModes() & ORIGINAL) == 0) {
3844                 // Only lookups with full privilege access are allowed to resolve caller-sensitive methods
3845                 throw new IllegalAccessException("Attempt to lookup caller-sensitive method using restricted lookup object");
3846             }
3847             return this;
3848         }
3849 
3850         /**
3851          * Returns {@code true} if this lookup has {@code PRIVATE} and {@code MODULE} access.
3852          * @return {@code true} if this lookup has {@code PRIVATE} and {@code MODULE} access.
3853          *
3854          * @deprecated This method was originally designed to test {@code PRIVATE} access

3918 
3919             @SuppressWarnings("removal")
3920             SecurityManager smgr = System.getSecurityManager();
3921             if (smgr == null)  return;
3922 
3923             // Step 1:
3924             boolean fullPrivilegeLookup = hasFullPrivilegeAccess();
3925             if (!fullPrivilegeLookup ||
3926                 !VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
3927                 ReflectUtil.checkPackageAccess(refc);
3928             }
3929 
3930             // Step 2a:
3931             if (m.isPublic()) return;
3932             if (!fullPrivilegeLookup) {
3933                 smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
3934             }
3935 
3936             // Step 3:
3937             Class<?> defc = m.getDeclaringClass();
3938             if (!fullPrivilegeLookup && PrimitiveClass.asPrimaryType(defc) != PrimitiveClass.asPrimaryType(refc)) {
3939                 ReflectUtil.checkPackageAccess(defc);
3940             }
3941         }
3942 
3943         void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
3944             boolean wantStatic = (refKind == REF_invokeStatic);
3945             String message;
3946             if (m.isObjectConstructor())
3947                 message = "expected a method, not a constructor";
3948             else if (!m.isMethod())
3949                 message = "expected a method";
3950             else if (wantStatic != m.isStatic())
3951                 message = wantStatic ? "expected a static method" : "expected a non-static method";
3952             else
3953                 { checkAccess(refKind, refc, m); return; }
3954             throw m.makeAccessException(message, this);
3955         }
3956 
3957         void checkField(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
3958             boolean wantStatic = !MethodHandleNatives.refKindHasReceiver(refKind);
3959             String message;
3960             if (wantStatic != m.isStatic())
3961                 message = wantStatic ? "expected a static field" : "expected a non-static field";
3962             else
3963                 { checkAccess(refKind, refc, m); return; }
3964             throw m.makeAccessException(message, this);
3965         }
3966 

4005                 throw m.makeAccessException("unexpected set of a final field", this);
4006             int requestedModes = fixmods(mods);  // adjust 0 => PACKAGE
4007             if ((requestedModes & allowedModes) != 0) {
4008                 if (VerifyAccess.isMemberAccessible(refc, m.getDeclaringClass(),
4009                                                     mods, lookupClass(), previousLookupClass(), allowedModes))
4010                     return;
4011             } else {
4012                 // Protected members can also be checked as if they were package-private.
4013                 if ((requestedModes & PROTECTED) != 0 && (allowedModes & PACKAGE) != 0
4014                         && VerifyAccess.isSamePackage(m.getDeclaringClass(), lookupClass()))
4015                     return;
4016             }
4017             throw m.makeAccessException(accessFailedMessage(refc, m), this);
4018         }
4019 
4020         String accessFailedMessage(Class<?> refc, MemberName m) {
4021             Class<?> defc = m.getDeclaringClass();
4022             int mods = m.getModifiers();
4023             // check the class first:
4024             boolean classOK = (Modifier.isPublic(defc.getModifiers()) &&
4025                                (PrimitiveClass.asPrimaryType(defc) == PrimitiveClass.asPrimaryType(refc) ||
4026                                 Modifier.isPublic(refc.getModifiers())));
4027             if (!classOK && (allowedModes & PACKAGE) != 0) {
4028                 // ignore previous lookup class to check if default package access
4029                 classOK = (VerifyAccess.isClassAccessible(defc, lookupClass(), null, FULL_POWER_MODES) &&
4030                            (PrimitiveClass.asPrimaryType(defc) == PrimitiveClass.asPrimaryType(refc) ||
4031                             VerifyAccess.isClassAccessible(refc, lookupClass(), null, FULL_POWER_MODES)));
4032             }
4033             if (!classOK)
4034                 return "class is not public";
4035             if (Modifier.isPublic(mods))
4036                 return "access to public member failed";  // (how?, module not readable?)
4037             if (Modifier.isPrivate(mods))
4038                 return "member is private";
4039             if (Modifier.isProtected(mods))
4040                 return "member is protected";
4041             return "member is private to package";
4042         }
4043 
4044         private void checkSpecialCaller(Class<?> specialCaller, Class<?> refc) throws IllegalAccessException {
4045             int allowedModes = this.allowedModes;
4046             if (allowedModes == TRUSTED)  return;
4047             if ((lookupModes() & PRIVATE) == 0
4048                 || (specialCaller != lookupClass()
4049                        // ensure non-abstract methods in superinterfaces can be special-invoked
4050                     && !(refc != null && refc.isInterface() && refc.isAssignableFrom(specialCaller))))

4087             final boolean doRestrict    = false;
4088             final boolean checkSecurity = true;
4089             return getDirectMethodCommon(REF_invokeSpecial, refc, method, checkSecurity, doRestrict, callerLookup);
4090         }
4091         /** Check access and get the requested method, eliding security manager checks. */
4092         private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Lookup callerLookup) throws IllegalAccessException {
4093             final boolean doRestrict    = true;
4094             final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
4095             return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerLookup);
4096         }
4097         /** Common code for all methods; do not call directly except from immediately above. */
4098         private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
4099                                                    boolean checkSecurity,
4100                                                    boolean doRestrict,
4101                                                    Lookup boundCaller) throws IllegalAccessException {
4102             checkMethod(refKind, refc, method);
4103             // Optionally check with the security manager; this isn't needed for unreflect* calls.
4104             if (checkSecurity)
4105                 checkSecurityManager(refc, method);
4106             assert(!method.isMethodHandleInvoke());

4107             if (refKind == REF_invokeSpecial &&
4108                 refc != lookupClass() &&
4109                 !refc.isInterface() && !lookupClass().isInterface() &&
4110                 refc != lookupClass().getSuperclass() &&
4111                 refc.isAssignableFrom(lookupClass())) {
4112                 assert(!method.getName().equals(ConstantDescs.INIT_NAME));  // not this code path
4113 
4114                 // Per JVMS 6.5, desc. of invokespecial instruction:
4115                 // If the method is in a superclass of the LC,
4116                 // and if our original search was above LC.super,
4117                 // repeat the search (symbolic lookup) from LC.super
4118                 // and continue with the direct superclass of that class,
4119                 // and so forth, until a match is found or no further superclasses exist.
4120                 // FIXME: MemberName.resolve should handle this instead.
4121                 Class<?> refcAsSuper = lookupClass();
4122                 MemberName m2;
4123                 do {
4124                     refcAsSuper = refcAsSuper.getSuperclass();
4125                     m2 = new MemberName(refcAsSuper,
4126                                         method.getName(),

4235                     throw getField.makeAccessException("caller class must be a subclass below the method", lookupClass());
4236                 }
4237                 refc = lookupClass();
4238             }
4239             return VarHandles.makeFieldHandle(getField, refc,
4240                                               this.allowedModes == TRUSTED && !getField.isTrustedFinalField());
4241         }
4242         /** Check access and get the requested constructor. */
4243         private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
4244             final boolean checkSecurity = true;
4245             return getDirectConstructorCommon(refc, ctor, checkSecurity);
4246         }
4247         /** Check access and get the requested constructor, eliding security manager checks. */
4248         private MethodHandle getDirectConstructorNoSecurityManager(Class<?> refc, MemberName ctor) throws IllegalAccessException {
4249             final boolean checkSecurity = false;  // not needed for reflection or for linking CONSTANT_MH constants
4250             return getDirectConstructorCommon(refc, ctor, checkSecurity);
4251         }
4252         /** Common code for all constructors; do not call directly except from immediately above. */
4253         private MethodHandle getDirectConstructorCommon(Class<?> refc, MemberName ctor,
4254                                                   boolean checkSecurity) throws IllegalAccessException {
4255             assert(ctor.isObjectConstructor());
4256             checkAccess(REF_newInvokeSpecial, refc, ctor);
4257             // Optionally check with the security manager; this isn't needed for unreflect* calls.
4258             if (checkSecurity)
4259                 checkSecurityManager(refc, ctor);
4260             assert(!MethodHandleNatives.isCallerSensitive(ctor));  // maybeBindCaller not relevant here
4261             return DirectMethodHandle.make(ctor).setVarargs(ctor);
4262         }
4263 
4264         /** Hook called from the JVM (via MethodHandleNatives) to link MH constants:
4265          */
4266         /*non-public*/
4267         MethodHandle linkMethodHandleConstant(byte refKind, Class<?> defc, String name, Object type)
4268                 throws ReflectiveOperationException {
4269             if (!(type instanceof Class || type instanceof MethodType))
4270                 throw new InternalError("unresolved MemberName");
4271             MemberName member = new MemberName(refKind, defc, name, type);
4272             MethodHandle mh = LOOKASIDE_TABLE.get(member);
4273             if (mh != null) {
4274                 checkSymbolicClass(defc);
4275                 return mh;

5141      * If the requested type is primitive, widening primitive conversions are attempted,
5142      * else reference conversions are attempted.
5143      * <p>The returned method handle is equivalent to {@code identity(type).bindTo(value)}.
5144      * @param type the return type of the desired method handle
5145      * @param value the value to return
5146      * @return a method handle of the given return type and no arguments, which always returns the given value
5147      * @throws NullPointerException if the {@code type} argument is null
5148      * @throws ClassCastException if the value cannot be converted to the required return type
5149      * @throws IllegalArgumentException if the given type is {@code void.class}
5150      */
5151     public static MethodHandle constant(Class<?> type, Object value) {
5152         if (type.isPrimitive()) {
5153             if (type == void.class)
5154                 throw newIllegalArgumentException("void type");
5155             Wrapper w = Wrapper.forPrimitiveType(type);
5156             value = w.convert(value, type);
5157             if (w.zero().equals(value))
5158                 return zero(w, type);
5159             return insertArguments(identity(type), 0, value);
5160         } else {
5161             if (!PrimitiveClass.isPrimitiveValueType(type) && value == null)
5162                 return zero(Wrapper.OBJECT, type);
5163             return identity(type).bindTo(value);
5164         }
5165     }
5166 
5167     /**
5168      * Produces a method handle which returns its sole argument when invoked.
5169      * @param type the type of the sole parameter and return value of the desired method handle
5170      * @return a unary method handle which accepts and returns the given type
5171      * @throws NullPointerException if the argument is null
5172      * @throws IllegalArgumentException if the given type is {@code void.class}
5173      */
5174     public static MethodHandle identity(Class<?> type) {
5175         Wrapper btw = (type.isPrimitive() ? Wrapper.forPrimitiveType(type) : Wrapper.OBJECT);
5176         int pos = btw.ordinal();
5177         MethodHandle ident = IDENTITY_MHS[pos];
5178         if (ident == null) {
5179             ident = setCachedMethodHandle(IDENTITY_MHS, pos, makeIdentity(btw.primitiveType()));
5180         }
5181         if (ident.type().returnType() == type)

5186     }
5187 
5188     /**
5189      * Produces a constant method handle of the requested return type which
5190      * returns the default value for that type every time it is invoked.
5191      * The resulting constant method handle will have no side effects.
5192      * <p>The returned method handle is equivalent to {@code empty(methodType(type))}.
5193      * It is also equivalent to {@code explicitCastArguments(constant(Object.class, null), methodType(type))},
5194      * since {@code explicitCastArguments} converts {@code null} to default values.
5195      * @param type the expected return type of the desired method handle
5196      * @return a constant method handle that takes no arguments
5197      *         and returns the default value of the given type (or void, if the type is void)
5198      * @throws NullPointerException if the argument is null
5199      * @see MethodHandles#constant
5200      * @see MethodHandles#empty
5201      * @see MethodHandles#explicitCastArguments
5202      * @since 9
5203      */
5204     public static MethodHandle zero(Class<?> type) {
5205         Objects.requireNonNull(type);
5206         if (type.isPrimitive()) {
5207             return zero(Wrapper.forPrimitiveType(type), type);
5208         } else if (PrimitiveClass.isPrimitiveValueType(type)) {
5209             // singleton default value
5210             Object value = UNSAFE.uninitializedDefaultValue(type);
5211             return identity(type).bindTo(value);
5212         } else {
5213             return zero(Wrapper.OBJECT, type);
5214         }
5215     }
5216 
5217     private static MethodHandle identityOrVoid(Class<?> type) {
5218         return type == void.class ? zero(type) : identity(type);
5219     }
5220 
5221     /**
5222      * Produces a method handle of the requested type which ignores any arguments, does nothing,
5223      * and returns a suitable default depending on the return type.
5224      * That is, it returns a zero primitive value, a {@code null}, or {@code void}.
5225      * <p>The returned method handle is equivalent to
5226      * {@code dropArguments(zero(type.returnType()), 0, type.parameterList())}.
5227      *
5228      * @apiNote Given a predicate and target, a useful "if-then" construct can be produced as
5229      * {@code guardWithTest(pred, target, empty(target.type())}.
5230      * @param type the type of the desired method handle
5231      * @return a constant method handle of the given type, which returns a default value of the given return type
5232      * @throws NullPointerException if the argument is null
5233      * @see MethodHandles#zero
5234      * @see MethodHandles#constant
5235      * @since 9
5236      */
5237     public static  MethodHandle empty(MethodType type) {
5238         Objects.requireNonNull(type);
5239         return dropArgumentsTrusted(zero(type.returnType()), 0, type.ptypes());
5240     }
5241 
5242     private static final MethodHandle[] IDENTITY_MHS = new MethodHandle[Wrapper.COUNT];
5243     private static MethodHandle makeIdentity(Class<?> ptype) {
5244         MethodType mtype = MethodType.methodType(ptype, ptype);
5245         LambdaForm lform = LambdaForm.identityForm(BasicType.basicType(ptype));
5246         return MethodHandleImpl.makeIntrinsic(mtype, lform, Intrinsic.IDENTITY);
5247     }
5248 
5249     private static MethodHandle zero(Wrapper btw, Class<?> rtype) {
5250         int pos = btw.ordinal();
5251         MethodHandle zero = ZERO_MHS[pos];
5252         if (zero == null) {
5253             zero = setCachedMethodHandle(ZERO_MHS, pos, makeZero(btw.primitiveType()));
5254         }
5255         if (zero.type().returnType() == rtype)
5256             return zero;
5257         assert(btw == Wrapper.OBJECT);
5258         return makeZero(rtype);
5259     }
5260     private static final MethodHandle[] ZERO_MHS = new MethodHandle[Wrapper.COUNT];
5261     private static MethodHandle makeZero(Class<?> rtype) {
5262         MethodType mtype = methodType(rtype);
5263         LambdaForm lform = LambdaForm.zeroForm(BasicType.basicType(rtype));
5264         return MethodHandleImpl.makeIntrinsic(mtype, lform, Intrinsic.ZERO);
< prev index next >