< prev index next >

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

Print this page

  31 import jdk.internal.org.objectweb.asm.ClassReader;
  32 import jdk.internal.org.objectweb.asm.Opcodes;
  33 import jdk.internal.org.objectweb.asm.Type;
  34 import jdk.internal.reflect.CallerSensitive;
  35 import jdk.internal.reflect.CallerSensitiveAdapter;
  36 import jdk.internal.reflect.Reflection;
  37 import jdk.internal.vm.annotation.ForceInline;
  38 import sun.invoke.util.ValueConversions;
  39 import sun.invoke.util.VerifyAccess;
  40 import sun.invoke.util.Wrapper;
  41 import sun.reflect.misc.ReflectUtil;
  42 import sun.security.util.SecurityConstants;
  43 
  44 import java.lang.constant.ConstantDescs;
  45 import java.lang.invoke.LambdaForm.BasicType;
  46 import java.lang.reflect.Constructor;
  47 import java.lang.reflect.Field;
  48 import java.lang.reflect.Member;
  49 import java.lang.reflect.Method;
  50 import java.lang.reflect.Modifier;
  51 import java.lang.reflect.ReflectPermission;
  52 import java.nio.ByteOrder;
  53 import java.security.ProtectionDomain;
  54 import java.util.ArrayList;
  55 import java.util.Arrays;
  56 import java.util.BitSet;
  57 import java.util.Iterator;
  58 import java.util.List;
  59 import java.util.Objects;
  60 import java.util.Set;
  61 import java.util.concurrent.ConcurrentHashMap;
  62 import java.util.stream.Stream;
  63 
  64 import static java.lang.invoke.LambdaForm.BasicType.V_TYPE;
  65 import static java.lang.invoke.MethodHandleImpl.Intrinsic;
  66 import static java.lang.invoke.MethodHandleNatives.Constants.*;
  67 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
  68 import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
  69 import static java.lang.invoke.MethodHandleStatics.newInternalError;
  70 import static java.lang.invoke.MethodType.methodType;
  71 

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

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

2574 ...
2575 MethodHandle MH_asList = publicLookup().findStatic(Arrays.class,
2576   "asList", methodType(List.class, Object[].class));
2577 assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());
2578          * }</pre></blockquote>
2579          * @param refc the class from which the method is accessed
2580          * @param name the name of the method
2581          * @param type the type of the method
2582          * @return the desired method handle
2583          * @throws NoSuchMethodException if the method does not exist
2584          * @throws IllegalAccessException if access checking fails,
2585          *                                or if the method is not {@code static},
2586          *                                or if the method's variable arity modifier bit
2587          *                                is set and {@code asVarargsCollector} fails
2588          * @throws    SecurityException if a security manager is present and it
2589          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2590          * @throws NullPointerException if any argument is null
2591          */
2592         public MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
2593             MemberName method = resolveOrFail(REF_invokeStatic, refc, name, type);






