MethodHandles.java 116.5 KB
Newer Older
1
/*
2
 * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
3 4 5 6
 * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
 *
 * This code is free software; you can redistribute it and/or modify it
 * under the terms of the GNU General Public License version 2 only, as
7
 * published by the Free Software Foundation.  Oracle designates this
8
 * particular file as subject to the "Classpath" exception as provided
9
 * by Oracle in the LICENSE file that accompanied this code.
10 11 12 13 14 15 16 17 18 19 20
 *
 * This code is distributed in the hope that it will be useful, but WITHOUT
 * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
 * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
 * version 2 for more details (a copy is included in the LICENSE file that
 * accompanied this code).
 *
 * You should have received a copy of the GNU General Public License version
 * 2 along with this work; if not, write to the Free Software Foundation,
 * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
 *
21 22 23
 * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
 * or visit www.oracle.com if you need additional information or have any
 * questions.
24 25
 */

26
package java.lang.invoke;
27

28
import java.lang.reflect.*;
29 30 31 32
import sun.invoke.WrapperInstance;
import sun.invoke.util.ValueConversions;
import sun.invoke.util.VerifyAccess;
import sun.invoke.util.Wrapper;
33
import java.util.List;
34 35 36
import java.util.ArrayList;
import java.util.Arrays;
import sun.reflect.Reflection;
37
import static java.lang.invoke.MethodHandleStatics.*;
38
import static java.lang.invoke.MethodHandleNatives.Constants.*;
39 40

/**
41 42
 * This class consists exclusively of static methods that operate on or return
 * method handles. They fall into several categories:
43
 * <ul>
44 45 46
 * <li>Lookup methods which help create method handles for methods and fields.
 * <li>Combinator methods, which combine or transform pre-existing method handles into new ones.
 * <li>Other factory methods to create method handles that emulate other common JVM operations or control flow patterns.
47
 * <li>Wrapper methods which can convert between method handles and interface types.
48
 * </ul>
49 50 51 52 53 54 55
 * <p>
 * @author John Rose, JSR 292 EG
 */
public class MethodHandles {

    private MethodHandles() { }  // do not instantiate

56
    private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
57 58 59 60 61
    static { MethodHandleImpl.initStatics(); }
    // See IMPL_LOOKUP below.

    //// Method handle creation from ordinary methods.

62
    /**
63
     * Returns a {@link Lookup lookup object} on the caller,
64 65 66 67
     * which has the capability to access any method handle that the caller has access to,
     * including direct method handles to private fields and methods.
     * This lookup object is a <em>capability</em> which may be delegated to trusted agents.
     * Do not store it in place where untrusted code can access it.
68
     */
69 70 71 72
    public static Lookup lookup() {
        return new Lookup();
    }

73
    /**
74
     * Returns a {@link Lookup lookup object} which is trusted minimally.
75 76
     * It can only be used to create method handles to
     * publicly accessible fields and methods.
77 78 79 80 81 82 83 84
     * <p>
     * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
     * of this lookup object will be {@link java.lang.Object}.
     * <p>
     * The lookup class can be changed to any other class {@code C} using an expression of the form
     * {@linkplain Lookup#in <code>publicLookup().in(C.class)</code>}.
     * Since all classes have equal access to public names,
     * such a change would confer no new access rights.
85 86 87 88 89
     */
    public static Lookup publicLookup() {
        return Lookup.PUBLIC_LOOKUP;
    }

90
    /**
91 92 93
     * A <em>lookup object</em> is a factory for creating method handles,
     * when the creation requires access checking.
     * Method handles do not perform
94
     * access checks when they are called, but rather when they are created.
95 96
     * Therefore, method handle access
     * restrictions must be enforced when a method handle is created.
97
     * The caller class against which those restrictions are enforced
98
     * is known as the {@linkplain #lookupClass lookup class}.
99 100 101 102 103 104 105 106 107 108 109 110 111 112 113 114 115 116
     * <p>
     * A lookup class which needs to create method handles will call
     * {@link MethodHandles#lookup MethodHandles.lookup} to create a factory for itself.
     * When the {@code Lookup} factory object is created, the identity of the lookup class is
     * determined, and securely stored in the {@code Lookup} object.
     * The lookup class (or its delegates) may then use factory methods
     * on the {@code Lookup} object to create method handles for access-checked members.
     * This includes all methods, constructors, and fields which are allowed to the lookup class,
     * even private ones.
     * <p>
     * The factory methods on a {@code Lookup} object correspond to all major
     * use cases for methods, constructors, and fields.
     * Here is a summary of the correspondence between these factory methods and
     * the behavior the resulting method handles:
     * <code>
     * <table border=1 cellpadding=5 summary="lookup method behaviors">
     * <tr><th>lookup expression</th><th>member</th><th>behavior</th></tr>
     * <tr>
117
     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}</td>
118 119 120
     *     <td>FT f;</td><td>(T) this.f;</td>
     * </tr>
     * <tr>
121
     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findStaticGetter lookup.findStaticGetter(C.class,"f",FT.class)}</td>
122 123 124
     *     <td>static<br>FT f;</td><td>(T) C.f;</td>
     * </tr>
     * <tr>
125
     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findSetter lookup.findSetter(C.class,"f",FT.class)}</td>
126 127 128
     *     <td>FT f;</td><td>this.f = x;</td>
     * </tr>
     * <tr>
129
     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findStaticSetter lookup.findStaticSetter(C.class,"f",FT.class)}</td>
130 131 132
     *     <td>static<br>FT f;</td><td>C.f = arg;</td>
     * </tr>
     * <tr>
133
     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findVirtual lookup.findVirtual(C.class,"m",MT)}</td>
134 135 136
     *     <td>T m(A*);</td><td>(T) this.m(arg*);</td>
     * </tr>
     * <tr>
137
     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findStatic lookup.findStatic(C.class,"m",MT)}</td>
138 139 140
     *     <td>static<br>T m(A*);</td><td>(T) C.m(arg*);</td>
     * </tr>
     * <tr>
141
     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findSpecial lookup.findSpecial(C.class,"m",MT,this.class)}</td>
142 143 144
     *     <td>T m(A*);</td><td>(T) super.m(arg*);</td>
     * </tr>
     * <tr>
145
     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findConstructor lookup.findConstructor(C.class,MT)}</td>
146 147 148
     *     <td>C(A*);</td><td>(T) new C(arg*);</td>
     * </tr>
     * <tr>
149
     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflectGetter lookup.unreflectGetter(aField)}</td>
150 151 152
     *     <td>(static)?<br>FT f;</td><td>(FT) aField.get(thisOrNull);</td>
     * </tr>
     * <tr>
153
     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflectSetter lookup.unreflectSetter(aField)}</td>
154 155 156
     *     <td>(static)?<br>FT f;</td><td>aField.set(thisOrNull, arg);</td>
     * </tr>
     * <tr>
157
     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
158 159 160
     *     <td>(static)?<br>T m(A*);</td><td>(T) aMethod.invoke(thisOrNull, arg*);</td>
     * </tr>
     * <tr>
161
     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflectConstructor lookup.unreflectConstructor(aConstructor)}</td>
162 163 164
     *     <td>C(A*);</td><td>(C) aConstructor.newInstance(arg*);</td>
     * </tr>
     * <tr>
165
     *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
166 167 168 169 170 171 172 173 174 175 176 177 178 179 180 181 182 183
     *     <td>(static)?<br>T m(A*);</td><td>(T) aMethod.invoke(thisOrNull, arg*);</td>
     * </tr>
     * </table>
     * </code>
     * Here, the type {@code C} is the class or interface being searched for a member,
     * documented as a parameter named {@code refc} in the lookup methods.
     * The method or constructor type {@code MT} is composed from the return type {@code T}
     * and the sequence of argument types {@code A*}.
     * Both {@code MT} and the field type {@code FT} are documented as a parameter named {@code type}.
     * The formal parameter {@code this} stands for the self-reference of type {@code C};
     * if it is present, it is always the leading argument to the method handle invocation.
     * The name {@code arg} stands for all the other method handle arguments.
     * In the code examples for the Core Reflection API, the name {@code thisOrNull}
     * stands for a null reference if the accessed method or field is static,
     * and {@code this} otherwise.
     * The names {@code aMethod}, {@code aField}, and {@code aConstructor} stand
     * for reflective objects corresponding to the given members.
     * <p>
184 185 186 187
     * In cases where the given member is of variable arity (i.e., a method or constructor)
     * the returned method handle will also be of {@linkplain MethodHandle#asVarargsCollector variable arity}.
     * In all other cases, the returned method handle will be of fixed arity.
     * <p>
188 189 190 191 192 193 194 195 196 197
     * The equivalence between looked-up method handles and underlying
     * class members can break down in a few ways:
     * <ul>
     * <li>If {@code C} is not symbolically accessible from the lookup class's loader,
     * the lookup can still succeed, even when there is no equivalent
     * Java expression or bytecoded constant.
     * <li>Likewise, if {@code T} or {@code MT}
     * is not symbolically accessible from the lookup class's loader,
     * the lookup can still succeed.
     * For example, lookups for {@code MethodHandle.invokeExact} and
198
     * {@code MethodHandle.invoke} will always succeed, regardless of requested type.
199 200 201 202
     * <li>If there is a security manager installed, it can forbid the lookup
     * on various grounds (<a href="#secmgr">see below</a>).
     * By contrast, the {@code ldc} instruction is not subject to
     * security manager checks.
203 204 205 206 207 208
     * </ul>
     *
     * <h3><a name="access"></a>Access checking</h3>
     * Access checks are applied in the factory methods of {@code Lookup},
     * when a method handle is created.
     * This is a key difference from the Core Reflection API, since
209
     * {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}
210 211 212 213 214 215
     * performs access checking against every caller, on every call.
     * <p>
     * All access checks start from a {@code Lookup} object, which
     * compares its recorded lookup class against all requests to
     * create method handles.
     * A single {@code Lookup} object can be used to create any number
216 217 218
     * of access-checked method handles, all checked against a single
     * lookup class.
     * <p>
219 220 221 222 223 224 225
     * A {@code Lookup} object can be shared with other trusted code,
     * such as a metaobject protocol.
     * A shared {@code Lookup} object delegates the capability
     * to create method handles on private members of the lookup class.
     * Even if privileged code uses the {@code Lookup} object,
     * the access checking is confined to the privileges of the
     * original lookup class.
226
     * <p>
227
     * A lookup can fail, because
228 229 230
     * the containing class is not accessible to the lookup class, or
     * because the desired class member is missing, or because the
     * desired class member is not accessible to the lookup class.
231 232 233 234 235 236 237 238
     * In any of these cases, a {@code ReflectiveOperationException} will be
     * thrown from the attempted lookup.  The exact class will be one of
     * the following:
     * <ul>
     * <li>NoSuchMethodException &mdash; if a method is requested but does not exist
     * <li>NoSuchFieldException &mdash; if a field is requested but does not exist
     * <li>IllegalAccessException &mdash; if the member exists but an access check fails
     * </ul>
239
     * <p>
240
     * In general, the conditions under which a method handle may be
241 242 243 244
     * looked up for a method {@code M} are exactly equivalent to the conditions
     * under which the lookup class could have compiled and resolved a call to {@code M}.
     * And the effect of invoking the method handle resulting from the lookup
     * is exactly equivalent to executing the compiled and resolved call to {@code M}.
245
     * The same point is true of fields and constructors.
246
     * <p>
247
     * In some cases, access between nested classes is obtained by the Java compiler by creating
248 249
     * an wrapper method to access a private method of another class
     * in the same top-level declaration.
250
     * For example, a nested class {@code C.D}
251
     * can access private members within other related classes such as
252 253 254 255 256 257 258
     * {@code C}, {@code C.D.E}, or {@code C.B},
     * but the Java compiler may need to generate wrapper methods in
     * those related classes.  In such cases, a {@code Lookup} object on
     * {@code C.E} would be unable to those private members.
     * A workaround for this limitation is the {@link Lookup#in Lookup.in} method,
     * which can transform a lookup on {@code C.E} into one on any of those other
     * classes, without special elevation of privilege.
259
     * <p>
260 261 262 263 264 265 266 267 268 269 270 271
     * Although bytecode instructions can only refer to classes in
     * a related class loader, this API can search for methods in any
     * class, as long as a reference to its {@code Class} object is
     * available.  Such cross-loader references are also possible with the
     * Core Reflection API, and are impossible to bytecode instructions
     * such as {@code invokestatic} or {@code getfield}.
     * There is a {@linkplain java.lang.SecurityManager security manager API}
     * to allow applications to check such cross-loader references.
     * These checks apply to both the {@code MethodHandles.Lookup} API
     * and the Core Reflection API
     * (as found on {@link java.lang.Class Class}).
     * <p>
272 273 274
     * Access checks only apply to named and reflected methods,
     * constructors, and fields.
     * Other method handle creation methods, such as
275
     * {@link MethodHandle#asType MethodHandle.asType},
276 277 278
     * do not require any access checks, and are done
     * with static methods of {@link MethodHandles},
     * independently of any {@code Lookup} object.
279 280 281 282 283 284 285 286 287 288 289 290 291 292 293 294 295 296 297 298 299 300 301 302 303
     *
     * <h3>Security manager interactions</h3>
     * <a name="secmgr"></a>
     * If a security manager is present, member lookups are subject to
     * additional checks.
     * From one to four calls are made to the security manager.
     * Any of these calls can refuse access by throwing a
     * {@link java.lang.SecurityException SecurityException}.
     * Define {@code smgr} as the security manager,
     * {@code refc} as the containing class in which the member
     * is being sought, and {@code defc} as the class in which the
     * member is actually defined.
     * The calls are made according to the following rules:
     * <ul>
     * <li>In all cases, {@link SecurityManager#checkMemberAccess
     *     smgr.checkMemberAccess(refc, Member.PUBLIC)} is called.
     * <li>If the class loader of the lookup class is not
     *     the same as or an ancestor of the class loader of {@code refc},
     *     then {@link SecurityManager#checkPackageAccess
     *     smgr.checkPackageAccess(refcPkg)} is called,
     *     where {@code refcPkg} is the package of {@code refc}.
     * <li>If the retrieved member is not public,
     *     {@link SecurityManager#checkMemberAccess
     *     smgr.checkMemberAccess(defc, Member.DECLARED)} is called.
     *     (Note that {@code defc} might be the same as {@code refc}.)
304 305 306 307 308 309
     *     The default implementation of this security manager method
     *     inspects the stack to determine the original caller of
     *     the reflective request (such as {@code findStatic}),
     *     and performs additional permission checks if the
     *     class loader of {@code defc} differs from the class
     *     loader of the class from which the reflective request came.
310 311 312 313 314 315 316 317
     * <li>If the retrieved member is not public,
     *     and if {@code defc} and {@code refc} are in different class loaders,
     *     and if the class loader of the lookup class is not
     *     the same as or an ancestor of the class loader of {@code defc},
     *     then {@link SecurityManager#checkPackageAccess
     *     smgr.checkPackageAccess(defcPkg)} is called,
     *     where {@code defcPkg} is the package of {@code defc}.
     * </ul>
318 319 320
     */
    public static final
    class Lookup {
321
        /** The class on behalf of whom the lookup is being performed. */
322 323
        private final Class<?> lookupClass;

324
        /** The allowed sorts of members which may be looked up (PUBLIC, etc.). */
325 326
        private final int allowedModes;

327 328 329 330 331 332 333 334 335 336 337 338 339 340 341 342 343 344 345 346 347 348 349 350 351 352 353 354 355 356
        /** A single-bit mask representing {@code public} access,
         *  which may contribute to the result of {@link #lookupModes lookupModes}.
         *  The value, {@code 0x01}, happens to be the same as the value of the
         *  {@code public} {@linkplain java.lang.reflect.Modifier#PUBLIC modifier bit}.
         */
        public static final int PUBLIC = Modifier.PUBLIC;

