9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.invoke;
27
28 import jdk.internal.access.SharedSecrets;
29 import jdk.internal.foreign.Utils;
30 import jdk.internal.javac.PreviewFeature;
31 import jdk.internal.misc.Unsafe;
32 import jdk.internal.misc.VM;
33 import jdk.internal.org.objectweb.asm.ClassReader;
34 import jdk.internal.org.objectweb.asm.Opcodes;
35 import jdk.internal.org.objectweb.asm.Type;
36 import jdk.internal.reflect.CallerSensitive;
37 import jdk.internal.reflect.CallerSensitiveAdapter;
38 import jdk.internal.reflect.Reflection;
39 import jdk.internal.util.ClassFileDumper;
40 import jdk.internal.vm.annotation.ForceInline;
41 import sun.invoke.util.ValueConversions;
42 import sun.invoke.util.VerifyAccess;
43 import sun.invoke.util.Wrapper;
44 import sun.reflect.misc.ReflectUtil;
45 import sun.security.util.SecurityConstants;
46
47 import java.lang.constant.ConstantDescs;
48 import java.lang.foreign.GroupLayout;
696 * If the desired member is {@code protected}, the usual JVM rules apply,
697 * including the requirement that the lookup class must either be in the
698 * same package as the desired member, or must inherit that member.
699 * (See the Java Virtual Machine Specification, sections {@jvms
700 * 4.9.2}, {@jvms 5.4.3.5}, and {@jvms 6.4}.)
701 * In addition, if the desired member is a non-static field or method
702 * in a different package, the resulting method handle may only be applied
703 * to objects of the lookup class or one of its subclasses.
704 * This requirement is enforced by narrowing the type of the leading
705 * {@code this} parameter from {@code C}
706 * (which will necessarily be a superclass of the lookup class)
707 * to the lookup class itself.
708 * <p>
709 * The JVM imposes a similar requirement on {@code invokespecial} instruction,
710 * that the receiver argument must match both the resolved method <em>and</em>
711 * the current class. Again, this requirement is enforced by narrowing the
712 * type of the leading parameter to the resulting method handle.
713 * (See the Java Virtual Machine Specification, section {@jvms 4.10.1.9}.)
714 * <p>
715 * The JVM represents constructors and static initializer blocks as internal methods
716 * with special names ({@value ConstantDescs#INIT_NAME} and {@value
717 * ConstantDescs#CLASS_INIT_NAME}).
718 * The internal syntax of invocation instructions allows them to refer to such internal
719 * methods as if they were normal methods, but the JVM bytecode verifier rejects them.
720 * A lookup of such an internal method will produce a {@code NoSuchMethodException}.
721 * <p>
722 * If the relationship between nested types is expressed directly through the
723 * {@code NestHost} and {@code NestMembers} attributes
724 * (see the Java Virtual Machine Specification, sections {@jvms
725 * 4.7.28} and {@jvms 4.7.29}),
726 * then the associated {@code Lookup} object provides direct access to
727 * the lookup class and all of its nestmates
728 * (see {@link java.lang.Class#getNestHost Class.getNestHost}).
729 * Otherwise, access between nested classes is obtained by the Java compiler creating
730 * a wrapper method to access a private method of another class in the same nest.
731 * For example, a nested class {@code C.D}
732 * can access private members within other related classes such as
733 * {@code C}, {@code C.D.E}, or {@code C.B},
734 * but the Java compiler may need to generate wrapper methods in
735 * those related classes. In such cases, a {@code Lookup} object on
736 * {@code C.E} would be unable to access those private members.
737 * A workaround for this limitation is the {@link Lookup#in Lookup.in} method,
1621 * @return the lookup modes, which limit the kinds of access performed by this lookup object
1622 * @see #in
1623 * @see #dropLookupMode
1624 *
1625 * @revised 9
1626 */
1627 public int lookupModes() {
1628 return allowedModes & ALL_MODES;
1629 }
1630
1631 /** Embody the current class (the lookupClass) as a lookup class
1632 * for method handle creation.
1633 * Must be called by from a method in this package,
1634 * which in turn is called by a method not in this package.
1635 */
1636 Lookup(Class<?> lookupClass) {
1637 this(lookupClass, null, FULL_POWER_MODES);
1638 }
1639
1640 private Lookup(Class<?> lookupClass, Class<?> prevLookupClass, int allowedModes) {
1641 assert prevLookupClass == null || ((allowedModes & MODULE) == 0
1642 && prevLookupClass.getModule() != lookupClass.getModule());
1643 assert !lookupClass.isArray() && !lookupClass.isPrimitive();
1644 this.lookupClass = lookupClass;
1645 this.prevLookupClass = prevLookupClass;
1646 this.allowedModes = allowedModes;
1647 }
1648
1649 private static Lookup newLookup(Class<?> lookupClass, Class<?> prevLookupClass, int allowedModes) {
1650 // make sure we haven't accidentally picked up a privileged class:
1651 checkUnprivilegedlookupClass(lookupClass);
1652 return new Lookup(lookupClass, prevLookupClass, allowedModes);
1653 }
1654
1655 /**
1656 * Creates a lookup on the specified new lookup class.
1657 * The resulting object will report the specified
1658 * class as its own {@link #lookupClass() lookupClass}.
1659 *
1660 * <p>
2801 * If the returned method handle is invoked, the constructor's class will
2802 * be initialized, if it has not already been initialized.
2803 * <p><b>Example:</b>
2804 * {@snippet lang="java" :
2805 import static java.lang.invoke.MethodHandles.*;
2806 import static java.lang.invoke.MethodType.*;
2807 ...
2808 MethodHandle MH_newArrayList = publicLookup().findConstructor(
2809 ArrayList.class, methodType(void.class, Collection.class));
2810 Collection orig = Arrays.asList("x", "y");
2811 Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
2812 assert(orig != copy);
2813 assertEquals(orig, copy);
2814 // a variable-arity constructor:
2815 MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
2816 ProcessBuilder.class, methodType(void.class, String[].class));
2817 ProcessBuilder pb = (ProcessBuilder)
2818 MH_newProcessBuilder.invoke("x", "y", "z");
2819 assertEquals("[x, y, z]", pb.command().toString());
2820 * }
2821 * @param refc the class or interface from which the method is accessed
2822 * @param type the type of the method, with the receiver argument omitted, and a void return type
2823 * @return the desired method handle
2824 * @throws NoSuchMethodException if the constructor does not exist
2825 * @throws IllegalAccessException if access checking fails
2826 * or if the method's variable arity modifier bit
2827 * is set and {@code asVarargsCollector} fails
2828 * @throws SecurityException if a security manager is present and it
2829 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2830 * @throws NullPointerException if any argument is null
2831 */
2832 public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
2833 if (refc.isArray()) {
2834 throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
2835 }
2836 String name = ConstantDescs.INIT_NAME;
2837 MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
2838 return getDirectConstructor(refc, ctor);
2839 }
2840
2841 /**
2842 * Looks up a class by name from the lookup context defined by this {@code Lookup} object,
2843 * <a href="MethodHandles.Lookup.html#equiv">as if resolved</a> by an {@code ldc} instruction.
2844 * Such a resolution, as specified in JVMS {@jvms 5.4.3.1}, attempts to locate and load the class,
2845 * and then determines whether the class is accessible to this lookup object.
2846 * <p>
2847 * For a class or an interface, the name is the {@linkplain ClassLoader##binary-name binary name}.
2848 * For an array class of {@code n} dimensions, the name begins with {@code n} occurrences
2849 * of {@code '['} and followed by the element type as encoded in the
2850 * {@linkplain Class##nameFormat table} specified in {@link Class#getName}.
2851 * <p>
2852 * The lookup context here is determined by the {@linkplain #lookupClass() lookup class},
2853 * its class loader, and the {@linkplain #lookupModes() lookup modes}.
2854 *
2855 * @param targetName the {@linkplain ClassLoader##binary-name binary name} of the class
3511 * arguments passed to the method handle.
3512 * <p>
3513 * If the constructor's {@code accessible} flag is not set,
3514 * access checking is performed immediately on behalf of the lookup class.
3515 * <p>
3516 * The returned method handle will have
3517 * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
3518 * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
3519 * <p>
3520 * If the returned method handle is invoked, the constructor's class will
3521 * be initialized, if it has not already been initialized.
3522 * @param c the reflected constructor
3523 * @return a method handle which can invoke the reflected constructor
3524 * @throws IllegalAccessException if access checking fails
3525 * or if the method's variable arity modifier bit
3526 * is set and {@code asVarargsCollector} fails
3527 * @throws NullPointerException if the argument is null
3528 */
3529 public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException {
3530 MemberName ctor = new MemberName(c);
3531 assert(ctor.isConstructor());
3532 @SuppressWarnings("deprecation")
3533 Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this;
3534 return lookup.getDirectConstructorNoSecurityManager(ctor.getDeclaringClass(), ctor);
3535 }
3536
3537 /**
3538 * Produces a method handle giving read access to a reflected field.
3539 * The type of the method handle will have a return type of the field's
3540 * value type.
3541 * If the field is {@code static}, the method handle will take no arguments.
3542 * Otherwise, its single argument will be the instance containing
3543 * the field.
3544 * If the {@code Field} object's {@code accessible} flag is not set,
3545 * access checking is performed immediately on behalf of the lookup class.
3546 * <p>
3547 * If the field is static, and
3548 * if the returned method handle is invoked, the field's class will
3549 * be initialized, if it has not already been initialized.
3550 * @param f the reflected field
3551 * @return a method handle which can load values from the reflected field
3552 * @throws IllegalAccessException if access checking fails
3553 * @throws NullPointerException if the argument is null
3554 */
3759 ReflectiveOperationException.class);
3760 }
3761
3762 MemberName resolveOrNull(byte refKind, MemberName member) {
3763 // do this before attempting to resolve
3764 if (!isClassAccessible(member.getDeclaringClass())) {
3765 return null;
3766 }
3767 Objects.requireNonNull(member.getName());
3768 Objects.requireNonNull(member.getType());
3769 return IMPL_NAMES.resolveOrNull(refKind, member, lookupClassOrNull(), allowedModes);
3770 }
3771
3772 MemberName resolveOrNull(byte refKind, Class<?> refc, String name, MethodType type) {
3773 // do this before attempting to resolve
3774 if (!isClassAccessible(refc)) {
3775 return null;
3776 }
3777 Objects.requireNonNull(type);
3778 // implicit null-check of name
3779 if (name.startsWith("<") && refKind != REF_newInvokeSpecial) {
3780 return null;
3781 }
3782 return IMPL_NAMES.resolveOrNull(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), allowedModes);
3783 }
3784
3785 void checkSymbolicClass(Class<?> refc) throws IllegalAccessException {
3786 if (!isClassAccessible(refc)) {
3787 throw new MemberName(refc).makeAccessException("symbolic reference class is not accessible", this);
3788 }
3789 }
3790
3791 boolean isClassAccessible(Class<?> refc) {
3792 Objects.requireNonNull(refc);
3793 Class<?> caller = lookupClassOrNull();
3794 Class<?> type = refc;
3795 while (type.isArray()) {
3796 type = type.getComponentType();
3797 }
3798 return caller == null || VerifyAccess.isClassAccessible(type, caller, prevLookupClass, allowedModes);
3799 }
3800
3801 /** Check name for an illegal leading "<" character. */
3802 void checkMethodName(byte refKind, String name) throws NoSuchMethodException {
3803 if (name.startsWith("<") && refKind != REF_newInvokeSpecial)
3804 throw new NoSuchMethodException("illegal method name: "+name);
3805 }
3806
3807 /**
3808 * Find my trustable caller class if m is a caller sensitive method.
3809 * If this lookup object has original full privilege access, then the caller class is the lookupClass.
3810 * Otherwise, if m is caller-sensitive, throw IllegalAccessException.
3811 */
3812 Lookup findBoundCallerLookup(MemberName m) throws IllegalAccessException {
3813 if (MethodHandleNatives.isCallerSensitive(m) && (lookupModes() & ORIGINAL) == 0) {
3814 // Only lookups with full privilege access are allowed to resolve caller-sensitive methods
3815 throw new IllegalAccessException("Attempt to lookup caller-sensitive method using restricted lookup object");
3816 }
3817 return this;
3818 }
3819
3820 /**
3821 * Returns {@code true} if this lookup has {@code PRIVATE} and {@code MODULE} access.
3822 * @return {@code true} if this lookup has {@code PRIVATE} and {@code MODULE} access.
3823 *
3824 * @deprecated This method was originally designed to test {@code PRIVATE} access
3888
3889 @SuppressWarnings("removal")
3890 SecurityManager smgr = System.getSecurityManager();
3891 if (smgr == null) return;
3892
3893 // Step 1:
3894 boolean fullPrivilegeLookup = hasFullPrivilegeAccess();
3895 if (!fullPrivilegeLookup ||
3896 !VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
3897 ReflectUtil.checkPackageAccess(refc);
3898 }
3899
3900 // Step 2a:
3901 if (m.isPublic()) return;
3902 if (!fullPrivilegeLookup) {
3903 smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
3904 }
3905
3906 // Step 3:
3907 Class<?> defc = m.getDeclaringClass();
3908 if (!fullPrivilegeLookup && defc != refc) {
3909 ReflectUtil.checkPackageAccess(defc);
3910 }
3911 }
3912
3913 void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
3914 boolean wantStatic = (refKind == REF_invokeStatic);
3915 String message;
3916 if (m.isConstructor())
3917 message = "expected a method, not a constructor";
3918 else if (!m.isMethod())
3919 message = "expected a method";
3920 else if (wantStatic != m.isStatic())
3921 message = wantStatic ? "expected a static method" : "expected a non-static method";
3922 else
3923 { checkAccess(refKind, refc, m); return; }
3924 throw m.makeAccessException(message, this);
3925 }
3926
3927 void checkField(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
3928 boolean wantStatic = !MethodHandleNatives.refKindHasReceiver(refKind);
3929 String message;
3930 if (wantStatic != m.isStatic())
3931 message = wantStatic ? "expected a static field" : "expected a non-static field";
3932 else
3933 { checkAccess(refKind, refc, m); return; }
3934 throw m.makeAccessException(message, this);
3935 }
3936
3975 throw m.makeAccessException("unexpected set of a final field", this);
3976 int requestedModes = fixmods(mods); // adjust 0 => PACKAGE
3977 if ((requestedModes & allowedModes) != 0) {
3978 if (VerifyAccess.isMemberAccessible(refc, m.getDeclaringClass(),
3979 mods, lookupClass(), previousLookupClass(), allowedModes))
3980 return;
3981 } else {
3982 // Protected members can also be checked as if they were package-private.
3983 if ((requestedModes & PROTECTED) != 0 && (allowedModes & PACKAGE) != 0
3984 && VerifyAccess.isSamePackage(m.getDeclaringClass(), lookupClass()))
3985 return;
3986 }
3987 throw m.makeAccessException(accessFailedMessage(refc, m), this);
3988 }
3989
3990 String accessFailedMessage(Class<?> refc, MemberName m) {
3991 Class<?> defc = m.getDeclaringClass();
3992 int mods = m.getModifiers();
3993 // check the class first:
3994 boolean classOK = (Modifier.isPublic(defc.getModifiers()) &&
3995 (defc == refc ||
3996 Modifier.isPublic(refc.getModifiers())));
3997 if (!classOK && (allowedModes & PACKAGE) != 0) {
3998 // ignore previous lookup class to check if default package access
3999 classOK = (VerifyAccess.isClassAccessible(defc, lookupClass(), null, FULL_POWER_MODES) &&
4000 (defc == refc ||
4001 VerifyAccess.isClassAccessible(refc, lookupClass(), null, FULL_POWER_MODES)));
4002 }
4003 if (!classOK)
4004 return "class is not public";
4005 if (Modifier.isPublic(mods))
4006 return "access to public member failed"; // (how?, module not readable?)
4007 if (Modifier.isPrivate(mods))
4008 return "member is private";
4009 if (Modifier.isProtected(mods))
4010 return "member is protected";
4011 return "member is private to package";
4012 }
4013
4014 private void checkSpecialCaller(Class<?> specialCaller, Class<?> refc) throws IllegalAccessException {
4015 int allowedModes = this.allowedModes;
4016 if (allowedModes == TRUSTED) return;
4017 if ((lookupModes() & PRIVATE) == 0
4018 || (specialCaller != lookupClass()
4019 // ensure non-abstract methods in superinterfaces can be special-invoked
4020 && !(refc != null && refc.isInterface() && refc.isAssignableFrom(specialCaller))))
4057 final boolean doRestrict = false;
4058 final boolean checkSecurity = true;
4059 return getDirectMethodCommon(REF_invokeSpecial, refc, method, checkSecurity, doRestrict, callerLookup);
4060 }
4061 /** Check access and get the requested method, eliding security manager checks. */
4062 private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Lookup callerLookup) throws IllegalAccessException {
4063 final boolean doRestrict = true;
4064 final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants
4065 return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerLookup);
4066 }
4067 /** Common code for all methods; do not call directly except from immediately above. */
4068 private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
4069 boolean checkSecurity,
4070 boolean doRestrict,
4071 Lookup boundCaller) throws IllegalAccessException {
4072 checkMethod(refKind, refc, method);
4073 // Optionally check with the security manager; this isn't needed for unreflect* calls.
4074 if (checkSecurity)
4075 checkSecurityManager(refc, method);
4076 assert(!method.isMethodHandleInvoke());
4077
4078 if (refKind == REF_invokeSpecial &&
4079 refc != lookupClass() &&
4080 !refc.isInterface() && !lookupClass().isInterface() &&
4081 refc != lookupClass().getSuperclass() &&
4082 refc.isAssignableFrom(lookupClass())) {
4083 assert(!method.getName().equals(ConstantDescs.INIT_NAME)); // not this code path
4084
4085 // Per JVMS 6.5, desc. of invokespecial instruction:
4086 // If the method is in a superclass of the LC,
4087 // and if our original search was above LC.super,
4088 // repeat the search (symbolic lookup) from LC.super
4089 // and continue with the direct superclass of that class,
4090 // and so forth, until a match is found or no further superclasses exist.
4091 // FIXME: MemberName.resolve should handle this instead.
4092 Class<?> refcAsSuper = lookupClass();
4093 MemberName m2;
4094 do {
4095 refcAsSuper = refcAsSuper.getSuperclass();
4096 m2 = new MemberName(refcAsSuper,
4097 method.getName(),
4206 throw getField.makeAccessException("caller class must be a subclass below the method", lookupClass());
4207 }
4208 refc = lookupClass();
4209 }
4210 return VarHandles.makeFieldHandle(getField, refc,
4211 this.allowedModes == TRUSTED && !getField.isTrustedFinalField());
4212 }
4213 /** Check access and get the requested constructor. */
4214 private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
4215 final boolean checkSecurity = true;
4216 return getDirectConstructorCommon(refc, ctor, checkSecurity);
4217 }
4218 /** Check access and get the requested constructor, eliding security manager checks. */
4219 private MethodHandle getDirectConstructorNoSecurityManager(Class<?> refc, MemberName ctor) throws IllegalAccessException {
4220 final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants
4221 return getDirectConstructorCommon(refc, ctor, checkSecurity);
4222 }
4223 /** Common code for all constructors; do not call directly except from immediately above. */
4224 private MethodHandle getDirectConstructorCommon(Class<?> refc, MemberName ctor,
4225 boolean checkSecurity) throws IllegalAccessException {
4226 assert(ctor.isConstructor());
4227 checkAccess(REF_newInvokeSpecial, refc, ctor);
4228 // Optionally check with the security manager; this isn't needed for unreflect* calls.
4229 if (checkSecurity)
4230 checkSecurityManager(refc, ctor);
4231 assert(!MethodHandleNatives.isCallerSensitive(ctor)); // maybeBindCaller not relevant here
4232 return DirectMethodHandle.make(ctor).setVarargs(ctor);
4233 }
4234
4235 /** Hook called from the JVM (via MethodHandleNatives) to link MH constants:
4236 */
4237 /*non-public*/
4238 MethodHandle linkMethodHandleConstant(byte refKind, Class<?> defc, String name, Object type)
4239 throws ReflectiveOperationException {
4240 if (!(type instanceof Class || type instanceof MethodType))
4241 throw new InternalError("unresolved MemberName");
4242 MemberName member = new MemberName(refKind, defc, name, type);
4243 MethodHandle mh = LOOKASIDE_TABLE.get(member);
4244 if (mh != null) {
4245 checkSymbolicClass(defc);
4246 return mh;
5112 * If the requested type is primitive, widening primitive conversions are attempted,
5113 * else reference conversions are attempted.
5114 * <p>The returned method handle is equivalent to {@code identity(type).bindTo(value)}.
5115 * @param type the return type of the desired method handle
5116 * @param value the value to return
5117 * @return a method handle of the given return type and no arguments, which always returns the given value
5118 * @throws NullPointerException if the {@code type} argument is null
5119 * @throws ClassCastException if the value cannot be converted to the required return type
5120 * @throws IllegalArgumentException if the given type is {@code void.class}
5121 */
5122 public static MethodHandle constant(Class<?> type, Object value) {
5123 if (type.isPrimitive()) {
5124 if (type == void.class)
5125 throw newIllegalArgumentException("void type");
5126 Wrapper w = Wrapper.forPrimitiveType(type);
5127 value = w.convert(value, type);
5128 if (w.zero().equals(value))
5129 return zero(w, type);
5130 return insertArguments(identity(type), 0, value);
5131 } else {
5132 if (value == null)
5133 return zero(Wrapper.OBJECT, type);
5134 return identity(type).bindTo(value);
5135 }
5136 }
5137
5138 /**
5139 * Produces a method handle which returns its sole argument when invoked.
5140 * @param type the type of the sole parameter and return value of the desired method handle
5141 * @return a unary method handle which accepts and returns the given type
5142 * @throws NullPointerException if the argument is null
5143 * @throws IllegalArgumentException if the given type is {@code void.class}
5144 */
5145 public static MethodHandle identity(Class<?> type) {
5146 Wrapper btw = (type.isPrimitive() ? Wrapper.forPrimitiveType(type) : Wrapper.OBJECT);
5147 int pos = btw.ordinal();
5148 MethodHandle ident = IDENTITY_MHS[pos];
5149 if (ident == null) {
5150 ident = setCachedMethodHandle(IDENTITY_MHS, pos, makeIdentity(btw.primitiveType()));
5151 }
5152 if (ident.type().returnType() == type)
5157 }
5158
5159 /**
5160 * Produces a constant method handle of the requested return type which
5161 * returns the default value for that type every time it is invoked.
5162 * The resulting constant method handle will have no side effects.
5163 * <p>The returned method handle is equivalent to {@code empty(methodType(type))}.
5164 * It is also equivalent to {@code explicitCastArguments(constant(Object.class, null), methodType(type))},
5165 * since {@code explicitCastArguments} converts {@code null} to default values.
5166 * @param type the expected return type of the desired method handle
5167 * @return a constant method handle that takes no arguments
5168 * and returns the default value of the given type (or void, if the type is void)
5169 * @throws NullPointerException if the argument is null
5170 * @see MethodHandles#constant
5171 * @see MethodHandles#empty
5172 * @see MethodHandles#explicitCastArguments
5173 * @since 9
5174 */
5175 public static MethodHandle zero(Class<?> type) {
5176 Objects.requireNonNull(type);
5177 return type.isPrimitive() ? zero(Wrapper.forPrimitiveType(type), type) : zero(Wrapper.OBJECT, type);
5178 }
5179
5180 private static MethodHandle identityOrVoid(Class<?> type) {
5181 return type == void.class ? zero(type) : identity(type);
5182 }
5183
5184 /**
5185 * Produces a method handle of the requested type which ignores any arguments, does nothing,
5186 * and returns a suitable default depending on the return type.
5187 * That is, it returns a zero primitive value, a {@code null}, or {@code void}.
5188 * <p>The returned method handle is equivalent to
5189 * {@code dropArguments(zero(type.returnType()), 0, type.parameterList())}.
5190 *
5191 * @apiNote Given a predicate and target, a useful "if-then" construct can be produced as
5192 * {@code guardWithTest(pred, target, empty(target.type())}.
5193 * @param type the type of the desired method handle
5194 * @return a constant method handle of the given type, which returns a default value of the given return type
5195 * @throws NullPointerException if the argument is null
5196 * @see MethodHandles#zero
5197 * @see MethodHandles#constant
5198 * @since 9
5199 */
5200 public static MethodHandle empty(MethodType type) {
5201 Objects.requireNonNull(type);
5202 return dropArgumentsTrusted(zero(type.returnType()), 0, type.ptypes());
5203 }
5204
5205 private static final MethodHandle[] IDENTITY_MHS = new MethodHandle[Wrapper.COUNT];
5206 private static MethodHandle makeIdentity(Class<?> ptype) {
5207 MethodType mtype = methodType(ptype, ptype);
5208 LambdaForm lform = LambdaForm.identityForm(BasicType.basicType(ptype));
5209 return MethodHandleImpl.makeIntrinsic(mtype, lform, Intrinsic.IDENTITY);
5210 }
5211
5212 private static MethodHandle zero(Wrapper btw, Class<?> rtype) {
5213 int pos = btw.ordinal();
5214 MethodHandle zero = ZERO_MHS[pos];
5215 if (zero == null) {
5216 zero = setCachedMethodHandle(ZERO_MHS, pos, makeZero(btw.primitiveType()));
5217 }
5218 if (zero.type().returnType() == rtype)
5219 return zero;
5220 assert(btw == Wrapper.OBJECT);
5221 return makeZero(rtype);
5222 }
5223 private static final MethodHandle[] ZERO_MHS = new MethodHandle[Wrapper.COUNT];
5224 private static MethodHandle makeZero(Class<?> rtype) {
5225 MethodType mtype = methodType(rtype);
5226 LambdaForm lform = LambdaForm.zeroForm(BasicType.basicType(rtype));
5227 return MethodHandleImpl.makeIntrinsic(mtype, lform, Intrinsic.ZERO);
|
9 * by Oracle in the LICENSE file that accompanied this code.
10 *
11 * This code is distributed in the hope that it will be useful, but WITHOUT
12 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
13 * FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
14 * version 2 for more details (a copy is included in the LICENSE file that
15 * accompanied this code).
16 *
17 * You should have received a copy of the GNU General Public License version
18 * 2 along with this work; if not, write to the Free Software Foundation,
19 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
20 *
21 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
22 * or visit www.oracle.com if you need additional information or have any
23 * questions.
24 */
25
26 package java.lang.invoke;
27
28 import jdk.internal.access.SharedSecrets;
29 import jdk.internal.value.PrimitiveClass;
30 import jdk.internal.foreign.Utils;
31 import jdk.internal.javac.PreviewFeature;
32 import jdk.internal.misc.Unsafe;
33 import jdk.internal.misc.VM;
34 import jdk.internal.org.objectweb.asm.ClassReader;
35 import jdk.internal.org.objectweb.asm.Opcodes;
36 import jdk.internal.org.objectweb.asm.Type;
37 import jdk.internal.reflect.CallerSensitive;
38 import jdk.internal.reflect.CallerSensitiveAdapter;
39 import jdk.internal.reflect.Reflection;
40 import jdk.internal.util.ClassFileDumper;
41 import jdk.internal.vm.annotation.ForceInline;
42 import sun.invoke.util.ValueConversions;
43 import sun.invoke.util.VerifyAccess;
44 import sun.invoke.util.Wrapper;
45 import sun.reflect.misc.ReflectUtil;
46 import sun.security.util.SecurityConstants;
47
48 import java.lang.constant.ConstantDescs;
49 import java.lang.foreign.GroupLayout;
697 * If the desired member is {@code protected}, the usual JVM rules apply,
698 * including the requirement that the lookup class must either be in the
699 * same package as the desired member, or must inherit that member.
700 * (See the Java Virtual Machine Specification, sections {@jvms
701 * 4.9.2}, {@jvms 5.4.3.5}, and {@jvms 6.4}.)
702 * In addition, if the desired member is a non-static field or method
703 * in a different package, the resulting method handle may only be applied
704 * to objects of the lookup class or one of its subclasses.
705 * This requirement is enforced by narrowing the type of the leading
706 * {@code this} parameter from {@code C}
707 * (which will necessarily be a superclass of the lookup class)
708 * to the lookup class itself.
709 * <p>
710 * The JVM imposes a similar requirement on {@code invokespecial} instruction,
711 * that the receiver argument must match both the resolved method <em>and</em>
712 * the current class. Again, this requirement is enforced by narrowing the
713 * type of the leading parameter to the resulting method handle.
714 * (See the Java Virtual Machine Specification, section {@jvms 4.10.1.9}.)
715 * <p>
716 * The JVM represents constructors and static initializer blocks as internal methods
717 * with special names ({@value ConstantDescs#INIT_NAME},
718 * {@value ConstantDescs#VNEW_NAME} and {@value ConstantDescs#CLASS_INIT_NAME}).
719 * The internal syntax of invocation instructions allows them to refer to such internal
720 * methods as if they were normal methods, but the JVM bytecode verifier rejects them.
721 * A lookup of such an internal method will produce a {@code NoSuchMethodException}.
722 * <p>
723 * If the relationship between nested types is expressed directly through the
724 * {@code NestHost} and {@code NestMembers} attributes
725 * (see the Java Virtual Machine Specification, sections {@jvms
726 * 4.7.28} and {@jvms 4.7.29}),
727 * then the associated {@code Lookup} object provides direct access to
728 * the lookup class and all of its nestmates
729 * (see {@link java.lang.Class#getNestHost Class.getNestHost}).
730 * Otherwise, access between nested classes is obtained by the Java compiler creating
731 * a wrapper method to access a private method of another class in the same nest.
732 * For example, a nested class {@code C.D}
733 * can access private members within other related classes such as
734 * {@code C}, {@code C.D.E}, or {@code C.B},
735 * but the Java compiler may need to generate wrapper methods in
736 * those related classes. In such cases, a {@code Lookup} object on
737 * {@code C.E} would be unable to access those private members.
738 * A workaround for this limitation is the {@link Lookup#in Lookup.in} method,
1622 * @return the lookup modes, which limit the kinds of access performed by this lookup object
1623 * @see #in
1624 * @see #dropLookupMode
1625 *
1626 * @revised 9
1627 */
1628 public int lookupModes() {
1629 return allowedModes & ALL_MODES;
1630 }
1631
1632 /** Embody the current class (the lookupClass) as a lookup class
1633 * for method handle creation.
1634 * Must be called by from a method in this package,
1635 * which in turn is called by a method not in this package.
1636 */
1637 Lookup(Class<?> lookupClass) {
1638 this(lookupClass, null, FULL_POWER_MODES);
1639 }
1640
1641 private Lookup(Class<?> lookupClass, Class<?> prevLookupClass, int allowedModes) {
1642 assert PrimitiveClass.isPrimaryType(lookupClass);
1643 assert prevLookupClass == null || ((allowedModes & MODULE) == 0
1644 && prevLookupClass.getModule() != lookupClass.getModule());
1645 assert !lookupClass.isArray() && !lookupClass.isPrimitive();
1646 this.lookupClass = lookupClass;
1647 this.prevLookupClass = prevLookupClass;
1648 this.allowedModes = allowedModes;
1649 }
1650
1651 private static Lookup newLookup(Class<?> lookupClass, Class<?> prevLookupClass, int allowedModes) {
1652 // make sure we haven't accidentally picked up a privileged class:
1653 checkUnprivilegedlookupClass(lookupClass);
1654 return new Lookup(lookupClass, prevLookupClass, allowedModes);
1655 }
1656
1657 /**
1658 * Creates a lookup on the specified new lookup class.
1659 * The resulting object will report the specified
1660 * class as its own {@link #lookupClass() lookupClass}.
1661 *
1662 * <p>
2803 * If the returned method handle is invoked, the constructor's class will
2804 * be initialized, if it has not already been initialized.
2805 * <p><b>Example:</b>
2806 * {@snippet lang="java" :
2807 import static java.lang.invoke.MethodHandles.*;
2808 import static java.lang.invoke.MethodType.*;
2809 ...
2810 MethodHandle MH_newArrayList = publicLookup().findConstructor(
2811 ArrayList.class, methodType(void.class, Collection.class));
2812 Collection orig = Arrays.asList("x", "y");
2813 Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
2814 assert(orig != copy);
2815 assertEquals(orig, copy);
2816 // a variable-arity constructor:
2817 MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
2818 ProcessBuilder.class, methodType(void.class, String[].class));
2819 ProcessBuilder pb = (ProcessBuilder)
2820 MH_newProcessBuilder.invoke("x", "y", "z");
2821 assertEquals("[x, y, z]", pb.command().toString());
2822 * }
2823 *
2824 *
2825 * @param refc the class or interface from which the method is accessed
2826 * @param type the type of the method, with the receiver argument omitted, and a void return type
2827 * @return the desired method handle
2828 * @throws NoSuchMethodException if the constructor does not exist
2829 * @throws IllegalAccessException if access checking fails
2830 * or if the method's variable arity modifier bit
2831 * is set and {@code asVarargsCollector} fails
2832 * @throws SecurityException if a security manager is present and it
2833 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
2834 * @throws NullPointerException if any argument is null
2835 */
2836 public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
2837 if (refc.isArray()) {
2838 throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
2839 }
2840 if (type.returnType() != void.class) {
2841 throw new NoSuchMethodException("Constructors must have void return type: " + refc.getName());
2842 }
2843 String name = ConstantDescs.INIT_NAME;
2844 MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
2845 return getDirectConstructor(refc, ctor);
2846 }
2847
2848 /**
2849 * Looks up a class by name from the lookup context defined by this {@code Lookup} object,
2850 * <a href="MethodHandles.Lookup.html#equiv">as if resolved</a> by an {@code ldc} instruction.
2851 * Such a resolution, as specified in JVMS {@jvms 5.4.3.1}, attempts to locate and load the class,
2852 * and then determines whether the class is accessible to this lookup object.
2853 * <p>
2854 * For a class or an interface, the name is the {@linkplain ClassLoader##binary-name binary name}.
2855 * For an array class of {@code n} dimensions, the name begins with {@code n} occurrences
2856 * of {@code '['} and followed by the element type as encoded in the
2857 * {@linkplain Class##nameFormat table} specified in {@link Class#getName}.
2858 * <p>
2859 * The lookup context here is determined by the {@linkplain #lookupClass() lookup class},
2860 * its class loader, and the {@linkplain #lookupModes() lookup modes}.
2861 *
2862 * @param targetName the {@linkplain ClassLoader##binary-name binary name} of the class
3518 * arguments passed to the method handle.
3519 * <p>
3520 * If the constructor's {@code accessible} flag is not set,
3521 * access checking is performed immediately on behalf of the lookup class.
3522 * <p>
3523 * The returned method handle will have
3524 * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
3525 * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
3526 * <p>
3527 * If the returned method handle is invoked, the constructor's class will
3528 * be initialized, if it has not already been initialized.
3529 * @param c the reflected constructor
3530 * @return a method handle which can invoke the reflected constructor
3531 * @throws IllegalAccessException if access checking fails
3532 * or if the method's variable arity modifier bit
3533 * is set and {@code asVarargsCollector} fails
3534 * @throws NullPointerException if the argument is null
3535 */
3536 public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException {
3537 MemberName ctor = new MemberName(c);
3538 assert(ctor.isObjectConstructor() || ctor.isStaticValueFactoryMethod());
3539 @SuppressWarnings("deprecation")
3540 Lookup lookup = c.isAccessible() ? IMPL_LOOKUP : this;
3541 Class<?> defc = c.getDeclaringClass();
3542 if (ctor.isObjectConstructor()) {
3543 assert(ctor.getMethodType().returnType() == void.class);
3544 return lookup.getDirectConstructorNoSecurityManager(defc, ctor);
3545 } else {
3546 // static init factory is a static method
3547 assert(ctor.isMethod() && ctor.getMethodType().returnType() == defc && ctor.getReferenceKind() == REF_invokeStatic) : ctor.toString();
3548 assert(!MethodHandleNatives.isCallerSensitive(ctor)); // must not be caller-sensitive
3549 return lookup.getDirectMethodNoSecurityManager(ctor.getReferenceKind(), defc, ctor, lookup);
3550 }
3551 }
3552
3553 /**
3554 * Produces a method handle giving read access to a reflected field.
3555 * The type of the method handle will have a return type of the field's
3556 * value type.
3557 * If the field is {@code static}, the method handle will take no arguments.
3558 * Otherwise, its single argument will be the instance containing
3559 * the field.
3560 * If the {@code Field} object's {@code accessible} flag is not set,
3561 * access checking is performed immediately on behalf of the lookup class.
3562 * <p>
3563 * If the field is static, and
3564 * if the returned method handle is invoked, the field's class will
3565 * be initialized, if it has not already been initialized.
3566 * @param f the reflected field
3567 * @return a method handle which can load values from the reflected field
3568 * @throws IllegalAccessException if access checking fails
3569 * @throws NullPointerException if the argument is null
3570 */
3775 ReflectiveOperationException.class);
3776 }
3777
3778 MemberName resolveOrNull(byte refKind, MemberName member) {
3779 // do this before attempting to resolve
3780 if (!isClassAccessible(member.getDeclaringClass())) {
3781 return null;
3782 }
3783 Objects.requireNonNull(member.getName());
3784 Objects.requireNonNull(member.getType());
3785 return IMPL_NAMES.resolveOrNull(refKind, member, lookupClassOrNull(), allowedModes);
3786 }
3787
3788 MemberName resolveOrNull(byte refKind, Class<?> refc, String name, MethodType type) {
3789 // do this before attempting to resolve
3790 if (!isClassAccessible(refc)) {
3791 return null;
3792 }
3793 Objects.requireNonNull(type);
3794 // implicit null-check of name
3795 if (isIllegalMethodName(refKind, name)) {
3796 return null;
3797 }
3798
3799 return IMPL_NAMES.resolveOrNull(refKind, new MemberName(refc, name, type, refKind), lookupClassOrNull(), allowedModes);
3800 }
3801
3802 void checkSymbolicClass(Class<?> refc) throws IllegalAccessException {
3803 if (!isClassAccessible(refc)) {
3804 throw new MemberName(refc).makeAccessException("symbolic reference class is not accessible", this);
3805 }
3806 }
3807
3808 boolean isClassAccessible(Class<?> refc) {
3809 Objects.requireNonNull(refc);
3810 Class<?> caller = lookupClassOrNull();
3811 Class<?> type = refc;
3812 while (type.isArray()) {
3813 type = type.getComponentType();
3814 }
3815 return caller == null || VerifyAccess.isClassAccessible(type, caller, prevLookupClass, allowedModes);
3816 }
3817
3818 /*
3819 * "<init>" can only be invoked via invokespecial
3820 * "<vnew>" factory can only invoked via invokestatic
3821 */
3822 boolean isIllegalMethodName(byte refKind, String name) {
3823 if (name.startsWith("<")) {
3824 return MemberName.VALUE_FACTORY_NAME.equals(name) ? refKind != REF_invokeStatic
3825 : refKind != REF_newInvokeSpecial;
3826 }
3827 return false;
3828 }
3829
3830 /** Check name for an illegal leading "<" character. */
3831 void checkMethodName(byte refKind, String name) throws NoSuchMethodException {
3832 if (isIllegalMethodName(refKind, name)) {
3833 throw new NoSuchMethodException("illegal method name: " + name + " " + refKind);
3834 }
3835 }
3836
3837 /**
3838 * Find my trustable caller class if m is a caller sensitive method.
3839 * If this lookup object has original full privilege access, then the caller class is the lookupClass.
3840 * Otherwise, if m is caller-sensitive, throw IllegalAccessException.
3841 */
3842 Lookup findBoundCallerLookup(MemberName m) throws IllegalAccessException {
3843 if (MethodHandleNatives.isCallerSensitive(m) && (lookupModes() & ORIGINAL) == 0) {
3844 // Only lookups with full privilege access are allowed to resolve caller-sensitive methods
3845 throw new IllegalAccessException("Attempt to lookup caller-sensitive method using restricted lookup object");
3846 }
3847 return this;
3848 }
3849
3850 /**
3851 * Returns {@code true} if this lookup has {@code PRIVATE} and {@code MODULE} access.
3852 * @return {@code true} if this lookup has {@code PRIVATE} and {@code MODULE} access.
3853 *
3854 * @deprecated This method was originally designed to test {@code PRIVATE} access
3918
3919 @SuppressWarnings("removal")
3920 SecurityManager smgr = System.getSecurityManager();
3921 if (smgr == null) return;
3922
3923 // Step 1:
3924 boolean fullPrivilegeLookup = hasFullPrivilegeAccess();
3925 if (!fullPrivilegeLookup ||
3926 !VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
3927 ReflectUtil.checkPackageAccess(refc);
3928 }
3929
3930 // Step 2a:
3931 if (m.isPublic()) return;
3932 if (!fullPrivilegeLookup) {
3933 smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
3934 }
3935
3936 // Step 3:
3937 Class<?> defc = m.getDeclaringClass();
3938 if (!fullPrivilegeLookup && PrimitiveClass.asPrimaryType(defc) != PrimitiveClass.asPrimaryType(refc)) {
3939 ReflectUtil.checkPackageAccess(defc);
3940 }
3941 }
3942
3943 void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
3944 boolean wantStatic = (refKind == REF_invokeStatic);
3945 String message;
3946 if (m.isObjectConstructor())
3947 message = "expected a method, not a constructor";
3948 else if (!m.isMethod())
3949 message = "expected a method";
3950 else if (wantStatic != m.isStatic())
3951 message = wantStatic ? "expected a static method" : "expected a non-static method";
3952 else
3953 { checkAccess(refKind, refc, m); return; }
3954 throw m.makeAccessException(message, this);
3955 }
3956
3957 void checkField(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
3958 boolean wantStatic = !MethodHandleNatives.refKindHasReceiver(refKind);
3959 String message;
3960 if (wantStatic != m.isStatic())
3961 message = wantStatic ? "expected a static field" : "expected a non-static field";
3962 else
3963 { checkAccess(refKind, refc, m); return; }
3964 throw m.makeAccessException(message, this);
3965 }
3966
4005 throw m.makeAccessException("unexpected set of a final field", this);
4006 int requestedModes = fixmods(mods); // adjust 0 => PACKAGE
4007 if ((requestedModes & allowedModes) != 0) {
4008 if (VerifyAccess.isMemberAccessible(refc, m.getDeclaringClass(),
4009 mods, lookupClass(), previousLookupClass(), allowedModes))
4010 return;
4011 } else {
4012 // Protected members can also be checked as if they were package-private.
4013 if ((requestedModes & PROTECTED) != 0 && (allowedModes & PACKAGE) != 0
4014 && VerifyAccess.isSamePackage(m.getDeclaringClass(), lookupClass()))
4015 return;
4016 }
4017 throw m.makeAccessException(accessFailedMessage(refc, m), this);
4018 }
4019
4020 String accessFailedMessage(Class<?> refc, MemberName m) {
4021 Class<?> defc = m.getDeclaringClass();
4022 int mods = m.getModifiers();
4023 // check the class first:
4024 boolean classOK = (Modifier.isPublic(defc.getModifiers()) &&
4025 (PrimitiveClass.asPrimaryType(defc) == PrimitiveClass.asPrimaryType(refc) ||
4026 Modifier.isPublic(refc.getModifiers())));
4027 if (!classOK && (allowedModes & PACKAGE) != 0) {
4028 // ignore previous lookup class to check if default package access
4029 classOK = (VerifyAccess.isClassAccessible(defc, lookupClass(), null, FULL_POWER_MODES) &&
4030 (PrimitiveClass.asPrimaryType(defc) == PrimitiveClass.asPrimaryType(refc) ||
4031 VerifyAccess.isClassAccessible(refc, lookupClass(), null, FULL_POWER_MODES)));
4032 }
4033 if (!classOK)
4034 return "class is not public";
4035 if (Modifier.isPublic(mods))
4036 return "access to public member failed"; // (how?, module not readable?)
4037 if (Modifier.isPrivate(mods))
4038 return "member is private";
4039 if (Modifier.isProtected(mods))
4040 return "member is protected";
4041 return "member is private to package";
4042 }
4043
4044 private void checkSpecialCaller(Class<?> specialCaller, Class<?> refc) throws IllegalAccessException {
4045 int allowedModes = this.allowedModes;
4046 if (allowedModes == TRUSTED) return;
4047 if ((lookupModes() & PRIVATE) == 0
4048 || (specialCaller != lookupClass()
4049 // ensure non-abstract methods in superinterfaces can be special-invoked
4050 && !(refc != null && refc.isInterface() && refc.isAssignableFrom(specialCaller))))
4087 final boolean doRestrict = false;
4088 final boolean checkSecurity = true;
4089 return getDirectMethodCommon(REF_invokeSpecial, refc, method, checkSecurity, doRestrict, callerLookup);
4090 }
4091 /** Check access and get the requested method, eliding security manager checks. */
4092 private MethodHandle getDirectMethodNoSecurityManager(byte refKind, Class<?> refc, MemberName method, Lookup callerLookup) throws IllegalAccessException {
4093 final boolean doRestrict = true;
4094 final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants
4095 return getDirectMethodCommon(refKind, refc, method, checkSecurity, doRestrict, callerLookup);
4096 }
4097 /** Common code for all methods; do not call directly except from immediately above. */
4098 private MethodHandle getDirectMethodCommon(byte refKind, Class<?> refc, MemberName method,
4099 boolean checkSecurity,
4100 boolean doRestrict,
4101 Lookup boundCaller) throws IllegalAccessException {
4102 checkMethod(refKind, refc, method);
4103 // Optionally check with the security manager; this isn't needed for unreflect* calls.
4104 if (checkSecurity)
4105 checkSecurityManager(refc, method);
4106 assert(!method.isMethodHandleInvoke());
4107 if (refKind == REF_invokeSpecial &&
4108 refc != lookupClass() &&
4109 !refc.isInterface() && !lookupClass().isInterface() &&
4110 refc != lookupClass().getSuperclass() &&
4111 refc.isAssignableFrom(lookupClass())) {
4112 assert(!method.getName().equals(ConstantDescs.INIT_NAME)); // not this code path
4113
4114 // Per JVMS 6.5, desc. of invokespecial instruction:
4115 // If the method is in a superclass of the LC,
4116 // and if our original search was above LC.super,
4117 // repeat the search (symbolic lookup) from LC.super
4118 // and continue with the direct superclass of that class,
4119 // and so forth, until a match is found or no further superclasses exist.
4120 // FIXME: MemberName.resolve should handle this instead.
4121 Class<?> refcAsSuper = lookupClass();
4122 MemberName m2;
4123 do {
4124 refcAsSuper = refcAsSuper.getSuperclass();
4125 m2 = new MemberName(refcAsSuper,
4126 method.getName(),
4235 throw getField.makeAccessException("caller class must be a subclass below the method", lookupClass());
4236 }
4237 refc = lookupClass();
4238 }
4239 return VarHandles.makeFieldHandle(getField, refc,
4240 this.allowedModes == TRUSTED && !getField.isTrustedFinalField());
4241 }
4242 /** Check access and get the requested constructor. */
4243 private MethodHandle getDirectConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
4244 final boolean checkSecurity = true;
4245 return getDirectConstructorCommon(refc, ctor, checkSecurity);
4246 }
4247 /** Check access and get the requested constructor, eliding security manager checks. */
4248 private MethodHandle getDirectConstructorNoSecurityManager(Class<?> refc, MemberName ctor) throws IllegalAccessException {
4249 final boolean checkSecurity = false; // not needed for reflection or for linking CONSTANT_MH constants
4250 return getDirectConstructorCommon(refc, ctor, checkSecurity);
4251 }
4252 /** Common code for all constructors; do not call directly except from immediately above. */
4253 private MethodHandle getDirectConstructorCommon(Class<?> refc, MemberName ctor,
4254 boolean checkSecurity) throws IllegalAccessException {
4255 assert(ctor.isObjectConstructor());
4256 checkAccess(REF_newInvokeSpecial, refc, ctor);
4257 // Optionally check with the security manager; this isn't needed for unreflect* calls.
4258 if (checkSecurity)
4259 checkSecurityManager(refc, ctor);
4260 assert(!MethodHandleNatives.isCallerSensitive(ctor)); // maybeBindCaller not relevant here
4261 return DirectMethodHandle.make(ctor).setVarargs(ctor);
4262 }
4263
4264 /** Hook called from the JVM (via MethodHandleNatives) to link MH constants:
4265 */
4266 /*non-public*/
4267 MethodHandle linkMethodHandleConstant(byte refKind, Class<?> defc, String name, Object type)
4268 throws ReflectiveOperationException {
4269 if (!(type instanceof Class || type instanceof MethodType))
4270 throw new InternalError("unresolved MemberName");
4271 MemberName member = new MemberName(refKind, defc, name, type);
4272 MethodHandle mh = LOOKASIDE_TABLE.get(member);
4273 if (mh != null) {
4274 checkSymbolicClass(defc);
4275 return mh;
5141 * If the requested type is primitive, widening primitive conversions are attempted,
5142 * else reference conversions are attempted.
5143 * <p>The returned method handle is equivalent to {@code identity(type).bindTo(value)}.
5144 * @param type the return type of the desired method handle
5145 * @param value the value to return
5146 * @return a method handle of the given return type and no arguments, which always returns the given value
5147 * @throws NullPointerException if the {@code type} argument is null
5148 * @throws ClassCastException if the value cannot be converted to the required return type
5149 * @throws IllegalArgumentException if the given type is {@code void.class}
5150 */
5151 public static MethodHandle constant(Class<?> type, Object value) {
5152 if (type.isPrimitive()) {
5153 if (type == void.class)
5154 throw newIllegalArgumentException("void type");
5155 Wrapper w = Wrapper.forPrimitiveType(type);
5156 value = w.convert(value, type);
5157 if (w.zero().equals(value))
5158 return zero(w, type);
5159 return insertArguments(identity(type), 0, value);
5160 } else {
5161 if (!PrimitiveClass.isPrimitiveValueType(type) && value == null)
5162 return zero(Wrapper.OBJECT, type);
5163 return identity(type).bindTo(value);
5164 }
5165 }
5166
5167 /**
5168 * Produces a method handle which returns its sole argument when invoked.
5169 * @param type the type of the sole parameter and return value of the desired method handle
5170 * @return a unary method handle which accepts and returns the given type
5171 * @throws NullPointerException if the argument is null
5172 * @throws IllegalArgumentException if the given type is {@code void.class}
5173 */
5174 public static MethodHandle identity(Class<?> type) {
5175 Wrapper btw = (type.isPrimitive() ? Wrapper.forPrimitiveType(type) : Wrapper.OBJECT);
5176 int pos = btw.ordinal();
5177 MethodHandle ident = IDENTITY_MHS[pos];
5178 if (ident == null) {
5179 ident = setCachedMethodHandle(IDENTITY_MHS, pos, makeIdentity(btw.primitiveType()));
5180 }
5181 if (ident.type().returnType() == type)
5186 }
5187
5188 /**
5189 * Produces a constant method handle of the requested return type which
5190 * returns the default value for that type every time it is invoked.
5191 * The resulting constant method handle will have no side effects.
5192 * <p>The returned method handle is equivalent to {@code empty(methodType(type))}.
5193 * It is also equivalent to {@code explicitCastArguments(constant(Object.class, null), methodType(type))},
5194 * since {@code explicitCastArguments} converts {@code null} to default values.
5195 * @param type the expected return type of the desired method handle
5196 * @return a constant method handle that takes no arguments
5197 * and returns the default value of the given type (or void, if the type is void)
5198 * @throws NullPointerException if the argument is null
5199 * @see MethodHandles#constant
5200 * @see MethodHandles#empty
5201 * @see MethodHandles#explicitCastArguments
5202 * @since 9
5203 */
5204 public static MethodHandle zero(Class<?> type) {
5205 Objects.requireNonNull(type);
5206 if (type.isPrimitive()) {
5207 return zero(Wrapper.forPrimitiveType(type), type);
5208 } else if (PrimitiveClass.isPrimitiveValueType(type)) {
5209 // singleton default value
5210 Object value = UNSAFE.uninitializedDefaultValue(type);
5211 return identity(type).bindTo(value);
5212 } else {
5213 return zero(Wrapper.OBJECT, type);
5214 }
5215 }
5216
5217 private static MethodHandle identityOrVoid(Class<?> type) {
5218 return type == void.class ? zero(type) : identity(type);
5219 }
5220
5221 /**
5222 * Produces a method handle of the requested type which ignores any arguments, does nothing,
5223 * and returns a suitable default depending on the return type.
5224 * That is, it returns a zero primitive value, a {@code null}, or {@code void}.
5225 * <p>The returned method handle is equivalent to
5226 * {@code dropArguments(zero(type.returnType()), 0, type.parameterList())}.
5227 *
5228 * @apiNote Given a predicate and target, a useful "if-then" construct can be produced as
5229 * {@code guardWithTest(pred, target, empty(target.type())}.
5230 * @param type the type of the desired method handle
5231 * @return a constant method handle of the given type, which returns a default value of the given return type
5232 * @throws NullPointerException if the argument is null
5233 * @see MethodHandles#zero
5234 * @see MethodHandles#constant
5235 * @since 9
5236 */
5237 public static MethodHandle empty(MethodType type) {
5238 Objects.requireNonNull(type);
5239 return dropArgumentsTrusted(zero(type.returnType()), 0, type.ptypes());
5240 }
5241
5242 private static final MethodHandle[] IDENTITY_MHS = new MethodHandle[Wrapper.COUNT];
5243 private static MethodHandle makeIdentity(Class<?> ptype) {
5244 MethodType mtype = MethodType.methodType(ptype, ptype);
5245 LambdaForm lform = LambdaForm.identityForm(BasicType.basicType(ptype));
5246 return MethodHandleImpl.makeIntrinsic(mtype, lform, Intrinsic.IDENTITY);
5247 }
5248
5249 private static MethodHandle zero(Wrapper btw, Class<?> rtype) {
5250 int pos = btw.ordinal();
5251 MethodHandle zero = ZERO_MHS[pos];
5252 if (zero == null) {
5253 zero = setCachedMethodHandle(ZERO_MHS, pos, makeZero(btw.primitiveType()));
5254 }
5255 if (zero.type().returnType() == rtype)
5256 return zero;
5257 assert(btw == Wrapper.OBJECT);
5258 return makeZero(rtype);
5259 }
5260 private static final MethodHandle[] ZERO_MHS = new MethodHandle[Wrapper.COUNT];
5261 private static MethodHandle makeZero(Class<?> rtype) {
5262 MethodType mtype = methodType(rtype);
5263 LambdaForm lform = LambdaForm.zeroForm(BasicType.basicType(rtype));
5264 return MethodHandleImpl.makeIntrinsic(mtype, lform, Intrinsic.ZERO);
|