2594             return getDirectMethod(REF_invokeStatic, refc, method, findBoundCallerLookup(method));
2595         }
2596 
2597         /**
2598          * Produces a method handle for a virtual method.
2599          * The type of the method handle will be that of the method,
2600          * with the receiver type (usually {@code refc}) prepended.
2601          * The method and all its argument types must be accessible to the lookup object.
2602          * <p>
2603          * When called, the handle will treat the first argument as a receiver
2604          * and, for non-private methods, dispatch on the receiver's type to determine which method
2605          * implementation to enter.
2606          * For private methods the named method in {@code refc} will be invoked on the receiver.
2607          * (The dispatching action is identical with that performed by an
2608          * {@code invokevirtual} or {@code invokeinterface} instruction.)
2609          * <p>
2610          * The first argument will be of type {@code refc} if the lookup
2611          * class has full privileges to access the member.  Otherwise
2612          * the member must be {@code protected} and the first argument
2613          * will be restricted in type to the lookup class.

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







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



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

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









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

3692         }
3693 
3694         void checkSymbolicClass(Class<?> refc) throws IllegalAccessException {
3695             if (!isClassAccessible(refc)) {
3696                 throw new MemberName(refc).makeAccessException("symbolic reference class is not accessible", this);
3697             }
3698         }
3699 
3700         boolean isClassAccessible(Class<?> refc) {
3701             Objects.requireNonNull(refc);
3702             Class<?> caller = lookupClassOrNull();
3703             Class<?> type = refc;
3704             while (type.isArray()) {
3705                 type = type.getComponentType();
3706             }
3707             return caller == null || VerifyAccess.isClassAccessible(type, caller, prevLookupClass, allowedModes);
3708         }
3709 
3710         /** Check name for an illegal leading "&lt;" character. */
3711         void checkMethodName(byte refKind, String name) throws NoSuchMethodException {
3712             if (name.startsWith("<") && refKind != REF_newInvokeSpecial)
3713                 throw new NoSuchMethodException("illegal method name: "+name);



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

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

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

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

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

4285      * @param arrayClass an array type
4286      * @return a method handle which can load values from the given array type
4287      * @throws NullPointerException if the argument is null
4288      * @throws  IllegalArgumentException if arrayClass is not an array type
4289      * @jvms 6.5 {@code aaload} Instruction
4290      */
4291     public static MethodHandle arrayElementGetter(Class<?> arrayClass) throws IllegalArgumentException {
4292         return MethodHandleImpl.makeArrayElementAccessor(arrayClass, MethodHandleImpl.ArrayAccess.GET);
4293     }
4294 
4295     /**
4296      * Produces a method handle giving write access to elements of an array,
4297      * as if by the {@code astore} bytecode.
4298      * The type of the method handle will have a void return type.
4299      * Its last argument will be the array's element type.
4300      * The first and second arguments will be the array type and int.
4301      *
4302      * <p> When the returned method handle is invoked,
4303      * the array reference and array index are checked.
4304      * A {@code NullPointerException} will be thrown if the array reference
4305      * is {@code null} and an {@code ArrayIndexOutOfBoundsException} will be


4306      * thrown if the index is negative or if it is greater than or equal to
4307      * the length of the array.
4308      *
4309      * @param arrayClass the class of an array
4310      * @return a method handle which can store values into the array type
4311      * @throws NullPointerException if the argument is null
4312      * @throws IllegalArgumentException if arrayClass is not an array type
4313      * @jvms 6.5 {@code aastore} Instruction
4314      */
4315     public static MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException {
4316         return MethodHandleImpl.makeArrayElementAccessor(arrayClass, MethodHandleImpl.ArrayAccess.SET);
4317     }
4318 
4319     /**
4320      * Produces a VarHandle giving access to elements of an array of type
4321      * {@code arrayClass}.  The VarHandle's variable type is the component type
4322      * of {@code arrayClass} and the list of coordinate types is
4323      * {@code (arrayClass, int)}, where the {@code int} coordinate type
4324      * corresponds to an argument that is an index into an array.
4325      * <p>

4998             Class<?> src = newType.parameterType(i);
4999             Class<?> dst = oldType.parameterType(j);
5000             if (src != dst)
5001                 throw newIllegalArgumentException("parameter types do not match after reorder",
5002                         oldType, newType);
5003         }
5004         return true;
5005     }
5006 
5007     /**
5008      * Produces a method handle of the requested return type which returns the given
5009      * constant value every time it is invoked.
5010      * <p>
5011      * Before the method handle is returned, the passed-in value is converted to the requested type.
5012      * If the requested type is primitive, widening primitive conversions are attempted,
5013      * else reference conversions are attempted.
5014      * <p>The returned method handle is equivalent to {@code identity(type).bindTo(value)}.
5015      * @param type the return type of the desired method handle
5016      * @param value the value to return
5017      * @return a method handle of the given return type and no arguments, which always returns the given value
5018      * @throws NullPointerException if the {@code type} argument is null


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

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








5078     }
5079 
5080     private static MethodHandle identityOrVoid(Class<?> type) {
5081         return type == void.class ? zero(type) : identity(type);
5082     }
5083 
5084     /**
5085      * Produces a method handle of the requested type which ignores any arguments, does nothing,
5086      * and returns a suitable default depending on the return type.
5087      * That is, it returns a zero primitive value, a {@code null}, or {@code void}.




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

  31 import jdk.internal.org.objectweb.asm.ClassReader;
  32 import jdk.internal.org.objectweb.asm.Opcodes;
  33 import jdk.internal.org.objectweb.asm.Type;
  34 import jdk.internal.reflect.CallerSensitive;
  35 import jdk.internal.reflect.CallerSensitiveAdapter;
  36 import jdk.internal.reflect.Reflection;
  37 import jdk.internal.vm.annotation.ForceInline;
  38 import sun.invoke.util.ValueConversions;
  39 import sun.invoke.util.VerifyAccess;
  40 import sun.invoke.util.Wrapper;
  41 import sun.reflect.misc.ReflectUtil;
  42 import sun.security.util.SecurityConstants;
  43 
  44 import java.lang.constant.ConstantDescs;
  45 import java.lang.invoke.LambdaForm.BasicType;
  46 import java.lang.reflect.Constructor;
  47 import java.lang.reflect.Field;
  48 import java.lang.reflect.Member;
  49 import java.lang.reflect.Method;
  50 import java.lang.reflect.Modifier;

  51 import java.nio.ByteOrder;
  52 import java.security.ProtectionDomain;
  53 import java.util.ArrayList;
  54 import java.util.Arrays;
  55 import java.util.BitSet;
  56 import java.util.Iterator;
  57 import java.util.List;
  58 import java.util.Objects;
  59 import java.util.Set;
  60 import java.util.concurrent.ConcurrentHashMap;
  61 import java.util.stream.Stream;
  62 
  63 import static java.lang.invoke.LambdaForm.BasicType.V_TYPE;
  64 import static java.lang.invoke.MethodHandleImpl.Intrinsic;
  65 import static java.lang.invoke.MethodHandleNatives.Constants.*;
  66 import static java.lang.invoke.MethodHandleStatics.UNSAFE;
  67 import static java.lang.invoke.MethodHandleStatics.newIllegalArgumentException;
  68 import static java.lang.invoke.MethodHandleStatics.newInternalError;
  69 import static java.lang.invoke.MethodType.methodType;
  70 

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

2574 ...
2575 MethodHandle MH_asList = publicLookup().findStatic(Arrays.class,
2576   "asList", methodType(List.class, Object[].class));
2577 assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());
2578          * }</pre></blockquote>
2579          * @param refc the class from which the method is accessed
2580          * @param name the name of the method
2581          * @param type the type of the method
2582          * @return the desired method handle
2583          * @throws NoSuchMethodException if the method does not exist
2584          * @throws IllegalAccessException if access checking fails,
2585          *                                or if the method is not {@code static},
2586          *                                or if the method's variable arity modifier bit
2587          *                                is set and {@code asVarargsCollector} fails
2588          * @throws    SecurityException if a security manager is present and it
2589          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2590          * @throws NullPointerException if any argument is null
2591          */
2592         public MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
2593             MemberName method = resolveOrFail(REF_invokeStatic, refc, name, type);
2594             // resolveOrFail could return a non-static <init> method if present
2595             // detect and throw NSME before producing a MethodHandle
2596             if (!method.isStatic() && name.equals("<init>")) {
2597                 throw new NoSuchMethodException("illegal method name: " + name);
2598             }
2599 
2600             return getDirectMethod(REF_invokeStatic, refc, method, findBoundCallerLookup(method));
2601         }
2602 
2603         /**
2604          * Produces a method handle for a virtual method.
2605          * The type of the method handle will be that of the method,
2606          * with the receiver type (usually {@code refc}) prepended.
2607          * The method and all its argument types must be accessible to the lookup object.
2608          * <p>
2609          * When called, the handle will treat the first argument as a receiver
2610          * and, for non-private methods, dispatch on the receiver's type to determine which method
2611          * implementation to enter.
2612          * For private methods the named method in {@code refc} will be invoked on the receiver.
2613          * (The dispatching action is identical with that performed by an
2614          * {@code invokevirtual} or {@code invokeinterface} instruction.)
2615          * <p>
2616          * The first argument will be of type {@code refc} if the lookup
2617          * class has full privileges to access the member.  Otherwise
2618          * the member must be {@code protected} and the first argument
2619          * will be restricted in type to the lookup class.

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          * <blockquote><pre>{@code
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          * }</pre></blockquote>
2745          *
2746          * @apiNote
2747          * This method does not find a static {@code <init>} factory method as it is invoked
2748          * via {@code invokestatic} bytecode as opposed to {@code invokespecial} for an
2749          * object constructor.  To look up static {@code <init>} factory method, use
2750          * the {@link #findStatic(Class, String, MethodType) findStatic} method.
2751          *
2752          * @param refc the class or interface from which the method is accessed
2753          * @param type the type of the method, with the receiver argument omitted, and a void return type
2754          * @return the desired method handle
2755          * @throws NoSuchMethodException if the constructor does not exist
2756          * @throws IllegalAccessException if access checking fails
2757          *                                or if the method's variable arity modifier bit
2758          *                                is set and {@code asVarargsCollector} fails
2759          * @throws    SecurityException if a security manager is present and it
2760          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2761          * @throws NullPointerException if any argument is null
2762          */
2763         public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
2764             if (refc.isArray()) {
2765                 throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
2766             }
2767             if (type.returnType() != void.class) {
2768                 throw new NoSuchMethodException("Constructors must have void return type: " + refc.getName());
2769             }
2770             String name = "<init>";
2771             MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
2772             return getDirectConstructor(refc, ctor);
2773         }
2774 
2775         /**
2776          * Looks up a class by name from the lookup context defined by this {@code Lookup} object,
2777          * <a href="MethodHandles.Lookup.html#equiv">as if resolved</a> by an {@code ldc} instruction.
2778          * Such a resolution, as specified in JVMS {@jvms 5.4.3.1}, attempts to locate and load the class,
2779          * and then determines whether the class is accessible to this lookup object.
2780          * <p>
2781          * The lookup context here is determined by the {@linkplain #lookupClass() lookup class},
2782          * its class loader, and the {@linkplain #lookupModes() lookup modes}.
2783          *
2784          * @param targetName the fully qualified name of the class to be looked up.
2785          * @return the requested class.
2786          * @throws SecurityException if a security manager is present and it
2787          *                           <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2788          * @throws LinkageError if the linkage fails
2789          * @throws ClassNotFoundException if the class cannot be loaded by the lookup class' loader.

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

3717         }
3718 
3719         void checkSymbolicClass(Class<?> refc) throws IllegalAccessException {
3720             if (!isClassAccessible(refc)) {
3721                 throw new MemberName(refc).makeAccessException("symbolic reference class is not accessible", this);
3722             }
3723         }
3724 
3725         boolean isClassAccessible(Class<?> refc) {
3726             Objects.requireNonNull(refc);
3727             Class<?> caller = lookupClassOrNull();
3728             Class<?> type = refc;
3729             while (type.isArray()) {
3730                 type = type.getComponentType();
3731             }
3732             return caller == null || VerifyAccess.isClassAccessible(type, caller, prevLookupClass, allowedModes);
3733         }
3734 
3735         /** Check name for an illegal leading "&lt;" character. */
3736         void checkMethodName(byte refKind, String name) throws NoSuchMethodException {
3737             // "<init>" can only be invoked via invokespecial or it's a static init factory
3738             if (name.startsWith("<") && refKind != REF_newInvokeSpecial &&
3739                     !(refKind == REF_invokeStatic && name.equals("<init>"))) {
3740                     throw new NoSuchMethodException("illegal method name: " + name);
3741             }
3742         }
3743 
3744         /**
3745          * Find my trustable caller class if m is a caller sensitive method.
3746          * If this lookup object has original full privilege access, then the caller class is the lookupClass.
3747          * Otherwise, if m is caller-sensitive, throw IllegalAccessException.
3748          */
3749         Lookup findBoundCallerLookup(MemberName m) throws IllegalAccessException {
3750             if (MethodHandleNatives.isCallerSensitive(m) && (lookupModes() & ORIGINAL) == 0) {
3751                 // Only lookups with full privilege access are allowed to resolve caller-sensitive methods
3752                 throw new IllegalAccessException("Attempt to lookup caller-sensitive method using restricted lookup object");
3753             }
3754             return this;
3755         }
3756 
3757         /**
3758          * Returns {@code true} if this lookup has {@code PRIVATE} and {@code MODULE} access.
3759          * @return {@code true} if this lookup has {@code PRIVATE} and {@code MODULE} access.
3760          *
3761          * @deprecated This method was originally designed to test {@code PRIVATE} access

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

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

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

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

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

4312      * @param arrayClass an array type
4313      * @return a method handle which can load values from the given array type
4314      * @throws NullPointerException if the argument is null
4315      * @throws  IllegalArgumentException if arrayClass is not an array type
4316      * @jvms 6.5 {@code aaload} Instruction
4317      */
4318     public static MethodHandle arrayElementGetter(Class<?> arrayClass) throws IllegalArgumentException {
4319         return MethodHandleImpl.makeArrayElementAccessor(arrayClass, MethodHandleImpl.ArrayAccess.GET);
4320     }
4321 
4322     /**
4323      * Produces a method handle giving write access to elements of an array,
4324      * as if by the {@code astore} bytecode.
4325      * The type of the method handle will have a void return type.
4326      * Its last argument will be the array's element type.
4327      * The first and second arguments will be the array type and int.
4328      *
4329      * <p> When the returned method handle is invoked,
4330      * the array reference and array index are checked.
4331      * A {@code NullPointerException} will be thrown if the array reference
4332      * is {@code null} or if the array's element type is a {@link Class#isPrimitiveValueType()
4333      * a primitive value type} and attempts to set {@code null} in the
4334      * array element.  An {@code ArrayIndexOutOfBoundsException} will be
4335      * thrown if the index is negative or if it is greater than or equal to
4336      * the length of the array.
4337      *
4338      * @param arrayClass the class of an array
4339      * @return a method handle which can store values into the array type
4340      * @throws NullPointerException if the argument is null
4341      * @throws IllegalArgumentException if arrayClass is not an array type
4342      * @jvms 6.5 {@code aastore} Instruction
4343      */
4344     public static MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException {
4345         return MethodHandleImpl.makeArrayElementAccessor(arrayClass, MethodHandleImpl.ArrayAccess.SET);
4346     }
4347 
4348     /**
4349      * Produces a VarHandle giving access to elements of an array of type
4350      * {@code arrayClass}.  The VarHandle's variable type is the component type
4351      * of {@code arrayClass} and the list of coordinate types is
4352      * {@code (arrayClass, int)}, where the {@code int} coordinate type
4353      * corresponds to an argument that is an index into an array.
4354      * <p>

5027             Class<?> src = newType.parameterType(i);
5028             Class<?> dst = oldType.parameterType(j);
5029             if (src != dst)
5030                 throw newIllegalArgumentException("parameter types do not match after reorder",
5031                         oldType, newType);
5032         }
5033         return true;
5034     }
5035 
5036     /**
5037      * Produces a method handle of the requested return type which returns the given
5038      * constant value every time it is invoked.
5039      * <p>
5040      * Before the method handle is returned, the passed-in value is converted to the requested type.
5041      * If the requested type is primitive, widening primitive conversions are attempted,
5042      * else reference conversions are attempted.
5043      * <p>The returned method handle is equivalent to {@code identity(type).bindTo(value)}.
5044      * @param type the return type of the desired method handle
5045      * @param value the value to return
5046      * @return a method handle of the given return type and no arguments, which always returns the given value
5047      * @throws NullPointerException if the given {@code type} is null, or
5048      *         if the given {@code type} is primitive or a primitive value type
5049      *         and the given value is null
5050      * @throws ClassCastException if the value cannot be converted to the required return type
5051      * @throws IllegalArgumentException if the given type is {@code void.class}
5052      */
5053     public static MethodHandle constant(Class<?> type, Object value) {
5054         if (type.isPrimitive()) {
5055             if (type == void.class)
5056                 throw newIllegalArgumentException("void type");
5057             Wrapper w = Wrapper.forPrimitiveType(type);
5058             value = w.convert(value, type);
5059             if (w.zero().equals(value))
5060                 return zero(w, type);
5061             return insertArguments(identity(type), 0, value);
5062         } else {
5063             if (!type.isPrimitiveValueType() && value == null)
5064                 return zero(Wrapper.OBJECT, type);
5065             return identity(type).bindTo(value);
5066         }
5067     }
5068 
5069     /**
5070      * Produces a method handle which returns its sole argument when invoked.
5071      * @param type the type of the sole parameter and return value of the desired method handle
5072      * @return a unary method handle which accepts and returns the given type
5073      * @throws NullPointerException if the argument is null
5074      * @throws IllegalArgumentException if the given type is {@code void.class}
5075      */
5076     public static MethodHandle identity(Class<?> type) {
5077         Wrapper btw = (type.isPrimitive() ? Wrapper.forPrimitiveType(type) : Wrapper.OBJECT);
5078         int pos = btw.ordinal();
5079         MethodHandle ident = IDENTITY_MHS[pos];
5080         if (ident == null) {
5081             ident = setCachedMethodHandle(IDENTITY_MHS, pos, makeIdentity(btw.primitiveType()));
5082         }
5083         if (ident.type().returnType() == type)

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