        /** A single-bit mask representing {@code private} access,
         *  which may contribute to the result of {@link #lookupModes lookupModes}.
         *  The value, {@code 0x02}, happens to be the same as the value of the
         *  {@code private} {@linkplain java.lang.reflect.Modifier#PRIVATE modifier bit}.
         */
        public static final int PRIVATE = Modifier.PRIVATE;

        /** A single-bit mask representing {@code protected} access,
         *  which may contribute to the result of {@link #lookupModes lookupModes}.
         *  The value, {@code 0x04}, happens to be the same as the value of the
         *  {@code protected} {@linkplain java.lang.reflect.Modifier#PROTECTED modifier bit}.
         */
        public static final int PROTECTED = Modifier.PROTECTED;

        /** A single-bit mask representing {@code package} access (default access),
         *  which may contribute to the result of {@link #lookupModes lookupModes}.
         *  The value is {@code 0x08}, which does not correspond meaningfully to
         *  any particular {@linkplain java.lang.reflect.Modifier modifier bit}.
         */
        public static final int PACKAGE = Modifier.STATIC;

        private static final int ALL_MODES = (PUBLIC | PRIVATE | PROTECTED | PACKAGE);
        private static final int TRUSTED   = -1;
357 358 359 360 361 362

        private static int fixmods(int mods) {
            mods &= (ALL_MODES - PACKAGE);
            return (mods != 0) ? mods : PACKAGE;
        }

363
        /** Tells which class is performing the lookup.  It is this class against
364 365
         *  which checks are performed for visibility and access permissions.
         *  <p>
366 367
         *  The class implies a maximum level of access permission,
         *  but the permissions may be additionally limited by the bitmask
368
         *  {@link #lookupModes lookupModes}, which controls whether non-public members
369
         *  can be accessed.
370 371 372 373 374
         */
        public Class<?> lookupClass() {
            return lookupClass;
        }

375 376 377 378 379
        // This is just for calling out to MethodHandleImpl.
        private Class<?> lookupClassOrNull() {
            return (allowedModes == TRUSTED) ? null : lookupClass;
        }

380
        /** Tells which access-protection classes of members this lookup object can produce.
381 382 383 384 385
         *  The result is a bit-mask of the bits
         *  {@linkplain #PUBLIC PUBLIC (0x01)},
         *  {@linkplain #PRIVATE PRIVATE (0x02)},
         *  {@linkplain #PROTECTED PROTECTED (0x04)},
         *  and {@linkplain #PACKAGE PACKAGE (0x08)}.
386 387
         *  <p>
         *  A freshly-created lookup object
388
         *  on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class}
389 390
         *  has all possible bits set, since the caller class can access all its own members.
         *  A lookup object on a new lookup class
391
         *  {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object}
392 393 394 395
         *  may have some mode bits set to zero.
         *  The purpose of this is to restrict access via the new lookup object,
         *  so that it can access only names which can be reached by the original
         *  lookup object, and also by the new lookup class.
396
         */
397
        public int lookupModes() {
398 399 400
            return allowedModes & ALL_MODES;
        }

401 402 403 404
        /** Embody the current class (the lookupClass) as a lookup class
         * for method handle creation.
         * Must be called by from a method in this package,
         * which in turn is called by a method not in this package.
405
         * <p>
406 407 408 409
         * Also, don't make it private, lest javac interpose
         * an access$N method.
         */
        Lookup() {
410 411 412
            this(getCallerClassAtEntryPoint(), ALL_MODES);
            // make sure we haven't accidentally picked up a privileged class:
            checkUnprivilegedlookupClass(lookupClass);
413 414
        }

415
        Lookup(Class<?> lookupClass) {
416 417 418 419
            this(lookupClass, ALL_MODES);
        }

        private Lookup(Class<?> lookupClass, int allowedModes) {
420
            this.lookupClass = lookupClass;
421
            this.allowedModes = allowedModes;
422 423 424
        }

        /**
425
         * Creates a lookup on the specified new lookup class.
426
         * The resulting object will report the specified
427
         * class as its own {@link #lookupClass lookupClass}.
428 429 430
         * <p>
         * However, the resulting {@code Lookup} object is guaranteed
         * to have no more access capabilities than the original.
431
         * In particular, access capabilities can be lost as follows:<ul>
432 433
         * <li>If the new lookup class differs from the old one,
         * protected members will not be accessible by virtue of inheritance.
434
         * (Protected members may continue to be accessible because of package sharing.)
435 436 437 438
         * <li>If the new lookup class is in a different package
         * than the old one, protected and default (package) members will not be accessible.
         * <li>If the new lookup class is not within the same package member
         * as the old one, private members will not be accessible.
439 440 441
         * <li>If the new lookup class is not accessible to the old lookup class,
         * then no members, not even public members, will be accessible.
         * (In all other cases, public members will continue to be accessible.)
442
         * </ul>
443 444 445 446
         *
         * @param requestedLookupClass the desired lookup class for the new lookup object
         * @return a lookup object which reports the desired lookup class
         * @throws NullPointerException if the argument is null
447
         */
448 449 450 451 452 453 454 455 456 457
        public Lookup in(Class<?> requestedLookupClass) {
            requestedLookupClass.getClass();  // null check
            if (allowedModes == TRUSTED)  // IMPL_LOOKUP can make any lookup at all
                return new Lookup(requestedLookupClass, ALL_MODES);
            if (requestedLookupClass == this.lookupClass)
                return this;  // keep same capabilities
            int newModes = (allowedModes & (ALL_MODES & ~PROTECTED));
            if ((newModes & PACKAGE) != 0
                && !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
                newModes &= ~(PACKAGE|PRIVATE);
458
            }
459
            // Allow nestmate lookups to be created without special privilege:
460 461 462 463
            if ((newModes & PRIVATE) != 0
                && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
                newModes &= ~PRIVATE;
            }
464 465 466 467 468 469
            if (newModes == PUBLIC
                && !VerifyAccess.isClassAccessible(requestedLookupClass, this.lookupClass)) {
                // The requested class it not accessible from the lookup class.
                // No permissions.
                newModes = 0;
            }
470 471
            checkUnprivilegedlookupClass(requestedLookupClass);
            return new Lookup(requestedLookupClass, newModes);
472 473
        }

474
        // Make sure outer class is initialized first.
475
        static { IMPL_NAMES.getClass(); }
476

477 478 479 480
        /** Version of lookup which is trusted minimally.
         *  It can only be used to create method handles to
         *  publicly accessible members.
         */
481
        static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, PUBLIC);
482 483

        /** Package-private version of lookup which is trusted. */
484
        static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
485 486

        private static void checkUnprivilegedlookupClass(Class<?> lookupClass) {
487
            String name = lookupClass.getName();
488
            if (name.startsWith("java.lang.invoke."))
489 490 491
                throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
        }

492
        /**
493
         * Displays the name of the class from which lookups are to be made.
494 495 496
         * (The name is the one reported by {@link java.lang.Class#getName() Class.getName}.)
         * If there are restrictions on the access permitted to this lookup,
         * this is indicated by adding a suffix to the class name, consisting
497 498
         * of a slash and a keyword.  The keyword represents the strongest
         * allowed access, and is chosen as follows:
499 500 501 502 503 504 505 506 507 508
         * <ul>
         * <li>If no access is allowed, the suffix is "/noaccess".
         * <li>If only public access is allowed, the suffix is "/public".
         * <li>If only public and package access are allowed, the suffix is "/package".
         * <li>If only public, package, and private access are allowed, the suffix is "/private".
         * </ul>
         * If none of the above cases apply, it is the case that full
         * access (public, package, private, and protected) is allowed.
         * In this case, no suffix is added.
         * This is true only of an object obtained originally from
509 510
         * {@link java.lang.invoke.MethodHandles#lookup MethodHandles.lookup}.
         * Objects created by {@link java.lang.invoke.MethodHandles.Lookup#in Lookup.in}
511
         * always have restricted access, and will display a suffix.
512 513 514 515 516 517 518
         * <p>
         * (It may seem strange that protected access should be
         * stronger than private access.  Viewed independently from
         * package access, protected access is the first to be lost,
         * because it requires a direct subclass relationship between
         * caller and callee.)
         * @see #in
519
         */
520 521
        @Override
        public String toString() {
522 523
            String cname = lookupClass.getName();
            switch (allowedModes) {
524 525
            case 0:  // no privileges
                return cname + "/noaccess";
526
            case PUBLIC:
527
                return cname + "/public";
528 529
            case PUBLIC|PACKAGE:
                return cname + "/package";
530 531
            case ALL_MODES & ~PROTECTED:
                return cname + "/private";
532 533
            case ALL_MODES:
                return cname;
534 535 536 537 538 539
            case TRUSTED:
                return "/trusted";  // internal only; not exported
            default:  // Should not happen, but it's a bitfield...
                cname = cname + "/" + Integer.toHexString(allowedModes);
                assert(false) : cname;
                return cname;
540
            }
541 542 543 544 545 546 547 548
        }

        // call this from an entry point method in Lookup with extraFrames=0.
        private static Class<?> getCallerClassAtEntryPoint() {
            final int CALLER_DEPTH = 4;
            // 0: Reflection.getCC, 1: getCallerClassAtEntryPoint,
            // 2: Lookup.<init>, 3: MethodHandles.*, 4: caller
            // Note:  This should be the only use of getCallerClass in this file.
549
            assert(Reflection.getCallerClass(CALLER_DEPTH-1) == MethodHandles.class);
550 551 552 553
            return Reflection.getCallerClass(CALLER_DEPTH);
        }

        /**
554
         * Produces a method handle for a static method.
555
         * The type of the method handle will be that of the method.
556 557
         * (Since static methods do not take receivers, there is no
         * additional receiver argument inserted into the method handle type,
558
         * as there would be with {@link #findVirtual findVirtual} or {@link #findSpecial findSpecial}.)
559 560 561
         * The method and all its argument types must be accessible to the lookup class.
         * If the method's class has not yet been initialized, that is done
         * immediately, before the method handle is returned.
562 563 564 565
         * <p>
         * The returned method handle will have
         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
         * the method's variable arity modifier bit ({@code 0x0080}) is set.
566
         * @param refc the class from which the method is accessed
567 568 569
         * @param name the name of the method
         * @param type the type of the method
         * @return the desired method handle
570
         * @throws NoSuchMethodException if the method does not exist
571 572 573 574
         * @throws IllegalAccessException if access checking fails,
         *                                or if the method is not {@code static},
         *                                or if the method's variable arity modifier bit
         *                                is set and {@code asVarargsCollector} fails
575 576
         * @exception SecurityException if a security manager is present and it
         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
577
         * @throws NullPointerException if any argument is null
578 579
         */
        public
580
        MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
581
            MemberName method = resolveOrFail(refc, name, type, true);
582
            checkSecurityManager(refc, method);  // stack walk magic: do not refactor
583 584 585 586
            return accessStatic(refc, method);
        }
        private
        MethodHandle accessStatic(Class<?> refc, MemberName method) throws IllegalAccessException {
587
            checkMethod(refc, method, true);
588
            return MethodHandleImpl.findMethod(method, false, lookupClassOrNull());
589
        }
