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 "<" 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 "<" 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);
|