590 591 592 593 594
        private
        MethodHandle resolveStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
            MemberName method = resolveOrFail(refc, name, type, true);
            return accessStatic(refc, method);
        }
595 596

        /**
597
         * Produces a method handle for a virtual method.
598
         * The type of the method handle will be that of the method,
599
         * with the receiver type (usually {@code refc}) prepended.
600 601 602 603 604 605 606
         * The method and all its argument types must be accessible to the lookup class.
         * <p>
         * When called, the handle will treat the first argument as a receiver
         * and dispatch on the receiver's type to determine which method
         * implementation to enter.
         * (The dispatching action is identical with that performed by an
         * {@code invokevirtual} or {@code invokeinterface} instruction.)
607 608 609 610
         * <p>
         * The returned method handle will have
         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
         * the method's variable arity modifier bit ({@code 0x0080}) is set.
611 612 613 614
         * <p>
         * Because of the general equivalence between {@code invokevirtual}
         * instructions and method handles produced by {@code findVirtual},
         * if the class is {@code MethodHandle} and the name string is
615
         * {@code invokeExact} or {@code invoke}, the resulting
616
         * method handle is equivalent to one produced by
617
         * {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker} or
618
         * {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker}
619 620
         * with the same {@code type} argument.
         *
621
         * @param refc the class or interface from which the method is accessed
622 623 624
         * @param name the name of the method
         * @param type the type of the method, with the receiver argument omitted
         * @return the desired method handle
625
         * @throws NoSuchMethodException if the method does not exist
626 627 628 629
         * @throws IllegalAccessException if access checking fails,
         *                                or if the method is {@code static}
         *                                or if the method's variable arity modifier bit
         *                                is set and {@code asVarargsCollector} fails
630 631
         * @exception SecurityException if a security manager is present and it
         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
632
         * @throws NullPointerException if any argument is null
633
         */
634
        public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
635
            MemberName method = resolveOrFail(refc, name, type, false);
636
            checkSecurityManager(refc, method);  // stack walk magic: do not refactor
637 638 639 640 641 642 643
            return accessVirtual(refc, method);
        }
        private MethodHandle resolveVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
            MemberName method = resolveOrFail(refc, name, type, false);
            return accessVirtual(refc, method);
        }
        private MethodHandle accessVirtual(Class<?> refc, MemberName method) throws IllegalAccessException {
644
            checkMethod(refc, method, false);
645
            MethodHandle mh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
646 647 648 649
            return restrictProtectedReceiver(method, mh);
        }

        /**
650
         * Produces a method handle which creates an object and initializes it, using
651 652 653 654 655 656 657 658
         * the constructor of the specified type.
         * The parameter types of the method handle will be those of the constructor,
         * while the return type will be a reference to the constructor's class.
         * The constructor and all its argument types must be accessible to the lookup class.
         * If the constructor's class has not yet been initialized, that is done
         * immediately, before the method handle is returned.
         * <p>
         * Note:  The requested type must have a return type of {@code void}.
659
         * This is consistent with the JVM's treatment of constructor type descriptors.
660 661 662 663
         * <p>
         * The returned method handle will have
         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
         * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
664 665 666
         * @param refc the class or interface from which the method is accessed
         * @param type the type of the method, with the receiver argument omitted, and a void return type
         * @return the desired method handle
667 668
         * @throws NoSuchMethodException if the constructor does not exist
         * @throws IllegalAccessException if access checking fails
669 670
         *                                or if the method's variable arity modifier bit
         *                                is set and {@code asVarargsCollector} fails
671 672
         * @exception SecurityException if a security manager is present and it
         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
673
         * @throws NullPointerException if any argument is null
674
         */
675
        public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
676 677
            String name = "<init>";
            MemberName ctor = resolveOrFail(refc, name, type, false, false, lookupClassOrNull());
678
            checkSecurityManager(refc, ctor);  // stack walk magic: do not refactor
679 680 681 682
            return accessConstructor(refc, ctor);
        }
        private MethodHandle accessConstructor(Class<?> refc, MemberName ctor) throws IllegalAccessException {
            assert(ctor.isConstructor());
683
            checkAccess(refc, ctor);
684 685
            MethodHandle rawMH = MethodHandleImpl.findMethod(ctor, false, lookupClassOrNull());
            MethodHandle allocMH = MethodHandleImpl.makeAllocator(rawMH);
686 687
            return fixVarargs(allocMH, rawMH);
        }
688 689 690 691 692
        private MethodHandle resolveConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
            String name = "<init>";
            MemberName ctor = resolveOrFail(refc, name, type, false, false, lookupClassOrNull());
            return accessConstructor(refc, ctor);
        }
693 694 695 696 697 698 699 700 701 702 703 704

        /** Return a version of MH which matches matchMH w.r.t. isVarargsCollector. */
        private static MethodHandle fixVarargs(MethodHandle mh, MethodHandle matchMH) {
            boolean va1 = mh.isVarargsCollector();
            boolean va2 = matchMH.isVarargsCollector();
            if (va1 == va2) {
                return mh;
            } else if (va2) {
                MethodType type = mh.type();
                int arity = type.parameterCount();
                return mh.asVarargsCollector(type.parameterType(arity-1));
            } else {
705
                return mh.asFixedArity();
706
            }
707 708 709
        }

        /**
710
         * Produces an early-bound method handle for a virtual method,
711
         * as if called from an {@code invokespecial}
712
         * instruction from {@code caller}.
713
         * The type of the method handle will be that of the method,
714
         * with a suitably restricted receiver type (such as {@code caller}) prepended.
715
         * The method and all its argument types must be accessible
716 717 718 719 720 721 722 723
         * to the caller.
         * <p>
         * When called, the handle will treat the first argument as a receiver,
         * but will not dispatch on the receiver's type.
         * (This direct invocation action is identical with that performed by an
         * {@code invokespecial} instruction.)
         * <p>
         * If the explicitly specified caller class is not identical with the
724 725
         * lookup class, or if this lookup object does not have private access
         * privileges, the access fails.
726 727 728 729
         * <p>
         * The returned method handle will have
         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
         * the method's variable arity modifier bit ({@code 0x0080}) is set.
730 731
         * @param refc the class or interface from which the method is accessed
         * @param name the name of the method (which must not be "&lt;init&gt;")
732 733 734
         * @param type the type of the method, with the receiver argument omitted
         * @param specialCaller the proposed calling class to perform the {@code invokespecial}
         * @return the desired method handle
735 736
         * @throws NoSuchMethodException if the method does not exist
         * @throws IllegalAccessException if access checking fails
737 738
         *                                or if the method's variable arity modifier bit
         *                                is set and {@code asVarargsCollector} fails
739 740
         * @exception SecurityException if a security manager is present and it
         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
741
         * @throws NullPointerException if any argument is null
742
         */
743
        public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
744
                                        Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
745 746
            checkSpecialCaller(specialCaller);
            MemberName method = resolveOrFail(refc, name, type, false, false, specialCaller);
747
            checkSecurityManager(refc, method);  // stack walk magic: do not refactor
748 749 750 751
            return accessSpecial(refc, method, specialCaller);
        }
        private MethodHandle accessSpecial(Class<?> refc, MemberName method,
                                           Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
752
            checkMethod(refc, method, false);
753
            MethodHandle mh = MethodHandleImpl.findMethod(method, false, specialCaller);
754 755
            return restrictReceiver(method, mh, specialCaller);
        }
756 757 758 759 760 761
        private MethodHandle resolveSpecial(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
            Class<?> specialCaller = lookupClass();
            checkSpecialCaller(specialCaller);
            MemberName method = resolveOrFail(refc, name, type, false, false, specialCaller);
            return accessSpecial(refc, method, specialCaller);
        }
762 763

        /**
764
         * Produces a method handle giving read access to a non-static field.
765 766
         * The type of the method handle will have a return type of the field's
         * value type.
767
         * The method handle's single argument will be the instance containing
768 769
         * the field.
         * Access checking is performed immediately on behalf of the lookup class.
770
         * @param refc the class or interface from which the method is accessed
771 772 773
         * @param name the field's name
         * @param type the field's type
         * @return a method handle which can load values from the field
774 775
         * @throws NoSuchFieldException if the field does not exist
         * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
776 777
         * @exception SecurityException if a security manager is present and it
         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
778
         * @throws NullPointerException if any argument is null
779
         */
780
        public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
781 782 783
            MemberName field = resolveOrFail(refc, name, type, false);
            checkSecurityManager(refc, field);  // stack walk magic: do not refactor
            return makeAccessor(refc, field, false, false, 0);
784
        }
785 786 787 788
        private MethodHandle resolveGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
            MemberName field = resolveOrFail(refc, name, type, false);
            return makeAccessor(refc, field, false, false, 0);
        }
789 790

        /**
791
         * Produces a method handle giving write access to a non-static field.
792
         * The type of the method handle will have a void return type.
793
         * The method handle will take two arguments, the instance containing
794
         * the field, and the value to be stored.
795 796
         * The second argument will be of the field's value type.
         * Access checking is performed immediately on behalf of the lookup class.
797
         * @param refc the class or interface from which the method is accessed
798 799 800
         * @param name the field's name
         * @param type the field's type
         * @return a method handle which can store values into the field
801 802
         * @throws NoSuchFieldException if the field does not exist
         * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
803 804
         * @exception SecurityException if a security manager is present and it
         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
805
         * @throws NullPointerException if any argument is null
806
         */
807
        public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
808 809 810
            MemberName field = resolveOrFail(refc, name, type, false);
            checkSecurityManager(refc, field);  // stack walk magic: do not refactor
            return makeAccessor(refc, field, false, true, 0);
811
        }
812 813 814 815
        private MethodHandle resolveSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
            MemberName field = resolveOrFail(refc, name, type, false);
            return makeAccessor(refc, field, false, true, 0);
        }
816 817

        /**
818
         * Produces a method handle giving read access to a static field.
819 820 821 822
         * The type of the method handle will have a return type of the field's
         * value type.
         * The method handle will take no arguments.
         * Access checking is performed immediately on behalf of the lookup class.
823
         * @param refc the class or interface from which the method is accessed
824 825 826
         * @param name the field's name
         * @param type the field's type
         * @return a method handle which can load values from the field
827 828
         * @throws NoSuchFieldException if the field does not exist
         * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
829 830
         * @exception SecurityException if a security manager is present and it
         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
831
         * @throws NullPointerException if any argument is null
832
         */
833
        public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
834 835 836
            MemberName field = resolveOrFail(refc, name, type, true);
            checkSecurityManager(refc, field);  // stack walk magic: do not refactor
            return makeAccessor(refc, field, false, false, 1);
837
        }
838 839 840 841
        private MethodHandle resolveStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
            MemberName field = resolveOrFail(refc, name, type, true);
            return makeAccessor(refc, field, false, false, 1);
        }
842 843

        /**
844
         * Produces a method handle giving write access to a static field.
845 846 847
         * The type of the method handle will have a void return type.
         * The method handle will take a single
         * argument, of the field's value type, the value to be stored.
848
         * Access checking is performed immediately on behalf of the lookup class.
849
         * @param refc the class or interface from which the method is accessed
850 851
         * @param name the field's name
         * @param type the field's type
852
         * @return a method handle which can store values into the field
853 854
         * @throws NoSuchFieldException if the field does not exist
         * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
855 856
         * @exception SecurityException if a security manager is present and it
         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
857
         * @throws NullPointerException if any argument is null
858
         */
859
        public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
860 861 862
            MemberName field = resolveOrFail(refc, name, type, true);
            checkSecurityManager(refc, field);  // stack walk magic: do not refactor
            return makeAccessor(refc, field, false, true, 1);
863
        }
864 865 866 867
        private MethodHandle resolveStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
            MemberName field = resolveOrFail(refc, name, type, true);
            return makeAccessor(refc, field, false, true, 1);
        }
868 869

        /**
870
         * Produces an early-bound method handle for a non-static method.
871 872 873
         * The receiver must have a supertype {@code defc} in which a method
         * of the given name and type is accessible to the lookup class.
         * The method and all its argument types must be accessible to the lookup class.
874 875 876 877 878
         * The type of the method handle will be that of the method,
         * without any insertion of an additional receiver parameter.
         * The given receiver will be bound into the method handle,
         * so that every call to the method handle will invoke the
         * requested method on the given receiver.
879
         * <p>
880 881 882 883 884 885 886 887 888
         * The returned method handle will have
         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
         * the method's variable arity modifier bit ({@code 0x0080}) is set
         * <em>and</em> the trailing array argument is not the only argument.
         * (If the trailing array argument is the only argument,
         * the given receiver value will be bound to it.)
         * <p>
         * This is equivalent to the following code:
         * <blockquote><pre>
889 890 891 892
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
...
MethodHandle mh0 = lookup().{@link #findVirtual findVirtual}(defc, name, type);
893 894
MethodHandle mh1 = mh0.{@link MethodHandle#bindTo bindTo}(receiver);
MethodType mt1 = mh1.type();
895
if (mh0.isVarargsCollector())
896 897 898
  mh1 = mh1.asVarargsCollector(mt1.parameterType(mt1.parameterCount()-1));
return mh1;
         * </pre></blockquote>
899 900 901
         * where {@code defc} is either {@code receiver.getClass()} or a super
         * type of that class, in which the requested method is accessible
         * to the lookup class.
902
         * (Note that {@code bindTo} does not preserve variable arity.)
903 904 905 906
         * @param receiver the object from which the method is accessed
         * @param name the name of the method
         * @param type the type of the method, with the receiver argument omitted
         * @return the desired method handle
907 908
         * @throws NoSuchMethodException if the method does not exist
         * @throws IllegalAccessException if access checking fails
909 910
         *                                or if the method's variable arity modifier bit
         *                                is set and {@code asVarargsCollector} fails
911 912
         * @exception SecurityException if a security manager is present and it
         *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
913
         * @throws NullPointerException if any argument is null
914
         */
915
        public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
916 917
            Class<? extends Object> refc = receiver.getClass(); // may get NPE
            MemberName method = resolveOrFail(refc, name, type, false);
918
            checkSecurityManager(refc, method);  // stack walk magic: do not refactor
919
            checkMethod(refc, method, false);
920 921
            MethodHandle dmh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
            MethodHandle bmh = MethodHandleImpl.bindReceiver(dmh, receiver);
922
            if (bmh == null)
923
                throw method.makeAccessException("no access", this);
924
            return fixVarargs(bmh, dmh);
925 926 927
        }

        /**
928
         * Makes a direct method handle to <i>m</i>, if the lookup class has permission.
929 930 931 932 933 934 935 936
         * If <i>m</i> is non-static, the receiver argument is treated as an initial argument.
         * If <i>m</i> is virtual, overriding is respected on every call.
         * Unlike the Core Reflection API, exceptions are <em>not</em> wrapped.
         * The type of the method handle will be that of the method,
         * with the receiver type prepended (but only if it is non-static).
         * If the method's {@code accessible} flag is not set,
         * access checking is performed immediately on behalf of the lookup class.
         * If <i>m</i> is not public, do not share the resulting handle with untrusted parties.
937 938 939 940
         * <p>
         * The returned method handle will have
         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
         * the method's variable arity modifier bit ({@code 0x0080}) is set.
941 942
         * @param m the reflected method
         * @return a method handle which can invoke the reflected method
943
         * @throws IllegalAccessException if access checking fails
944 945
         *                                or if the method's variable arity modifier bit
         *                                is set and {@code asVarargsCollector} fails
946
         * @throws NullPointerException if the argument is null
947
         */
948
        public MethodHandle unreflect(Method m) throws IllegalAccessException {
949 950 951
            MemberName method = new MemberName(m);
            assert(method.isMethod());
            if (!m.isAccessible())  checkMethod(method.getDeclaringClass(), method, method.isStatic());
952
            MethodHandle mh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
953 954
            if (!m.isAccessible())  mh = restrictProtectedReceiver(method, mh);
            return mh;
955 956 957
        }

        /**
958
         * Produces a method handle for a reflected method.
959
         * It will bypass checks for overriding methods on the receiver,
960
         * as if by a {@code invokespecial} instruction from within the {@code specialCaller}.
961
         * The type of the method handle will be that of the method,
962
         * with the special caller type prepended (and <em>not</em> the receiver of the method).
963 964 965
         * If the method's {@code accessible} flag is not set,
         * access checking is performed immediately on behalf of the lookup class,
         * as if {@code invokespecial} instruction were being linked.
966 967 968 969
         * <p>
         * The returned method handle will have
         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
         * the method's variable arity modifier bit ({@code 0x0080}) is set.
970
         * @param m the reflected method
971
         * @param specialCaller the class nominally calling the method
972
         * @return a method handle which can invoke the reflected method
973
         * @throws IllegalAccessException if access checking fails
974 975
         *                                or if the method's variable arity modifier bit
         *                                is set and {@code asVarargsCollector} fails
976
         * @throws NullPointerException if any argument is null
977
         */
978
        public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException {
979 980 981 982 983
            checkSpecialCaller(specialCaller);
            MemberName method = new MemberName(m);
            assert(method.isMethod());
            // ignore m.isAccessible:  this is a new kind of access
            checkMethod(m.getDeclaringClass(), method, false);
984
            MethodHandle mh = MethodHandleImpl.findMethod(method, false, lookupClassOrNull());
985
            return restrictReceiver(method, mh, specialCaller);
986 987 988
        }

        /**
989
         * Produces a method handle for a reflected constructor.
990 991
         * The type of the method handle will be that of the constructor,
         * with the return type changed to the declaring class.
992 993 994 995 996
         * The method handle will perform a {@code newInstance} operation,
         * creating a new instance of the constructor's class on the
         * arguments passed to the method handle.
         * <p>
         * If the constructor's {@code accessible} flag is not set,
997
         * access checking is performed immediately on behalf of the lookup class.
998 999 1000 1001
         * <p>
         * The returned method handle will have
         * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
         * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
1002
         * @param c the reflected constructor
1003
         * @return a method handle which can invoke the reflected constructor
1004
         * @throws IllegalAccessException if access checking fails
1005 1006
         *                                or if the method's variable arity modifier bit
         *                                is set and {@code asVarargsCollector} fails
1007
         * @throws NullPointerException if the argument is null
1008
         */
1009
        public MethodHandle unreflectConstructor(Constructor c) throws IllegalAccessException {
1010 1011 1012
            MemberName ctor = new MemberName(c);
            assert(ctor.isConstructor());
            if (!c.isAccessible())  checkAccess(c.getDeclaringClass(), ctor);
1013 1014
            MethodHandle rawCtor = MethodHandleImpl.findMethod(ctor, false, lookupClassOrNull());
            MethodHandle allocator = MethodHandleImpl.makeAllocator(rawCtor);
1015
            return fixVarargs(allocator, rawCtor);
1016 1017 1018
        }

        /**
1019
         * Produces a method handle giving read access to a reflected field.
1020
         * The type of the method handle will have a return type of the field's
1021 1022 1023 1024
         * value type.
         * If the field is static, the method handle will take no arguments.
         * Otherwise, its single argument will be the instance containing
         * the field.
1025
         * If the field's {@code accessible} flag is not set,
1026 1027 1028
         * access checking is performed immediately on behalf of the lookup class.
         * @param f the reflected field
         * @return a method handle which can load values from the reflected field
1029 1030
         * @throws IllegalAccessException if access checking fails
         * @throws NullPointerException if the argument is null
1031
         */
1032
        public MethodHandle unreflectGetter(Field f) throws IllegalAccessException {
1033
            return makeAccessor(f.getDeclaringClass(), new MemberName(f), f.isAccessible(), false, -1);
1034 1035 1036
        }

        /**
1037
         * Produces a method handle giving write access to a reflected field.
1038
         * The type of the method handle will have a void return type.
1039 1040 1041 1042
         * If the field is static, the method handle will take a single
         * argument, of the field's value type, the value to be stored.
         * Otherwise, the two arguments will be the instance containing
         * the field, and the value to be stored.
1043
         * If the field's {@code accessible} flag is not set,
1044 1045 1046
         * access checking is performed immediately on behalf of the lookup class.
         * @param f the reflected field
         * @return a method handle which can store values into the reflected field
1047 1048
         * @throws IllegalAccessException if access checking fails
         * @throws NullPointerException if the argument is null
1049
         */
1050
        public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
1051
            return makeAccessor(f.getDeclaringClass(), new MemberName(f), f.isAccessible(), true, -1);
1052 1053
        }

1054
        /// Helper methods, all package-private.
1055

1056
        MemberName resolveOrFail(Class<?> refc, String name, Class<?> type, boolean isStatic) throws NoSuchFieldException, IllegalAccessException {
1057
            checkSymbolicClass(refc);  // do this before attempting to resolve
1058
            name.getClass(); type.getClass();  // NPE
1059
            int mods = (isStatic ? Modifier.STATIC : 0);
1060 1061
            return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull(),
                                            NoSuchFieldException.class);
1062
        }
1063

1064
        MemberName resolveOrFail(Class<?> refc, String name, MethodType type, boolean isStatic) throws NoSuchMethodException, IllegalAccessException {
1065
            checkSymbolicClass(refc);  // do this before attempting to resolve
1066
            name.getClass(); type.getClass();  // NPE
1067
            int mods = (isStatic ? Modifier.STATIC : 0);
1068 1069
            return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull(),
                                            NoSuchMethodException.class);
1070 1071
        }

1072
        MemberName resolveOrFail(Class<?> refc, String name, MethodType type, boolean isStatic,
1073
                                 boolean searchSupers, Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
1074
            checkSymbolicClass(refc);  // do this before attempting to resolve
1075
            name.getClass(); type.getClass();  // NPE
1076
            int mods = (isStatic ? Modifier.STATIC : 0);
1077 1078
            return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), searchSupers, specialCaller,
                                            NoSuchMethodException.class);
1079
        }
1080

1081
        void checkSymbolicClass(Class<?> refc) throws IllegalAccessException {
1082 1083
            Class<?> caller = lookupClassOrNull();
            if (caller != null && !VerifyAccess.isClassAccessible(refc, caller))
1084
                throw new MemberName(refc).makeAccessException("symbolic reference class is not public", this);
1085 1086
        }

1087 1088 1089 1090 1091 1092 1093 1094 1095 1096 1097 1098 1099 1100 1101 1102 1103 1104 1105 1106 1107 1108 1109 1110 1111 1112 1113 1114 1115 1116 1117 1118 1119 1120 1121 1122 1123 1124 1125 1126
        /**
         * Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
         * This function performs stack walk magic: do not refactor it.
         */
        void checkSecurityManager(Class<?> refc, MemberName m) {
            SecurityManager smgr = System.getSecurityManager();
            if (smgr == null)  return;
            if (allowedModes == TRUSTED)  return;
            // Step 1:
            smgr.checkMemberAccess(refc, Member.PUBLIC);
            // Step 2:
            if (!VerifyAccess.classLoaderIsAncestor(lookupClass, refc))
                smgr.checkPackageAccess(VerifyAccess.getPackageName(refc));
            // Step 3:
            if (m.isPublic()) return;
            Class<?> defc = m.getDeclaringClass();
            smgr.checkMemberAccess(defc, Member.DECLARED);  // STACK WALK HERE
            // Step 4:
            if (defc != refc)
                smgr.checkPackageAccess(VerifyAccess.getPackageName(defc));

            // Comment from SM.checkMemberAccess, where which=DECLARED:
            /*
             * stack depth of 4 should be the caller of one of the
             * methods in java.lang.Class that invoke checkMember
             * access. The stack should look like:
             *
             * someCaller                        [3]
             * java.lang.Class.someReflectionAPI [2]
             * java.lang.Class.checkMemberAccess [1]
             * SecurityManager.checkMemberAccess [0]
             *
             */
            // For us it is this stack:
            // someCaller                        [3]
            // Lookup.findSomeMember             [2]
            // Lookup.checkSecurityManager       [1]
            // SecurityManager.checkMemberAccess [0]
        }

1127
        void checkMethod(Class<?> refc, MemberName m, boolean wantStatic) throws IllegalAccessException {
1128 1129 1130 1131 1132 1133 1134 1135 1136
            String message;
            if (m.isConstructor())
                message = "expected a method, not a constructor";
            else if (!m.isMethod())
                message = "expected a method";
            else if (wantStatic != m.isStatic())
                message = wantStatic ? "expected a static method" : "expected a non-static method";
            else
                { checkAccess(refc, m); return; }
1137
            throw m.makeAccessException(message, this);
1138 1139
        }

1140
        void checkAccess(Class<?> refc, MemberName m) throws IllegalAccessException {
1141 1142 1143
            int allowedModes = this.allowedModes;
            if (allowedModes == TRUSTED)  return;
            int mods = m.getModifiers();
1144
            if (Modifier.isPublic(mods) && Modifier.isPublic(refc.getModifiers()) && allowedModes != 0)
1145 1146 1147 1148 1149 1150 1151 1152 1153 1154
                return;  // common case
            int requestedModes = fixmods(mods);  // adjust 0 => PACKAGE
            if ((requestedModes & allowedModes) != 0
                && VerifyAccess.isMemberAccessible(refc, m.getDeclaringClass(),
                                                   mods, lookupClass()))
                return;
            if (((requestedModes & ~allowedModes) & PROTECTED) != 0
                && VerifyAccess.isSamePackage(m.getDeclaringClass(), lookupClass()))
                // Protected members can also be checked as if they were package-private.
                return;
1155
            throw m.makeAccessException(accessFailedMessage(refc, m), this);
1156 1157 1158 1159 1160
        }

        String accessFailedMessage(Class<?> refc, MemberName m) {
            Class<?> defc = m.getDeclaringClass();
            int mods = m.getModifiers();
1161 1162 1163 1164 1165 1166 1167 1168 1169 1170
            // check the class first:
            boolean classOK = (Modifier.isPublic(defc.getModifiers()) &&
                               (defc == refc ||
                                Modifier.isPublic(refc.getModifiers())));
            if (!classOK && (allowedModes & PACKAGE) != 0) {
                classOK = (VerifyAccess.isClassAccessible(defc, lookupClass()) &&
                           (defc == refc ||
                            VerifyAccess.isClassAccessible(refc, lookupClass())));
            }
            if (!classOK)
1171 1172 1173 1174 1175 1176 1177 1178 1179 1180
                return "class is not public";
            if (Modifier.isPublic(mods))
                return "access to public member failed";  // (how?)
            if (Modifier.isPrivate(mods))
                return "member is private";
            if (Modifier.isProtected(mods))
                return "member is protected";
            return "member is private to package";
        }

1181 1182
        private static final boolean ALLOW_NESTMATE_ACCESS = false;

1183
        void checkSpecialCaller(Class<?> specialCaller) throws IllegalAccessException {
1184
            if (allowedModes == TRUSTED)  return;
1185 1186 1187 1188
            if ((allowedModes & PRIVATE) == 0
                || (specialCaller != lookupClass()
                    && !(ALLOW_NESTMATE_ACCESS &&
                         VerifyAccess.isSamePackageMember(specialCaller, lookupClass()))))
1189 1190
                throw new MemberName(specialCaller).
                    makeAccessException("no private access for invokespecial", this);
1191 1192
        }

1193
        MethodHandle restrictProtectedReceiver(MemberName method, MethodHandle mh) throws IllegalAccessException {
1194 1195 1196 1197
            // The accessing class only has the right to use a protected member
            // on itself or a subclass.  Enforce that restriction, from JVMS 5.4.4, etc.
            if (!method.isProtected() || method.isStatic()
                || allowedModes == TRUSTED
1198
                || method.getDeclaringClass() == lookupClass()
1199
                || VerifyAccess.isSamePackage(method.getDeclaringClass(), lookupClass())
1200 1201
                || (ALLOW_NESTMATE_ACCESS &&
                    VerifyAccess.isSamePackageMember(method.getDeclaringClass(), lookupClass())))
1202 1203 1204 1205
                return mh;
            else
                return restrictReceiver(method, mh, lookupClass());
        }
1206
        MethodHandle restrictReceiver(MemberName method, MethodHandle mh, Class<?> caller) throws IllegalAccessException {
1207 1208 1209
            assert(!method.isStatic());
            Class<?> defc = method.getDeclaringClass();  // receiver type of mh is too wide
            if (defc.isInterface() || !defc.isAssignableFrom(caller)) {
1210
                throw method.makeAccessException("caller class must be a subclass below the method", caller);
1211
            }
1212 1213 1214
            MethodType rawType = mh.type();
            if (rawType.parameterType(0) == caller)  return mh;
            MethodType narrowType = rawType.changeParameterType(0, caller);
1215
            MethodHandle narrowMH = MethodHandleImpl.convertArguments(mh, narrowType, rawType, 0);
1216
            return fixVarargs(narrowMH, mh);
1217 1218 1219
        }

        MethodHandle makeAccessor(Class<?> refc, MemberName field,
1220 1221
                                  boolean trusted, boolean isSetter,
                                  int checkStatic) throws IllegalAccessException {
1222
            assert(field.isField());
1223 1224 1225 1226
            if (checkStatic >= 0 && (checkStatic != 0) != field.isStatic())
                throw field.makeAccessException((checkStatic != 0)
                                                ? "expected a static field"
                                                : "expected a non-static field", this);
1227
            if (trusted)
1228
                return MethodHandleImpl.accessField(field, isSetter, lookupClassOrNull());
1229
            checkAccess(refc, field);
1230
            MethodHandle mh = MethodHandleImpl.accessField(field, isSetter, lookupClassOrNull());
1231
            return restrictProtectedReceiver(field, mh);
1232
        }
1233 1234 1235 1236 1237 1238 1239 1240 1241 1242 1243 1244 1245 1246 1247 1248 1249 1250 1251

        /** Hook called from the JVM (via MethodHandleNatives) to link MH constants:
         */
        /*non-public*/
        MethodHandle linkMethodHandleConstant(int refKind, Class<?> defc, String name, Object type) throws ReflectiveOperationException {
            switch (refKind) {
            case REF_getField:          return resolveGetter(       defc, name, (Class<?>)   type );
            case REF_getStatic:         return resolveStaticGetter( defc, name, (Class<?>)   type );
            case REF_putField:          return resolveSetter(       defc, name, (Class<?>)   type );
            case REF_putStatic:         return resolveStaticSetter( defc, name, (Class<?>)   type );
            case REF_invokeVirtual:     return resolveVirtual(      defc, name, (MethodType) type );
            case REF_invokeStatic:      return resolveStatic(       defc, name, (MethodType) type );
            case REF_invokeSpecial:     return resolveSpecial(      defc, name, (MethodType) type );
            case REF_newInvokeSpecial:  return resolveConstructor(  defc,       (MethodType) type );
            case REF_invokeInterface:   return resolveVirtual(      defc, name, (MethodType) type );
            }
            // oops
            throw new ReflectiveOperationException("bad MethodHandle constant #"+refKind+" "+name+" : "+type);
        }
1252 1253 1254
    }

    /**
1255
     * Produces a method handle giving read access to elements of an array.
1256 1257 1258 1259 1260
     * The type of the method handle will have a return type of the array's
     * element type.  Its first argument will be the array type,
     * and the second will be {@code int}.
     * @param arrayClass an array type
     * @return a method handle which can load values from the given array type
1261
     * @throws NullPointerException if the argument is null
1262 1263 1264 1265
     * @throws  IllegalArgumentException if arrayClass is not an array type
     */
    public static
    MethodHandle arrayElementGetter(Class<?> arrayClass) throws IllegalArgumentException {
1266
        return MethodHandleImpl.accessArrayElement(arrayClass, false);
1267 1268 1269
    }

    /**
1270
     * Produces a method handle giving write access to elements of an array.
1271 1272 1273 1274
     * The type of the method handle will have a void return type.
     * Its last argument will be the array's element type.
     * The first and second arguments will be the array type and int.
     * @return a method handle which can store values into the array type
1275
     * @throws NullPointerException if the argument is null
1276 1277 1278 1279
     * @throws IllegalArgumentException if arrayClass is not an array type
     */
    public static
    MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException {
1280
        return MethodHandleImpl.accessArrayElement(arrayClass, true);
1281 1282 1283 1284 1285
    }

    /// method handle invocation (reflective style)

    /**
1286
     * Produces a method handle which will invoke any method handle of the
1287 1288
     * given {@code type}, with a given number of trailing arguments replaced by
     * a single trailing {@code Object[]} array.
1289 1290 1291 1292
     * The resulting invoker will be a method handle with the following
     * arguments:
     * <ul>
     * <li>a single {@code MethodHandle} target
1293 1294
     * <li>zero or more leading values (counted by {@code leadingArgCount})
     * <li>an {@code Object[]} array containing trailing arguments
1295
     * </ul>
1296
     * <p>
1297
     * The invoker will invoke its target like a call to {@link MethodHandle#invoke invoke} with
1298 1299
     * the indicated {@code type}.
     * That is, if the target is exactly of the given {@code type}, it will behave
1300
     * like {@code invokeExact}; otherwise it behave as if {@link MethodHandle#asType asType}
1301 1302 1303
     * is used to convert the target to the required {@code type}.
     * <p>
     * The type of the returned invoker will not be the given {@code type}, but rather
1304 1305 1306
     * will have all parameters except the first {@code leadingArgCount}
     * replaced by a single array of type {@code Object[]}, which will be
     * the final parameter.
1307
     * <p>
1308
     * Before invoking its target, the invoker will spread the final array, apply
1309
     * reference casts as necessary, and unbox and widen primitive arguments.
1310 1311 1312
     * <p>
     * This method is equivalent to the following code (though it may be more efficient):
     * <p><blockquote><pre>
1313
MethodHandle invoker = MethodHandles.invoker(type);
1314
int spreadArgCount = type.parameterCount() - leadingArgCount;
1315 1316
invoker = invoker.asSpreader(Object[].class, spreadArgCount);
return invoker;
1317
     * </pre></blockquote>
1318 1319
     * <p>
     * This method throws no reflective or security exceptions.
1320
     * @param type the desired target type
1321
     * @param leadingArgCount number of fixed arguments, to be passed unchanged to the target
1322
     * @return a method handle suitable for invoking any method handle of the given type
1323 1324 1325
     * @throws NullPointerException if {@code type} is null
     * @throws IllegalArgumentException if {@code leadingArgCount} is not in
     *                  the range from 0 to {@code type.parameterCount()} inclusive
1326 1327
     */
    static public
1328 1329 1330 1331
    MethodHandle spreadInvoker(MethodType type, int leadingArgCount) {
        if (leadingArgCount < 0 || leadingArgCount > type.parameterCount())
            throw new IllegalArgumentException("bad argument count "+leadingArgCount);
        return type.invokers().spreadInvoker(leadingArgCount);
1332 1333 1334
    }

    /**
1335
     * Produces a special <em>invoker method handle</em> which can be used to
1336
     * invoke any method handle of the given type, as if by {@link MethodHandle#invokeExact invokeExact}.
1337
     * The resulting invoker will have a type which is
1338 1339 1340
     * exactly equal to the desired type, except that it will accept
     * an additional leading argument of type {@code MethodHandle}.
     * <p>
1341 1342
     * This method is equivalent to the following code (though it may be more efficient):
     * <p><blockquote><pre>
1343
publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)
1344
     * </pre></blockquote>
1345 1346 1347 1348 1349 1350 1351 1352
     *
     * <p style="font-size:smaller;">
     * <em>Discussion:</em>
     * Invoker method handles can be useful when working with variable method handles
     * of unknown types.
     * For example, to emulate an {@code invokeExact} call to a variable method
     * handle {@code M}, extract its type {@code T},
     * look up the invoker method {@code X} for {@code T},
1353
     * and call the invoker method, as {@code X.invoke(T, A...)}.
1354 1355 1356 1357 1358 1359 1360
     * (It would not work to call {@code X.invokeExact}, since the type {@code T}
     * is unknown.)
     * If spreading, collecting, or other argument transformations are required,
     * they can be applied once to the invoker {@code X} and reused on many {@code M}
     * method handle values, as long as they are compatible with the type of {@code X}.
     * <p>
     * <em>(Note:  The invoker method is not available via the Core Reflection API.
1361
     * An attempt to call {@linkplain java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}
1362
     * on the declared {@code invokeExact} or {@code invoke} method will raise an
1363 1364 1365
     * {@link java.lang.UnsupportedOperationException UnsupportedOperationException}.)</em>
     * <p>
     * This method throws no reflective or security exceptions.
1366 1367 1368 1369 1370
     * @param type the desired target type
     * @return a method handle suitable for invoking any method handle of the given type
     */
    static public
    MethodHandle exactInvoker(MethodType type) {
1371
        return type.invokers().exactInvoker();
1372 1373
    }

1374 1375
    /**
     * Produces a special <em>invoker method handle</em> which can be used to
1376
     * invoke any method handle compatible with the given type, as if by {@link MethodHandle#invoke invoke}.
1377 1378 1379 1380
     * The resulting invoker will have a type which is
     * exactly equal to the desired type, except that it will accept
     * an additional leading argument of type {@code MethodHandle}.
     * <p>
1381 1382
     * Before invoking its target, if the target differs from the expected type,
     * the invoker will apply reference casts as
1383 1384 1385 1386
     * necessary and box, unbox, or widen primitive values, as if by {@link MethodHandle#asType asType}.
     * Similarly, the return value will be converted as necessary.
     * If the target is a {@linkplain MethodHandle#asVarargsCollector variable arity method handle},
     * the required arity conversion will be made, again as if by {@link MethodHandle#asType asType}.
1387
     * <p>
1388 1389 1390 1391 1392
     * A {@linkplain MethodType#genericMethodType general method type},
     * mentions only {@code Object} arguments and return values.
     * An invoker for such a type is capable of calling any method handle
     * of the same arity as the general type.
     * <p>
1393 1394
     * This method is equivalent to the following code (though it may be more efficient):
     * <p><blockquote><pre>
1395
publicLookup().findVirtual(MethodHandle.class, "invoke", type)
1396 1397 1398 1399 1400 1401 1402
     * </pre></blockquote>
     * <p>
     * This method throws no reflective or security exceptions.
     * @param type the desired target type
     * @return a method handle suitable for invoking any method handle convertible to the given type
     */
    static public
1403 1404 1405 1406
    MethodHandle invoker(MethodType type) {
        return type.invokers().generalInvoker();
    }

1407 1408 1409
    /**
     * Perform value checking, exactly as if for an adapted method handle.
     * It is assumed that the given value is either null, of type T0,
1410
     * or (if T0 is primitive) of the wrapper class corresponding to T0.
1411 1412 1413 1414 1415 1416 1417
     * The following checks and conversions are made:
     * <ul>
     * <li>If T0 and T1 are references, then a cast to T1 is applied.
     *     (The types do not need to be related in any particular way.)
     * <li>If T0 and T1 are primitives, then a widening or narrowing
     *     conversion is applied, if one exists.
     * <li>If T0 is a primitive and T1 a reference, and
1418
     *     T0 has a wrapper class TW, a boxing conversion to TW is applied,
1419 1420 1421
     *     possibly followed by a reference conversion.
     *     T1 must be TW or a supertype.
     * <li>If T0 is a reference and T1 a primitive, and
1422
     *     T1 has a wrapper class TW, an unboxing conversion is applied,
1423 1424 1425 1426 1427 1428 1429 1430 1431 1432 1433 1434
     *     possibly preceded by a reference conversion.
     *     T0 must be TW or a supertype.
     * <li>If T1 is void, the return value is discarded
     * <li>If T0 is void and T1 a reference, a null value is introduced.
     * <li>If T0 is void and T1 a primitive, a zero value is introduced.
     * </ul>
     * If the value is discarded, null will be returned.
     * @param valueType
     * @param value
     * @return the value, converted if necessary
     * @throws java.lang.ClassCastException if a cast fails
     */
1435
    // FIXME: This is used in just one place.  Refactor away.
1436 1437 1438 1439 1440 1441 1442 1443 1444
    static
    <T0, T1> T1 checkValue(Class<T0> t0, Class<T1> t1, Object value)
       throws ClassCastException
    {
        if (t0 == t1) {
            // no conversion needed; just reassert the same type
            if (t0.isPrimitive())
                return Wrapper.asPrimitiveType(t1).cast(value);
            else
1445
                return Wrapper.OBJECT.convert(value, t1);
1446 1447 1448 1449
        }
        boolean prim0 = t0.isPrimitive(), prim1 = t1.isPrimitive();
        if (!prim0) {
            // check contract with caller
1450
            Wrapper.OBJECT.convert(value, t0);
1451
            if (!prim1) {
1452
                return Wrapper.OBJECT.convert(value, t1);
1453 1454 1455
            }
            // convert reference to primitive by unboxing
            Wrapper w1 = Wrapper.forPrimitiveType(t1);
1456
            return w1.convert(value, t1);
1457 1458 1459 1460
        }
        // check contract with caller:
        Wrapper.asWrapperType(t0).cast(value);
        Wrapper w1 = Wrapper.forPrimitiveType(t1);
1461
        return w1.convert(value, t1);
1462 1463
    }

1464 1465
    // FIXME: Delete this.  It is used only for insertArguments & bindTo.
    // Replace by a more standard check.
1466 1467 1468 1469 1470 1471 1472 1473 1474 1475 1476 1477 1478 1479 1480
    static
    Object checkValue(Class<?> T1, Object value)
       throws ClassCastException
    {
        Class<?> T0;
        if (value == null)
            T0 = Object.class;
        else
            T0 = value.getClass();
        return checkValue(T0, T1, value);
    }

    /// method handle modification (creation from other method handles)

    /**
1481
     * Produces a method handle which adapts the type of the
1482
     * given method handle to a new type by pairwise argument and return type conversion.
1483 1484 1485 1486 1487 1488
     * The original type and new type must have the same number of arguments.
     * The resulting method handle is guaranteed to report a type
     * which is equal to the desired new type.
     * <p>
     * If the original type and new type are equal, returns target.
     * <p>
1489
     * The same conversions are allowed as for {@link MethodHandle#asType MethodHandle.asType},
1490
     * and some additional conversions are also applied if those conversions fail.
1491 1492
     * Given types <em>T0</em>, <em>T1</em>, one of the following conversions is applied
     * if possible, before or instead of any conversions done by {@code asType}:
1493
     * <ul>
1494 1495
     * <li>If <em>T0</em> and <em>T1</em> are references, and <em>T1</em> is an interface type,
     *     then the value of type <em>T0</em> is passed as a <em>T1</em> without a cast.
1496
     *     (This treatment of interfaces follows the usage of the bytecode verifier.)
1497 1498
     * <li>If <em>T0</em> is boolean and <em>T1</em> is another primitive,
     *     the boolean is converted to a byte value, 1 for true, 0 for false.
1499
     *     (This treatment follows the usage of the bytecode verifier.)
1500 1501 1502 1503 1504 1505 1506 1507 1508 1509 1510 1511 1512 1513
     * <li>If <em>T1</em> is boolean and <em>T0</em> is another primitive,
     *     <em>T0</em> is converted to byte via Java casting conversion (JLS 5.5),
     *     and the low order bit of the result is tested, as if by {@code (x & 1) != 0}.
     * <li>If <em>T0</em> and <em>T1</em> are primitives other than boolean,
     *     then a Java casting conversion (JLS 5.5) is applied.
     *     (Specifically, <em>T0</em> will convert to <em>T1</em> by
     *     widening and/or narrowing.)
     * <li>If <em>T0</em> is a reference and <em>T1</em> a primitive, an unboxing
     *     conversion will be applied at runtime, possibly followed
     *     by a Java casting conversion (JLS 5.5) on the primitive value,
     *     possibly followed by a conversion from byte to boolean by testing
     *     the low-order bit.
     * <li>If <em>T0</em> is a reference and <em>T1</em> a primitive,
     *     and if the reference is null at runtime, a zero value is introduced.
1514 1515 1516
     * </ul>
     * @param target the method handle to invoke after arguments are retyped
     * @param newType the expected type of the new method handle
1517
     * @return a method handle which delegates to the target after performing
1518 1519
     *           any necessary argument conversions, and arranges for any
     *           necessary return value conversions
1520
     * @throws NullPointerException if either argument is null
1521 1522 1523 1524 1525
     * @throws WrongMethodTypeException if the conversion cannot be made
     * @see MethodHandle#asType
     */
    public static
    MethodHandle explicitCastArguments(MethodHandle target, MethodType newType) {
1526
        return MethodHandleImpl.convertArguments(target, newType, 2);
1527 1528 1529
    }

    /**
1530
     * Produces a method handle which adapts the calling sequence of the
1531
     * given method handle to a new type, by reordering the arguments.
1532
     * The resulting method handle is guaranteed to report a type
1533 1534 1535 1536 1537 1538 1539 1540 1541 1542 1543 1544
     * which is equal to the desired new type.
     * <p>
     * The given array controls the reordering.
     * Call {@code #I} the number of incoming parameters (the value
     * {@code newType.parameterCount()}, and call {@code #O} the number
     * of outgoing parameters (the value {@code target.type().parameterCount()}).
     * Then the length of the reordering array must be {@code #O},
     * and each element must be a non-negative number less than {@code #I}.
     * For every {@code N} less than {@code #O}, the {@code N}-th
     * outgoing argument will be taken from the {@code I}-th incoming
     * argument, where {@code I} is {@code reorder[N]}.
     * <p>
1545 1546
     * No argument or return value conversions are applied.
     * The type of each incoming argument, as determined by {@code newType},
1547 1548
     * must be identical to the type of the corresponding outgoing parameter
     * or parameters in the target method handle.
1549 1550 1551
     * The return type of {@code newType} must be identical to the return
     * type of the original target.
     * <p>
1552 1553 1554 1555
     * The reordering array need not specify an actual permutation.
     * An incoming argument will be duplicated if its index appears
     * more than once in the array, and an incoming argument will be dropped
     * if its index does not appear in the array.
1556 1557 1558 1559
     * As in the case of {@link #dropArguments(MethodHandle,int,List) dropArguments},
     * incoming arguments which are not mentioned in the reordering array
     * are may be any type, as determined only by {@code newType}.
     * <blockquote><pre>
1560 1561 1562 1563 1564
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
...
MethodType intfn1 = methodType(int.class, int.class);
MethodType intfn2 = methodType(int.class, int.class, int.class);
1565 1566
MethodHandle sub = ... {int x, int y => x-y} ...;
assert(sub.type().equals(intfn2));
1567 1568
MethodHandle sub1 = permuteArguments(sub, intfn2, 0, 1);
MethodHandle rsub = permuteArguments(sub, intfn2, 1, 0);
1569 1570 1571
assert((int)rsub.invokeExact(1, 100) == 99);
MethodHandle add = ... {int x, int y => x+y} ...;
assert(add.type().equals(intfn2));
1572
MethodHandle twice = permuteArguments(add, intfn1, 0, 0);
1573 1574 1575
assert(twice.type().equals(intfn1));
assert((int)twice.invokeExact(21) == 42);
     * </pre></blockquote>
1576 1577
     * @param target the method handle to invoke after arguments are reordered
     * @param newType the expected type of the new method handle
1578 1579
     * @param reorder an index array which controls the reordering
     * @return a method handle which delegates to the target after it
1580
     *           drops unused arguments and moves and/or duplicates the other arguments
1581
     * @throws NullPointerException if any argument is null
1582 1583 1584 1585 1586
     * @throws IllegalArgumentException if the index array length is not equal to
     *                  the arity of the target, or if any index array element
     *                  not a valid index for a parameter of {@code newType},
     *                  or if two corresponding parameter types in
     *                  {@code target.type()} and {@code newType} are not identical,
1587 1588
     */
    public static
1589
    MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder) {
1590 1591
        MethodType oldType = target.type();
        checkReorder(reorder, newType, oldType);
1592
        return MethodHandleImpl.permuteArguments(target,
1593 1594 1595 1596 1597
                                                 newType, oldType,
                                                 reorder);
    }

    private static void checkReorder(int[] reorder, MethodType newType, MethodType oldType) {
1598 1599 1600
        if (newType.returnType() != oldType.returnType())
            throw newIllegalArgumentException("return types do not match",
                    oldType, newType);
1601 1602 1603
        if (reorder.length == oldType.parameterCount()) {
            int limit = newType.parameterCount();
            boolean bad = false;
1604 1605
            for (int j = 0; j < reorder.length; j++) {
                int i = reorder[j];
1606 1607 1608
                if (i < 0 || i >= limit) {
                    bad = true; break;
                }
1609 1610 1611 1612 1613
                Class<?> src = newType.parameterType(i);
                Class<?> dst = oldType.parameterType(j);
                if (src != dst)
                    throw newIllegalArgumentException("parameter types do not match after reorder",
                            oldType, newType);
1614 1615 1616
            }
            if (!bad)  return;
        }
1617
        throw newIllegalArgumentException("bad reorder array: "+Arrays.toString(reorder));
1618 1619 1620
    }

    /**
1621
     * Produces a method handle of the requested return type which returns the given
1622 1623 1624 1625 1626
     * constant value every time it is invoked.
     * <p>
     * Before the method handle is returned, the passed-in value is converted to the requested type.
     * If the requested type is primitive, widening primitive conversions are attempted,
     * else reference conversions are attempted.
1627
     * <p>The returned method handle is equivalent to {@code identity(type).bindTo(value)}.
1628 1629 1630
     * @param type the return type of the desired method handle
     * @param value the value to return
     * @return a method handle of the given return type and no arguments, which always returns the given value
1631 1632 1633
     * @throws NullPointerException if the {@code type} argument is null
     * @throws ClassCastException if the value cannot be converted to the required return type
     * @throws IllegalArgumentException if the given type is {@code void.class}
1634 1635 1636 1637
     */
    public static
    MethodHandle constant(Class<?> type, Object value) {
        if (type.isPrimitive()) {
1638 1639
            if (type == void.class)
                throw newIllegalArgumentException("void type");
1640
            Wrapper w = Wrapper.forPrimitiveType(type);
1641
            return insertArguments(identity(type), 0, w.convert(value, type));
1642 1643 1644 1645 1646 1647
        } else {
            return identity(type).bindTo(type.cast(value));
        }
    }

    /**
1648 1649 1650 1651 1652
     * Produces a method handle which returns its sole argument when invoked.
     * @param type the type of the sole parameter and return value of the desired method handle
     * @return a unary method handle which accepts and returns the given type
     * @throws NullPointerException if the argument is null
     * @throws IllegalArgumentException if the given type is {@code void.class}
1653 1654 1655
     */
    public static
    MethodHandle identity(Class<?> type) {
1656 1657
        if (type == void.class)
            throw newIllegalArgumentException("void type");
1658 1659 1660 1661 1662 1663 1664
        else if (type == Object.class)
            return ValueConversions.identity();
        else if (type.isPrimitive())
            return ValueConversions.identity(Wrapper.forPrimitiveType(type));
        else
            return AdapterMethodHandle.makeRetypeRaw(
                    MethodType.methodType(type, type), ValueConversions.identity());
1665 1666 1667
    }

    /**
1668 1669 1670 1671 1672 1673 1674 1675 1676
     * Provides a target method handle with one or more <em>bound arguments</em>
     * in advance of the method handle's invocation.
     * The formal parameters to the target corresponding to the bound
     * arguments are called <em>bound parameters</em>.
     * Returns a new method handle which saves away the bound arguments.
     * When it is invoked, it receives arguments for any non-bound parameters,
     * binds the saved arguments to their corresponding parameters,
     * and calls the original target.
     * <p>
1677 1678 1679
     * The type of the new method handle will drop the types for the bound
     * parameters from the original target type, since the new method handle
     * will no longer require those arguments to be supplied by its callers.
1680
     * <p>
1681 1682 1683
     * Each given argument object must match the corresponding bound parameter type.
     * If a bound parameter type is a primitive, the argument object
     * must be a wrapper, and will be unboxed to produce the primitive value.
1684
     * <p>
1685 1686 1687 1688
     * The {@code pos} argument selects which parameters are to be bound.
     * It may range between zero and <i>N-L</i> (inclusively),
     * where <i>N</i> is the arity of the target method handle
     * and <i>L</i> is the length of the values array.
1689 1690
     * @param target the method handle to invoke after the argument is inserted
     * @param pos where to insert the argument (zero for the first)
1691
     * @param values the series of arguments to insert
1692
     * @return a method handle which inserts an additional argument,
1693
     *         before calling the original method handle
1694
     * @throws NullPointerException if the target or the {@code values} array is null
1695
     * @see MethodHandle#bindTo
1696 1697
     */
    public static
1698 1699
    MethodHandle insertArguments(MethodHandle target, int pos, Object... values) {
        int insCount = values.length;
1700 1701
        MethodType oldType = target.type();
        int outargs = oldType.parameterCount();
1702 1703 1704 1705
        int inargs  = outargs - insCount;
        if (inargs < 0)
            throw newIllegalArgumentException("too many values to insert");
        if (pos < 0 || pos > inargs)
1706
            throw newIllegalArgumentException("no argument type to append");
1707 1708 1709 1710 1711 1712 1713
        MethodHandle result = target;
        for (int i = 0; i < insCount; i++) {
            Object value = values[i];
            Class<?> valueType = oldType.parameterType(pos+i);
            value = checkValue(valueType, value);
            if (pos == 0 && !valueType.isPrimitive()) {
                // At least for now, make bound method handles a special case.
1714
                MethodHandle bmh = MethodHandleImpl.bindReceiver(result, value);
1715 1716 1717 1718 1719 1720
                if (bmh != null) {
                    result = bmh;
                    continue;
                }
                // else fall through to general adapter machinery
            }
1721
            result = MethodHandleImpl.bindArgument(result, pos, value);
1722
        }
1723 1724 1725
        return result;
    }

1726
    /**
1727 1728 1729 1730 1731
     * Produces a method handle which will discard some dummy arguments
     * before calling some other specified <i>target</i> method handle.
     * The type of the new method handle will be the same as the target's type,
     * except it will also include the dummy argument types,
     * at some given position.
1732
     * <p>
1733 1734 1735 1736 1737
     * The {@code pos} argument may range between zero and <i>N</i>,
     * where <i>N</i> is the arity of the target.
     * If {@code pos} is zero, the dummy arguments will precede
     * the target's real arguments; if {@code pos} is <i>N</i>
     * they will come after.
1738 1739 1740
     * <p>
     * <b>Example:</b>
     * <p><blockquote><pre>
1741 1742
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
1743 1744 1745 1746
...
MethodHandle cat = lookup().findVirtual(String.class,
  "concat", methodType(String.class, String.class));
assertEquals("xy", (String) cat.invokeExact("x", "y"));
1747 1748 1749 1750 1751 1752 1753 1754 1755
MethodType bigType = cat.type().insertParameterTypes(0, int.class, String.class);
MethodHandle d0 = dropArguments(cat, 0, bigType.parameterList().subList(0,2));
assertEquals(bigType, d0.type());
assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));
     * </pre></blockquote>
     * <p>
     * This method is also equivalent to the following code:
     * <p><blockquote><pre>
     * {@link #dropArguments(MethodHandle,int,Class...) dropArguments}(target, pos, valueTypes.toArray(new Class[0]))
1756
     * </pre></blockquote>
1757 1758 1759 1760
     * @param target the method handle to invoke after the arguments are dropped
     * @param valueTypes the type(s) of the argument(s) to drop
     * @param pos position of first argument to drop (zero for the leftmost)
     * @return a method handle which drops arguments of the given types,
1761
     *         before calling the original method handle
1762
     * @throws NullPointerException if the target is null,
1763
     *                              or if the {@code valueTypes} list or any of its elements is null
1764 1765 1766
     * @throws IllegalArgumentException if any element of {@code valueTypes} is {@code void.class},
     *                  or if {@code pos} is negative or greater than the arity of the target,
     *                  or if the new method handle's type would have too many parameters
1767 1768
     */
    public static
1769
    MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) {
1770
        MethodType oldType = target.type();  // get NPE
1771
        if (valueTypes.size() == 0)  return target;
1772
        int outargs = oldType.parameterCount();
1773
        int inargs  = outargs + valueTypes.size();
1774 1775 1776 1777
        if (pos < 0 || pos >= inargs)
            throw newIllegalArgumentException("no argument type to remove");
        ArrayList<Class<?>> ptypes =
                new ArrayList<Class<?>>(oldType.parameterList());
1778 1779
        ptypes.addAll(pos, valueTypes);
        MethodType newType = MethodType.methodType(oldType.returnType(), ptypes);
1780
        return MethodHandleImpl.dropArguments(target, newType, pos);
1781 1782
    }

1783
    /**
1784 1785 1786 1787 1788
     * Produces a method handle which will discard some dummy arguments
     * before calling some other specified <i>target</i> method handle.
     * The type of the new method handle will be the same as the target's type,
     * except it will also include the dummy argument types,
     * at some given position.
1789
     * <p>
1790 1791 1792 1793 1794
     * The {@code pos} argument may range between zero and <i>N</i>,
     * where <i>N</i> is the arity of the target.
     * If {@code pos} is zero, the dummy arguments will precede
     * the target's real arguments; if {@code pos} is <i>N</i>
     * they will come after.
1795 1796 1797 1798 1799 1800 1801 1802 1803 1804 1805 1806 1807 1808 1809 1810 1811 1812 1813 1814 1815
     * <p>
     * <b>Example:</b>
     * <p><blockquote><pre>
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
...
MethodHandle cat = lookup().findVirtual(String.class,
  "concat", methodType(String.class, String.class));
assertEquals("xy", (String) cat.invokeExact("x", "y"));
MethodHandle d0 = dropArguments(cat, 0, String.class);
assertEquals("yz", (String) d0.invokeExact("x", "y", "z"));
MethodHandle d1 = dropArguments(cat, 1, String.class);
assertEquals("xz", (String) d1.invokeExact("x", "y", "z"));
MethodHandle d2 = dropArguments(cat, 2, String.class);
assertEquals("xy", (String) d2.invokeExact("x", "y", "z"));
MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class);
assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
     * </pre></blockquote>
     * <p>
     * This method is also equivalent to the following code:
     * <p><blockquote><pre>
1816
     * {@link #dropArguments(MethodHandle,int,List) dropArguments}(target, pos, Arrays.asList(valueTypes))
1817
     * </pre></blockquote>
1818 1819 1820 1821 1822
     * @param target the method handle to invoke after the arguments are dropped
     * @param valueTypes the type(s) of the argument(s) to drop
     * @param pos position of first argument to drop (zero for the leftmost)
     * @return a method handle which drops arguments of the given types,
     *         before calling the original method handle
1823
     * @throws NullPointerException if the target is null,
1824
     *                              or if the {@code valueTypes} array or any of its elements is null
1825 1826 1827
     * @throws IllegalArgumentException if any element of {@code valueTypes} is {@code void.class},
     *                  or if {@code pos} is negative or greater than the arity of the target,
     *                  or if the new method handle's type would have too many parameters
1828
     */
1829 1830 1831 1832 1833 1834
    public static
    MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes) {
        return dropArguments(target, pos, Arrays.asList(valueTypes));
    }

    /**
1835
     * Adapts a target method handle by pre-processing
1836 1837 1838 1839 1840
     * one or more of its arguments, each with its own unary filter function,
     * and then calling the target with each pre-processed argument
     * replaced by the result of its corresponding filter function.
     * <p>
     * The pre-processing is performed by one or more method handles,
1841
     * specified in the elements of the {@code filters} array.
1842 1843 1844 1845 1846
     * The first element of the filter array corresponds to the {@code pos}
     * argument of the target, and so on in sequence.
     * <p>
     * Null arguments in the array are treated as identity functions,
     * and the corresponding arguments left unchanged.
1847
     * (If there are no non-null elements in the array, the original target is returned.)
1848
     * Each filter is applied to the corresponding argument of the adapter.
1849 1850
     * <p>
     * If a filter {@code F} applies to the {@code N}th argument of
1851
     * the target, then {@code F} must be a method handle which
1852 1853 1854 1855 1856 1857
     * takes exactly one argument.  The type of {@code F}'s sole argument
     * replaces the corresponding argument type of the target
     * in the resulting adapted method handle.
     * The return type of {@code F} must be identical to the corresponding
     * parameter type of the target.
     * <p>
1858
     * It is an error if there are elements of {@code filters}
1859
     * (null or not)
1860
     * which do not correspond to argument positions in the target.
1861 1862
     * <b>Example:</b>
     * <p><blockquote><pre>
1863 1864
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
1865 1866 1867 1868 1869
...
MethodHandle cat = lookup().findVirtual(String.class,
  "concat", methodType(String.class, String.class));
MethodHandle upcase = lookup().findVirtual(String.class,
  "toUpperCase", methodType(String.class));
1870
assertEquals("xy", (String) cat.invokeExact("x", "y"));
1871
MethodHandle f0 = filterArguments(cat, 0, upcase);
1872
assertEquals("Xy", (String) f0.invokeExact("x", "y")); // Xy
1873
MethodHandle f1 = filterArguments(cat, 1, upcase);
1874
assertEquals("xY", (String) f1.invokeExact("x", "y")); // xY
1875
MethodHandle f2 = filterArguments(cat, 0, upcase, upcase);
1876
assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
1877 1878 1879 1880 1881 1882 1883 1884
     * </pre></blockquote>
     * <p> Here is pseudocode for the resulting adapter:
     * <blockquote><pre>
     * V target(P... p, A[i]... a[i], B... b);
     * A[i] filter[i](V[i]);
     * T adapter(P... p, V[i]... v[i], B... b) {
     *   return target(p..., f[i](v[i])..., b...);
     * }
1885
     * </pre></blockquote>
1886
     *
1887
     * @param target the method handle to invoke after arguments are filtered
1888
     * @param pos the position of the first argument to filter
1889 1890
     * @param filters method handles to call initially on filtered arguments
     * @return method handle which incorporates the specified argument filtering logic
1891
     * @throws NullPointerException if the target is null
1892 1893
     *                              or if the {@code filters} array is null
     * @throws IllegalArgumentException if a non-null element of {@code filters}
1894
     *          does not match a corresponding argument type of target as described above,
1895
     *          or if the {@code pos+filters.length} is greater than {@code target.type().parameterCount()}
1896 1897
     */
    public static
1898
    MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters) {
1899 1900
        MethodType targetType = target.type();
        MethodHandle adapter = target;
1901 1902
        MethodType adapterType = null;
        assert((adapterType = targetType) != null);
1903
        int maxPos = targetType.parameterCount();
1904 1905 1906
        if (pos + filters.length > maxPos)
            throw newIllegalArgumentException("too many filters");
        int curPos = pos-1;  // pre-incremented
1907
        for (MethodHandle filter : filters) {
1908 1909
            curPos += 1;
            if (filter == null)  continue;  // ignore null elements of filters
1910 1911
            adapter = filterArgument(adapter, curPos, filter);
            assert((adapterType = adapterType.changeParameterType(curPos, filter.type().parameterType(0))) != null);
1912
        }
1913
        assert(adapterType.equals(adapter.type()));
1914 1915 1916
        return adapter;
    }

1917 1918 1919 1920 1921 1922 1923 1924 1925 1926
    /*non-public*/ static
    MethodHandle filterArgument(MethodHandle target, int pos, MethodHandle filter) {
        MethodType targetType = target.type();
        MethodType filterType = filter.type();
        if (filterType.parameterCount() != 1
            || filterType.returnType() != targetType.parameterType(pos))
            throw newIllegalArgumentException("target and filter types do not match", targetType, filterType);
        return MethodHandleImpl.filterArgument(target, pos, filter);
    }

1927
    /**
1928 1929 1930
     * Adapts a target method handle by post-processing
     * its return value (if any) with a filter (another method handle).
     * The result of the filter is returned from the adapter.
1931
     * <p>
1932 1933 1934 1935 1936
     * If the target returns a value, the filter must accept that value as
     * its only argument.
     * If the target returns void, the filter must accept no arguments.
     * <p>
     * The return type of the filter
1937 1938
     * replaces the return type of the target
     * in the resulting adapted method handle.
1939
     * The argument type of the filter (if any) must be identical to the
1940 1941 1942
     * return type of the target.
     * <b>Example:</b>
     * <p><blockquote><pre>
1943 1944
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
1945 1946 1947 1948 1949 1950 1951 1952
...
MethodHandle cat = lookup().findVirtual(String.class,
  "concat", methodType(String.class, String.class));
MethodHandle length = lookup().findVirtual(String.class,
  "length", methodType(int.class));
System.out.println((String) cat.invokeExact("x", "y")); // xy
MethodHandle f0 = filterReturnValue(cat, length);
System.out.println((int) f0.invokeExact("x", "y")); // 2
1953 1954 1955 1956 1957 1958 1959 1960 1961 1962 1963 1964 1965 1966 1967 1968 1969 1970 1971 1972 1973 1974 1975
     * </pre></blockquote>
     * <p> Here is pseudocode for the resulting adapter:
     * <blockquote><pre>
     * V target(A...);
     * T filter(V);
     * T adapter(A... a) {
     *   V v = target(a...);
     *   return filter(v);
     * }
     * // and if the target has a void return:
     * void target2(A...);
     * T filter2();
     * T adapter2(A... a) {
     *   target2(a...);
     *   return filter2();
     * }
     * // and if the filter has a void return:
     * V target3(A...);
     * void filter3(V);
     * void adapter3(A... a) {
     *   V v = target3(a...);
     *   filter3(v);
     * }
1976 1977 1978 1979
     * </pre></blockquote>
     * @param target the method handle to invoke before filtering the return value
     * @param filter method handle to call on the return value
     * @return method handle which incorporates the specified return value filtering logic
1980
     * @throws NullPointerException if either argument is null
1981 1982
     * @throws IllegalArgumentException if the argument list of {@code filter}
     *          does not match the return type of target as described above
1983
     */
1984
    public static
1985 1986 1987
    MethodHandle filterReturnValue(MethodHandle target, MethodHandle filter) {
        MethodType targetType = target.type();
        MethodType filterType = filter.type();
1988 1989 1990 1991 1992 1993
        Class<?> rtype = targetType.returnType();
        int filterValues = filterType.parameterCount();
        if (filterValues == 0
                ? (rtype != void.class)
                : (rtype != filterType.parameterType(0)))
            throw newIllegalArgumentException("target and filter types do not match", target, filter);
1994 1995
        // result = fold( lambda(retval, arg...) { filter(retval) },
        //                lambda(        arg...) { target(arg...) } )
1996 1997
        MethodType newType = targetType.changeReturnType(filterType.returnType());
        MethodHandle result = null;
1998 1999
        assert(AdapterMethodHandle.canCollectArguments(filterType, targetType, 0, false));
        return AdapterMethodHandle.makeCollectArguments(filter, target, 0, false);
2000 2001
    }

2002
    /**
2003
     * Adapts a target method handle by pre-processing
2004
     * some of its arguments, and then calling the target with
2005 2006
     * the result of the pre-processing, inserted into the original
     * sequence of arguments.
2007
     * <p>
2008 2009 2010 2011 2012 2013 2014 2015 2016 2017 2018 2019 2020 2021 2022 2023
     * The pre-processing is performed by {@code combiner}, a second method handle.
     * Of the arguments passed to the adapter, the first {@code N} arguments
     * are copied to the combiner, which is then called.
     * (Here, {@code N} is defined as the parameter count of the combiner.)
     * After this, control passes to the target, with any result
     * from the combiner inserted before the original {@code N} incoming
     * arguments.
     * <p>
     * If the combiner returns a value, the first parameter type of the target
     * must be identical with the return type of the combiner, and the next
     * {@code N} parameter types of the target must exactly match the parameters
     * of the combiner.
     * <p>
     * If the combiner has a void return, no result will be inserted,
     * and the first {@code N} parameter types of the target
     * must exactly match the parameters of the combiner.
2024 2025
     * <p>
     * The resulting adapter is the same type as the target, except that the
2026 2027
     * first parameter type is dropped,
     * if it corresponds to the result of the combiner.
2028
     * <p>
2029
     * (Note that {@link #dropArguments(MethodHandle,int,List) dropArguments} can be used to remove any arguments
2030
     * that either the combiner or the target does not wish to receive.
2031
     * If some of the incoming arguments are destined only for the combiner,
2032
     * consider using {@link MethodHandle#asCollector asCollector} instead, since those
2033 2034
     * arguments will not need to be live on the stack on entry to the
     * target.)
2035 2036 2037 2038 2039 2040 2041 2042 2043 2044 2045 2046 2047 2048 2049
     * <b>Example:</b>
     * <p><blockquote><pre>
import static java.lang.invoke.MethodHandles.*;
import static java.lang.invoke.MethodType.*;
...
MethodHandle trace = publicLookup().findVirtual(java.io.PrintStream.class,
  "println", methodType(void.class, String.class))
    .bindTo(System.out);
MethodHandle cat = lookup().findVirtual(String.class,
  "concat", methodType(String.class, String.class));
assertEquals("boojum", (String) cat.invokeExact("boo", "jum"));
MethodHandle catTrace = foldArguments(cat, trace);
// also prints "boo":
assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
     * </pre></blockquote>
2050 2051
     * <p> Here is pseudocode for the resulting adapter:
     * <blockquote><pre>
2052
     * // there are N arguments in A...
2053 2054 2055 2056 2057 2058
     * T target(V, A[N]..., B...);
     * V combiner(A...);
     * T adapter(A... a, B... b) {
     *   V v = combiner(a...);
     *   return target(v, a..., b...);
     * }
2059 2060 2061 2062 2063 2064 2065
     * // and if the combiner has a void return:
     * T target2(A[N]..., B...);
     * void combiner2(A...);
     * T adapter2(A... a, B... b) {
     *   combiner2(a...);
     *   return target2(a..., b...);
     * }
2066 2067 2068 2069
     * </pre></blockquote>
     * @param target the method handle to invoke after arguments are combined
     * @param combiner method handle to call initially on the incoming arguments
     * @return method handle which incorporates the specified argument folding logic
2070
     * @throws NullPointerException if either argument is null
2071 2072 2073 2074 2075
     * @throws IllegalArgumentException if {@code combiner}'s return type
     *          is non-void and not the same as the first argument type of
     *          the target, or if the initial {@code N} argument types
     *          of the target
     *          (skipping one matching the {@code combiner}'s return type)
2076 2077 2078 2079
     *          are not identical with the argument types of {@code combiner}
     */
    public static
    MethodHandle foldArguments(MethodHandle target, MethodHandle combiner) {
2080
        int pos = 0;
2081 2082
        MethodType targetType = target.type();
        MethodType combinerType = combiner.type();
2083
        int foldPos = pos;
2084
        int foldArgs = combinerType.parameterCount();
2085 2086 2087 2088 2089 2090
        int foldVals = combinerType.returnType() == void.class ? 0 : 1;
        int afterInsertPos = foldPos + foldVals;
        boolean ok = (targetType.parameterCount() >= afterInsertPos + foldArgs);
        if (ok && !(combinerType.parameterList()
                    .equals(targetType.parameterList().subList(afterInsertPos,
                                                               afterInsertPos + foldArgs))))
2091
            ok = false;
2092
        if (ok && foldVals != 0 && !combinerType.returnType().equals(targetType.parameterType(0)))
2093
            ok = false;
2094 2095
        if (!ok)
            throw misMatchedTypes("target and combiner types", targetType, combinerType);
2096 2097 2098 2099
        MethodType newType = targetType.dropParameterTypes(foldPos, afterInsertPos);
        MethodHandle res = MethodHandleImpl.foldArguments(target, newType, foldPos, combiner);
        if (res == null)  throw newIllegalArgumentException("cannot fold from "+newType+" to " +targetType);
        return res;
2100 2101
    }

2102
    /**
2103
     * Makes a method handle which adapts a target method handle,
2104 2105 2106 2107
     * by guarding it with a test, a boolean-valued method handle.
     * If the guard fails, a fallback handle is called instead.
     * All three method handles must have the same corresponding
     * argument and return types, except that the return type
2108 2109
     * of the test must be boolean, and the test is allowed
     * to have fewer arguments than the other two method handles.
2110 2111 2112
     * <p> Here is pseudocode for the resulting adapter:
     * <blockquote><pre>
     * boolean test(A...);
2113 2114 2115
     * T target(A...,B...);
     * T fallback(A...,B...);
     * T adapter(A... a,B... b) {
2116
     *   if (test(a...))
2117
     *     return target(a..., b...);
2118
     *   else
2119
     *     return fallback(a..., b...);
2120 2121
     * }
     * </pre></blockquote>
2122 2123 2124
     * Note that the test arguments ({@code a...} in the pseudocode) cannot
     * be modified by execution of the test, and so are passed unchanged
     * from the caller to the target or fallback as appropriate.
2125 2126 2127 2128
     * @param test method handle used for test, must return boolean
     * @param target method handle to call if test passes
     * @param fallback method handle to call if test fails
     * @return method handle which incorporates the specified if/then/else logic
2129
     * @throws NullPointerException if any argument is null
2130 2131
     * @throws IllegalArgumentException if {@code test} does not return boolean,
     *          or if all three method types do not match (with the return
2132
     *          type of {@code test} changed to match that of the target).
2133 2134 2135 2136 2137
     */
    public static
    MethodHandle guardWithTest(MethodHandle test,
                               MethodHandle target,
                               MethodHandle fallback) {
2138 2139 2140
        MethodType gtype = test.type();
        MethodType ttype = target.type();
        MethodType ftype = fallback.type();
2141
        if (!ttype.equals(ftype))
2142
            throw misMatchedTypes("target and fallback types", ttype, ftype);
2143 2144 2145 2146 2147 2148 2149
        if (gtype.returnType() != boolean.class)
            throw newIllegalArgumentException("guard type is not a predicate "+gtype);
        List<Class<?>> targs = ttype.parameterList();
        List<Class<?>> gargs = gtype.parameterList();
        if (!targs.equals(gargs)) {
            int gpc = gargs.size(), tpc = targs.size();
            if (gpc >= tpc || !targs.subList(0, gpc).equals(gargs))
2150
                throw misMatchedTypes("target and test types", ttype, gtype);
2151 2152
            test = dropArguments(test, gpc, targs.subList(gpc, tpc));
            gtype = test.type();
2153
        }
2154
        return MethodHandleImpl.makeGuardWithTest(test, target, fallback);
2155 2156
    }

2157 2158 2159 2160
    static RuntimeException misMatchedTypes(String what, MethodType t1, MethodType t2) {
        return newIllegalArgumentException(what + " must match: " + t1 + " != " + t2);
    }

2161
    /**
2162
     * Makes a method handle which adapts a target method handle,
2163 2164 2165 2166
     * by running it inside an exception handler.
     * If the target returns normally, the adapter returns that value.
     * If an exception matching the specified type is thrown, the fallback
     * handle is called instead on the exception, plus the original arguments.
2167
     * <p>
2168 2169 2170 2171
     * The target and handler must have the same corresponding
     * argument and return types, except that handler may omit trailing arguments
     * (similarly to the predicate in {@link #guardWithTest guardWithTest}).
     * Also, the handler must have an extra leading parameter of {@code exType} or a supertype.
2172 2173
     * <p> Here is pseudocode for the resulting adapter:
     * <blockquote><pre>
2174
     * T target(A..., B...);
2175
     * T handler(ExType, A...);
2176
     * T adapter(A... a, B... b) {
2177
     *   try {
2178
     *     return target(a..., b...);
2179 2180 2181
     *   } catch (ExType ex) {
     *     return handler(ex, a...);
     *   }
2182 2183
     * }
     * </pre></blockquote>
2184 2185 2186 2187 2188 2189 2190 2191 2192 2193
     * Note that the saved arguments ({@code a...} in the pseudocode) cannot
     * be modified by execution of the target, and so are passed unchanged
     * from the caller to the handler, if the handler is invoked.
     * <p>
     * The target and handler must return the same type, even if the handler
     * always throws.  (This might happen, for instance, because the handler
     * is simulating a {@code finally} clause).
     * To create such a throwing handler, compose the handler creation logic
     * with {@link #throwException throwException},
     * in order to create a method handle of the correct return type.
2194 2195 2196 2197
     * @param target method handle to call
     * @param exType the type of exception which the handler will catch
     * @param handler method handle to call if a matching exception is thrown
     * @return method handle which incorporates the specified try/catch logic
2198
     * @throws NullPointerException if any argument is null
2199 2200 2201 2202
     * @throws IllegalArgumentException if {@code handler} does not accept
     *          the given exception type, or if the method handle types do
     *          not match in their return types and their
     *          corresponding parameters
2203 2204
     */
    public static
2205 2206 2207
    MethodHandle catchException(MethodHandle target,
                                Class<? extends Throwable> exType,
                                MethodHandle handler) {
2208 2209 2210 2211 2212 2213 2214 2215 2216 2217 2218 2219 2220 2221
        MethodType ttype = target.type();
        MethodType htype = handler.type();
        if (htype.parameterCount() < 1 ||
            !htype.parameterType(0).isAssignableFrom(exType))
            throw newIllegalArgumentException("handler does not accept exception type "+exType);
        if (htype.returnType() != ttype.returnType())
            throw misMatchedTypes("target and handler return types", ttype, htype);
        List<Class<?>> targs = ttype.parameterList();
        List<Class<?>> hargs = htype.parameterList();
        hargs = hargs.subList(1, hargs.size());  // omit leading parameter from handler
        if (!targs.equals(hargs)) {
            int hpc = hargs.size(), tpc = targs.size();
            if (hpc >= tpc || !targs.subList(0, hpc).equals(hargs))
                throw misMatchedTypes("target and handler types", ttype, htype);
2222
            handler = dropArguments(handler, 1+hpc, targs.subList(hpc, tpc));
2223 2224
            htype = handler.type();
        }
2225
        return MethodHandleImpl.makeGuardWithCatch(target, exType, handler);
2226 2227
    }

2228
    /**
2229
     * Produces a method handle which will throw exceptions of the given {@code exType}.
2230 2231 2232 2233 2234
     * The method handle will accept a single argument of {@code exType},
     * and immediately throw it as an exception.
     * The method type will nominally specify a return of {@code returnType}.
     * The return type may be anything convenient:  It doesn't matter to the
     * method handle's behavior, since it will never return normally.
2235 2236
     * @return method handle which can throw the given exceptions
     * @throws NullPointerException if either argument is null
2237 2238 2239
     */
    public static
    MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType) {
2240
        return MethodHandleImpl.throwException(MethodType.methodType(returnType, exType));
2241
    }
2242
}