jdk/src/share/classes/java/lang/invoke/MethodHandles.java
changeset 8822 8145ab9f5f86
parent 8821 2836ee97ee27
child 9645 dabb5e4edc4c
equal deleted inserted replaced
8821:2836ee97ee27 8822:8145ab9f5f86
       
     1 /*
       
     2  * Copyright (c) 2008, 2011, Oracle and/or its affiliates. All rights reserved.
       
     3  * DO NOT ALTER OR REMOVE COPYRIGHT NOTICES OR THIS FILE HEADER.
       
     4  *
       
     5  * This code is free software; you can redistribute it and/or modify it
       
     6  * 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  * This code is distributed in the hope that it will be useful, but WITHOUT
       
    12  * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
       
    13  * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
       
    14  * version 2 for more details (a copy is included in the LICENSE file that
       
    15  * accompanied this code).
       
    16  *
       
    17  * You should have received a copy of the GNU General Public License version
       
    18  * 2 along with this work; if not, write to the Free Software Foundation,
       
    19  * Inc., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301 USA.
       
    20  *
       
    21  * Please contact Oracle, 500 Oracle Parkway, Redwood Shores, CA 94065 USA
       
    22  * or visit www.oracle.com if you need additional information or have any
       
    23  * questions.
       
    24  */
       
    25 
       
    26 package java.lang.invoke;
       
    27 
       
    28 import java.lang.reflect.*;
       
    29 import sun.invoke.WrapperInstance;
       
    30 import sun.invoke.util.ValueConversions;
       
    31 import sun.invoke.util.VerifyAccess;
       
    32 import sun.invoke.util.Wrapper;
       
    33 import java.util.List;
       
    34 import java.util.ArrayList;
       
    35 import java.util.Arrays;
       
    36 import sun.reflect.Reflection;
       
    37 import static java.lang.invoke.MethodHandleStatics.*;
       
    38 
       
    39 /**
       
    40  * This class consists exclusively of static methods that operate on or return
       
    41  * method handles. They fall into several categories:
       
    42  * <ul>
       
    43  * <li>Lookup methods which help create method handles for methods and fields.
       
    44  * <li>Combinator methods, which combine or transform pre-existing method handles into new ones.
       
    45  * <li>Other factory methods to create method handles that emulate other common JVM operations or control flow patterns.
       
    46  * <li>Wrapper methods which can convert between method handles and interface types.
       
    47  * </ul>
       
    48  * <p>
       
    49  * @author John Rose, JSR 292 EG
       
    50  */
       
    51 public class MethodHandles {
       
    52 
       
    53     private MethodHandles() { }  // do not instantiate
       
    54 
       
    55     private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
       
    56     static { MethodHandleImpl.initStatics(); }
       
    57     // See IMPL_LOOKUP below.
       
    58 
       
    59     //// Method handle creation from ordinary methods.
       
    60 
       
    61     /**
       
    62      * Returns a {@link Lookup lookup object} on the caller,
       
    63      * which has the capability to access any method handle that the caller has access to,
       
    64      * including direct method handles to private fields and methods.
       
    65      * This lookup object is a <em>capability</em> which may be delegated to trusted agents.
       
    66      * Do not store it in place where untrusted code can access it.
       
    67      */
       
    68     public static Lookup lookup() {
       
    69         return new Lookup();
       
    70     }
       
    71 
       
    72     /**
       
    73      * Returns a {@link Lookup lookup object} which is trusted minimally.
       
    74      * It can only be used to create method handles to
       
    75      * publicly accessible fields and methods.
       
    76      * <p>
       
    77      * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
       
    78      * of this lookup object will be {@link java.lang.Object}.
       
    79      * <p>
       
    80      * The lookup class can be changed to any other class {@code C} using an expression of the form
       
    81      * {@linkplain Lookup#in <code>publicLookup().in(C.class)</code>}.
       
    82      * Since all classes have equal access to public names,
       
    83      * such a change would confer no new access rights.
       
    84      */
       
    85     public static Lookup publicLookup() {
       
    86         return Lookup.PUBLIC_LOOKUP;
       
    87     }
       
    88 
       
    89     /**
       
    90      * A <em>lookup object</em> is a factory for creating method handles,
       
    91      * when the creation requires access checking.
       
    92      * Method handles do not perform
       
    93      * access checks when they are called, but rather when they are created.
       
    94      * Therefore, method handle access
       
    95      * restrictions must be enforced when a method handle is created.
       
    96      * The caller class against which those restrictions are enforced
       
    97      * is known as the {@linkplain #lookupClass lookup class}.
       
    98      * <p>
       
    99      * A lookup class which needs to create method handles will call
       
   100      * {@link MethodHandles#lookup MethodHandles.lookup} to create a factory for itself.
       
   101      * When the {@code Lookup} factory object is created, the identity of the lookup class is
       
   102      * determined, and securely stored in the {@code Lookup} object.
       
   103      * The lookup class (or its delegates) may then use factory methods
       
   104      * on the {@code Lookup} object to create method handles for access-checked members.
       
   105      * This includes all methods, constructors, and fields which are allowed to the lookup class,
       
   106      * even private ones.
       
   107      * <p>
       
   108      * The factory methods on a {@code Lookup} object correspond to all major
       
   109      * use cases for methods, constructors, and fields.
       
   110      * Here is a summary of the correspondence between these factory methods and
       
   111      * the behavior the resulting method handles:
       
   112      * <code>
       
   113      * <table border=1 cellpadding=5 summary="lookup method behaviors">
       
   114      * <tr><th>lookup expression</th><th>member</th><th>behavior</th></tr>
       
   115      * <tr>
       
   116      *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}</td>
       
   117      *     <td>FT f;</td><td>(T) this.f;</td>
       
   118      * </tr>
       
   119      * <tr>
       
   120      *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findStaticGetter lookup.findStaticGetter(C.class,"f",FT.class)}</td>
       
   121      *     <td>static<br>FT f;</td><td>(T) C.f;</td>
       
   122      * </tr>
       
   123      * <tr>
       
   124      *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findSetter lookup.findSetter(C.class,"f",FT.class)}</td>
       
   125      *     <td>FT f;</td><td>this.f = x;</td>
       
   126      * </tr>
       
   127      * <tr>
       
   128      *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findStaticSetter lookup.findStaticSetter(C.class,"f",FT.class)}</td>
       
   129      *     <td>static<br>FT f;</td><td>C.f = arg;</td>
       
   130      * </tr>
       
   131      * <tr>
       
   132      *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findVirtual lookup.findVirtual(C.class,"m",MT)}</td>
       
   133      *     <td>T m(A*);</td><td>(T) this.m(arg*);</td>
       
   134      * </tr>
       
   135      * <tr>
       
   136      *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findStatic lookup.findStatic(C.class,"m",MT)}</td>
       
   137      *     <td>static<br>T m(A*);</td><td>(T) C.m(arg*);</td>
       
   138      * </tr>
       
   139      * <tr>
       
   140      *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findSpecial lookup.findSpecial(C.class,"m",MT,this.class)}</td>
       
   141      *     <td>T m(A*);</td><td>(T) super.m(arg*);</td>
       
   142      * </tr>
       
   143      * <tr>
       
   144      *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#findConstructor lookup.findConstructor(C.class,MT)}</td>
       
   145      *     <td>C(A*);</td><td>(T) new C(arg*);</td>
       
   146      * </tr>
       
   147      * <tr>
       
   148      *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflectGetter lookup.unreflectGetter(aField)}</td>
       
   149      *     <td>(static)?<br>FT f;</td><td>(FT) aField.get(thisOrNull);</td>
       
   150      * </tr>
       
   151      * <tr>
       
   152      *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflectSetter lookup.unreflectSetter(aField)}</td>
       
   153      *     <td>(static)?<br>FT f;</td><td>aField.set(thisOrNull, arg);</td>
       
   154      * </tr>
       
   155      * <tr>
       
   156      *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
       
   157      *     <td>(static)?<br>T m(A*);</td><td>(T) aMethod.invoke(thisOrNull, arg*);</td>
       
   158      * </tr>
       
   159      * <tr>
       
   160      *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflectConstructor lookup.unreflectConstructor(aConstructor)}</td>
       
   161      *     <td>C(A*);</td><td>(C) aConstructor.newInstance(arg*);</td>
       
   162      * </tr>
       
   163      * <tr>
       
   164      *     <td>{@linkplain java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
       
   165      *     <td>(static)?<br>T m(A*);</td><td>(T) aMethod.invoke(thisOrNull, arg*);</td>
       
   166      * </tr>
       
   167      * </table>
       
   168      * </code>
       
   169      * Here, the type {@code C} is the class or interface being searched for a member,
       
   170      * documented as a parameter named {@code refc} in the lookup methods.
       
   171      * The method or constructor type {@code MT} is composed from the return type {@code T}
       
   172      * and the sequence of argument types {@code A*}.
       
   173      * Both {@code MT} and the field type {@code FT} are documented as a parameter named {@code type}.
       
   174      * The formal parameter {@code this} stands for the self-reference of type {@code C};
       
   175      * if it is present, it is always the leading argument to the method handle invocation.
       
   176      * The name {@code arg} stands for all the other method handle arguments.
       
   177      * In the code examples for the Core Reflection API, the name {@code thisOrNull}
       
   178      * stands for a null reference if the accessed method or field is static,
       
   179      * and {@code this} otherwise.
       
   180      * The names {@code aMethod}, {@code aField}, and {@code aConstructor} stand
       
   181      * for reflective objects corresponding to the given members.
       
   182      * <p>
       
   183      * The equivalence between looked-up method handles and underlying
       
   184      * class members can break down in a few ways:
       
   185      * <ul>
       
   186      * <li>If {@code C} is not symbolically accessible from the lookup class's loader,
       
   187      * the lookup can still succeed, even when there is no equivalent
       
   188      * Java expression or bytecoded constant.
       
   189      * <li>Likewise, if {@code T} or {@code MT}
       
   190      * is not symbolically accessible from the lookup class's loader,
       
   191      * the lookup can still succeed.
       
   192      * For example, lookups for {@code MethodHandle.invokeExact} and
       
   193      * {@code MethodHandle.invokeGeneric} will always succeed, regardless of requested type.
       
   194      * <li>If there is a security manager installed, it can forbid the lookup
       
   195      * on various grounds (<a href="#secmgr">see below</a>).
       
   196      * By contrast, the {@code ldc} instruction is not subject to
       
   197      * security manager checks.
       
   198      * </ul>
       
   199      *
       
   200      * <h3><a name="access"></a>Access checking</h3>
       
   201      * Access checks are applied in the factory methods of {@code Lookup},
       
   202      * when a method handle is created.
       
   203      * This is a key difference from the Core Reflection API, since
       
   204      * {@link java.lang.reflect.Method#invoke Method.invoke}
       
   205      * performs access checking against every caller, on every call.
       
   206      * <p>
       
   207      * All access checks start from a {@code Lookup} object, which
       
   208      * compares its recorded lookup class against all requests to
       
   209      * create method handles.
       
   210      * A single {@code Lookup} object can be used to create any number
       
   211      * of access-checked method handles, all checked against a single
       
   212      * lookup class.
       
   213      * <p>
       
   214      * A {@code Lookup} object can be shared with other trusted code,
       
   215      * such as a metaobject protocol.
       
   216      * A shared {@code Lookup} object delegates the capability
       
   217      * to create method handles on private members of the lookup class.
       
   218      * Even if privileged code uses the {@code Lookup} object,
       
   219      * the access checking is confined to the privileges of the
       
   220      * original lookup class.
       
   221      * <p>
       
   222      * A lookup can fail, because
       
   223      * the containing class is not accessible to the lookup class, or
       
   224      * because the desired class member is missing, or because the
       
   225      * desired class member is not accessible to the lookup class.
       
   226      * In any of these cases, a {@code ReflectiveOperationException} will be
       
   227      * thrown from the attempted lookup.  The exact class will be one of
       
   228      * the following:
       
   229      * <ul>
       
   230      * <li>NoSuchMethodException &mdash; if a method is requested but does not exist
       
   231      * <li>NoSuchFieldException &mdash; if a field is requested but does not exist
       
   232      * <li>IllegalAccessException &mdash; if the member exists but an access check fails
       
   233      * </ul>
       
   234      * <p>
       
   235      * In general, the conditions under which a method handle may be
       
   236      * looked up for a method {@code M} are exactly equivalent to the conditions
       
   237      * under which the lookup class could have compiled and resolved a call to {@code M}.
       
   238      * And the effect of invoking the method handle resulting from the lookup
       
   239      * is exactly equivalent to executing the compiled and resolved call to {@code M}.
       
   240      * The same point is true of fields and constructors.
       
   241      * <p>
       
   242      * In some cases, access between nested classes is obtained by the Java compiler by creating
       
   243      * an wrapper method to access a private method of another class
       
   244      * in the same top-level declaration.
       
   245      * For example, a nested class {@code C.D}
       
   246      * can access private members within other related classes such as
       
   247      * {@code C}, {@code C.D.E}, or {@code C.B},
       
   248      * but the Java compiler may need to generate wrapper methods in
       
   249      * those related classes.  In such cases, a {@code Lookup} object on
       
   250      * {@code C.E} would be unable to those private members.
       
   251      * A workaround for this limitation is the {@link Lookup#in Lookup.in} method,
       
   252      * which can transform a lookup on {@code C.E} into one on any of those other
       
   253      * classes, without special elevation of privilege.
       
   254      * <p>
       
   255      * Although bytecode instructions can only refer to classes in
       
   256      * a related class loader, this API can search for methods in any
       
   257      * class, as long as a reference to its {@code Class} object is
       
   258      * available.  Such cross-loader references are also possible with the
       
   259      * Core Reflection API, and are impossible to bytecode instructions
       
   260      * such as {@code invokestatic} or {@code getfield}.
       
   261      * There is a {@linkplain java.lang.SecurityManager security manager API}
       
   262      * to allow applications to check such cross-loader references.
       
   263      * These checks apply to both the {@code MethodHandles.Lookup} API
       
   264      * and the Core Reflection API
       
   265      * (as found on {@link java.lang.Class Class}).
       
   266      * <p>
       
   267      * Access checks only apply to named and reflected methods,
       
   268      * constructors, and fields.
       
   269      * Other method handle creation methods, such as
       
   270      * {@link #convertArguments MethodHandles.convertArguments},
       
   271      * do not require any access checks, and are done
       
   272      * with static methods of {@link MethodHandles},
       
   273      * independently of any {@code Lookup} object.
       
   274      *
       
   275      * <h3>Security manager interactions</h3>
       
   276      * <a name="secmgr"></a>
       
   277      * If a security manager is present, member lookups are subject to
       
   278      * additional checks.
       
   279      * From one to four calls are made to the security manager.
       
   280      * Any of these calls can refuse access by throwing a
       
   281      * {@link java.lang.SecurityException SecurityException}.
       
   282      * Define {@code smgr} as the security manager,
       
   283      * {@code refc} as the containing class in which the member
       
   284      * is being sought, and {@code defc} as the class in which the
       
   285      * member is actually defined.
       
   286      * The calls are made according to the following rules:
       
   287      * <ul>
       
   288      * <li>In all cases, {@link SecurityManager#checkMemberAccess
       
   289      *     smgr.checkMemberAccess(refc, Member.PUBLIC)} is called.
       
   290      * <li>If the class loader of the lookup class is not
       
   291      *     the same as or an ancestor of the class loader of {@code refc},
       
   292      *     then {@link SecurityManager#checkPackageAccess
       
   293      *     smgr.checkPackageAccess(refcPkg)} is called,
       
   294      *     where {@code refcPkg} is the package of {@code refc}.
       
   295      * <li>If the retrieved member is not public,
       
   296      *     {@link SecurityManager#checkMemberAccess
       
   297      *     smgr.checkMemberAccess(defc, Member.DECLARED)} is called.
       
   298      *     (Note that {@code defc} might be the same as {@code refc}.)
       
   299      * <li>If the retrieved member is not public,
       
   300      *     and if {@code defc} and {@code refc} are in different class loaders,
       
   301      *     and if the class loader of the lookup class is not
       
   302      *     the same as or an ancestor of the class loader of {@code defc},
       
   303      *     then {@link SecurityManager#checkPackageAccess
       
   304      *     smgr.checkPackageAccess(defcPkg)} is called,
       
   305      *     where {@code defcPkg} is the package of {@code defc}.
       
   306      * </ul>
       
   307      * In all cases, the requesting class presented to the security
       
   308      * manager will be the lookup class from the current {@code Lookup} object.
       
   309      */
       
   310     public static final
       
   311     class Lookup {
       
   312         /** The class on behalf of whom the lookup is being performed. */
       
   313         private final Class<?> lookupClass;
       
   314 
       
   315         /** The allowed sorts of members which may be looked up (PUBLIC, etc.). */
       
   316         private final int allowedModes;
       
   317 
       
   318         /** A single-bit mask representing {@code public} access,
       
   319          *  which may contribute to the result of {@link #lookupModes lookupModes}.
       
   320          *  The value, {@code 0x01}, happens to be the same as the value of the
       
   321          *  {@code public} {@linkplain java.lang.reflect.Modifier#PUBLIC modifier bit}.
       
   322          */
       
   323         public static final int PUBLIC = Modifier.PUBLIC;
       
   324 
       
   325         /** A single-bit mask representing {@code private} access,
       
   326          *  which may contribute to the result of {@link #lookupModes lookupModes}.
       
   327          *  The value, {@code 0x02}, happens to be the same as the value of the
       
   328          *  {@code private} {@linkplain java.lang.reflect.Modifier#PRIVATE modifier bit}.
       
   329          */
       
   330         public static final int PRIVATE = Modifier.PRIVATE;
       
   331 
       
   332         /** A single-bit mask representing {@code protected} access,
       
   333          *  which may contribute to the result of {@link #lookupModes lookupModes}.
       
   334          *  The value, {@code 0x04}, happens to be the same as the value of the
       
   335          *  {@code protected} {@linkplain java.lang.reflect.Modifier#PROTECTED modifier bit}.
       
   336          */
       
   337         public static final int PROTECTED = Modifier.PROTECTED;
       
   338 
       
   339         /** A single-bit mask representing {@code package} access (default access),
       
   340          *  which may contribute to the result of {@link #lookupModes lookupModes}.
       
   341          *  The value is {@code 0x08}, which does not correspond meaningfully to
       
   342          *  any particular {@linkplain java.lang.reflect.Modifier modifier bit}.
       
   343          */
       
   344         public static final int PACKAGE = Modifier.STATIC;
       
   345 
       
   346         private static final int ALL_MODES = (PUBLIC | PRIVATE | PROTECTED | PACKAGE);
       
   347         private static final int TRUSTED   = -1;
       
   348 
       
   349         private static int fixmods(int mods) {
       
   350             mods &= (ALL_MODES - PACKAGE);
       
   351             return (mods != 0) ? mods : PACKAGE;
       
   352         }
       
   353 
       
   354         /** Tells which class is performing the lookup.  It is this class against
       
   355          *  which checks are performed for visibility and access permissions.
       
   356          *  <p>
       
   357          *  The class implies a maximum level of access permission,
       
   358          *  but the permissions may be additionally limited by the bitmask
       
   359          *  {@link #lookupModes lookupModes}, which controls whether non-public members
       
   360          *  can be accessed.
       
   361          */
       
   362         public Class<?> lookupClass() {
       
   363             return lookupClass;
       
   364         }
       
   365 
       
   366         // This is just for calling out to MethodHandleImpl.
       
   367         private Class<?> lookupClassOrNull() {
       
   368             return (allowedModes == TRUSTED) ? null : lookupClass;
       
   369         }
       
   370 
       
   371         /** Tells which access-protection classes of members this lookup object can produce.
       
   372          *  The result is a bit-mask of the bits
       
   373          *  {@linkplain #PUBLIC PUBLIC (0x01)},
       
   374          *  {@linkplain #PRIVATE PRIVATE (0x02)},
       
   375          *  {@linkplain #PROTECTED PROTECTED (0x04)},
       
   376          *  and {@linkplain #PACKAGE PACKAGE (0x08)}.
       
   377          *  <p>
       
   378          *  A freshly-created lookup object
       
   379          *  on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class}
       
   380          *  has all possible bits set, since the caller class can access all its own members.
       
   381          *  A lookup object on a new lookup class
       
   382          *  {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object}
       
   383          *  may have some mode bits set to zero.
       
   384          *  The purpose of this is to restrict access via the new lookup object,
       
   385          *  so that it can access only names which can be reached by the original
       
   386          *  lookup object, and also by the new lookup class.
       
   387          */
       
   388         public int lookupModes() {
       
   389             return allowedModes & ALL_MODES;
       
   390         }
       
   391 
       
   392         /** Embody the current class (the lookupClass) as a lookup class
       
   393          * for method handle creation.
       
   394          * Must be called by from a method in this package,
       
   395          * which in turn is called by a method not in this package.
       
   396          * <p>
       
   397          * Also, don't make it private, lest javac interpose
       
   398          * an access$N method.
       
   399          */
       
   400         Lookup() {
       
   401             this(getCallerClassAtEntryPoint(), ALL_MODES);
       
   402             // make sure we haven't accidentally picked up a privileged class:
       
   403             checkUnprivilegedlookupClass(lookupClass);
       
   404         }
       
   405 
       
   406         Lookup(Class<?> lookupClass) {
       
   407             this(lookupClass, ALL_MODES);
       
   408         }
       
   409 
       
   410         private Lookup(Class<?> lookupClass, int allowedModes) {
       
   411             this.lookupClass = lookupClass;
       
   412             this.allowedModes = allowedModes;
       
   413         }
       
   414 
       
   415         /**
       
   416          * Creates a lookup on the specified new lookup class.
       
   417          * The resulting object will report the specified
       
   418          * class as its own {@link #lookupClass lookupClass}.
       
   419          * <p>
       
   420          * However, the resulting {@code Lookup} object is guaranteed
       
   421          * to have no more access capabilities than the original.
       
   422          * In particular, access capabilities can be lost as follows:<ul>
       
   423          * <li>If the new lookup class differs from the old one,
       
   424          * protected members will not be accessible by virtue of inheritance.
       
   425          * (Protected members may continue to be accessible because of package sharing.)
       
   426          * <li>If the new lookup class is in a different package
       
   427          * than the old one, protected and default (package) members will not be accessible.
       
   428          * <li>If the new lookup class is not within the same package member
       
   429          * as the old one, private members will not be accessible.
       
   430          * <li>If the new lookup class is not accessible to the old lookup class,
       
   431          * then no members, not even public members, will be accessible.
       
   432          * (In all other cases, public members will continue to be accessible.)
       
   433          * </ul>
       
   434          *
       
   435          * @param requestedLookupClass the desired lookup class for the new lookup object
       
   436          * @return a lookup object which reports the desired lookup class
       
   437          * @throws NullPointerException if the argument is null
       
   438          */
       
   439         public Lookup in(Class<?> requestedLookupClass) {
       
   440             requestedLookupClass.getClass();  // null check
       
   441             if (allowedModes == TRUSTED)  // IMPL_LOOKUP can make any lookup at all
       
   442                 return new Lookup(requestedLookupClass, ALL_MODES);
       
   443             if (requestedLookupClass == this.lookupClass)
       
   444                 return this;  // keep same capabilities
       
   445             int newModes = (allowedModes & (ALL_MODES & ~PROTECTED));
       
   446             if ((newModes & PACKAGE) != 0
       
   447                 && !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
       
   448                 newModes &= ~(PACKAGE|PRIVATE);
       
   449             }
       
   450             // Allow nestmate lookups to be created without special privilege:
       
   451             if ((newModes & PRIVATE) != 0
       
   452                 && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
       
   453                 newModes &= ~PRIVATE;
       
   454             }
       
   455             if (newModes == PUBLIC
       
   456                 && !VerifyAccess.isClassAccessible(requestedLookupClass, this.lookupClass)) {
       
   457                 // The requested class it not accessible from the lookup class.
       
   458                 // No permissions.
       
   459                 newModes = 0;
       
   460             }
       
   461             checkUnprivilegedlookupClass(requestedLookupClass);
       
   462             return new Lookup(requestedLookupClass, newModes);
       
   463         }
       
   464 
       
   465         // Make sure outer class is initialized first.
       
   466         static { IMPL_NAMES.getClass(); }
       
   467 
       
   468         /** Version of lookup which is trusted minimally.
       
   469          *  It can only be used to create method handles to
       
   470          *  publicly accessible members.
       
   471          */
       
   472         static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, PUBLIC);
       
   473 
       
   474         /** Package-private version of lookup which is trusted. */
       
   475         static final Lookup IMPL_LOOKUP = new Lookup(Object.class, TRUSTED);
       
   476 
       
   477         private static void checkUnprivilegedlookupClass(Class<?> lookupClass) {
       
   478             String name = lookupClass.getName();
       
   479             if (name.startsWith("java.lang.invoke."))
       
   480                 throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
       
   481         }
       
   482 
       
   483         /**
       
   484          * Displays the name of the class from which lookups are to be made.
       
   485          * (The name is the one reported by {@link java.lang.Class#getName() Class.getName}.)
       
   486          * If there are restrictions on the access permitted to this lookup,
       
   487          * this is indicated by adding a suffix to the class name, consisting
       
   488          * of a slash and a keyword.  The keyword represents the strongest
       
   489          * allowed access, and is chosen as follows:
       
   490          * <ul>
       
   491          * <li>If no access is allowed, the suffix is "/noaccess".
       
   492          * <li>If only public access is allowed, the suffix is "/public".
       
   493          * <li>If only public and package access are allowed, the suffix is "/package".
       
   494          * <li>If only public, package, and private access are allowed, the suffix is "/private".
       
   495          * </ul>
       
   496          * If none of the above cases apply, it is the case that full
       
   497          * access (public, package, private, and protected) is allowed.
       
   498          * In this case, no suffix is added.
       
   499          * This is true only of an object obtained originally from
       
   500          * {@link java.lang.invoke.MethodHandles#lookup MethodHandles.lookup}.
       
   501          * Objects created by {@link java.lang.invoke.MethodHandles.Lookup#in Lookup.in}
       
   502          * always have restricted access, and will display a suffix.
       
   503          * <p>
       
   504          * (It may seem strange that protected access should be
       
   505          * stronger than private access.  Viewed independently from
       
   506          * package access, protected access is the first to be lost,
       
   507          * because it requires a direct subclass relationship between
       
   508          * caller and callee.)
       
   509          * @see #in
       
   510          */
       
   511         @Override
       
   512         public String toString() {
       
   513             String cname = lookupClass.getName();
       
   514             switch (allowedModes) {
       
   515             case 0:  // no privileges
       
   516                 return cname + "/noaccess";
       
   517             case PUBLIC:
       
   518                 return cname + "/public";
       
   519             case PUBLIC|PACKAGE:
       
   520                 return cname + "/package";
       
   521             case ALL_MODES & ~PROTECTED:
       
   522                 return cname + "/private";
       
   523             case ALL_MODES:
       
   524                 return cname;
       
   525             case TRUSTED:
       
   526                 return "/trusted";  // internal only; not exported
       
   527             default:  // Should not happen, but it's a bitfield...
       
   528                 cname = cname + "/" + Integer.toHexString(allowedModes);
       
   529                 assert(false) : cname;
       
   530                 return cname;
       
   531             }
       
   532         }
       
   533 
       
   534         // call this from an entry point method in Lookup with extraFrames=0.
       
   535         private static Class<?> getCallerClassAtEntryPoint() {
       
   536             final int CALLER_DEPTH = 4;
       
   537             // 0: Reflection.getCC, 1: getCallerClassAtEntryPoint,
       
   538             // 2: Lookup.<init>, 3: MethodHandles.*, 4: caller
       
   539             // Note:  This should be the only use of getCallerClass in this file.
       
   540             assert(Reflection.getCallerClass(CALLER_DEPTH-1) == MethodHandles.class);
       
   541             return Reflection.getCallerClass(CALLER_DEPTH);
       
   542         }
       
   543 
       
   544         /**
       
   545          * Produces a method handle for a static method.
       
   546          * The type of the method handle will be that of the method.
       
   547          * (Since static methods do not take receivers, there is no
       
   548          * additional receiver argument inserted into the method handle type,
       
   549          * as there would be with {@link #findVirtual findVirtual} or {@link #findSpecial findSpecial}.)
       
   550          * The method and all its argument types must be accessible to the lookup class.
       
   551          * If the method's class has not yet been initialized, that is done
       
   552          * immediately, before the method handle is returned.
       
   553          * <p>
       
   554          * The returned method handle will have
       
   555          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
       
   556          * the method's variable arity modifier bit ({@code 0x0080}) is set.
       
   557          * @param refc the class from which the method is accessed
       
   558          * @param name the name of the method
       
   559          * @param type the type of the method
       
   560          * @return the desired method handle
       
   561          * @throws NoSuchMethodException if the method does not exist
       
   562          * @throws IllegalAccessException if access checking fails, or if the method is not {@code static}
       
   563          * @exception SecurityException if a security manager is present and it
       
   564          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
       
   565          * @throws NullPointerException if any argument is null
       
   566          */
       
   567         public
       
   568         MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
       
   569             MemberName method = resolveOrFail(refc, name, type, true);
       
   570             checkMethod(refc, method, true);
       
   571             return MethodHandleImpl.findMethod(method, false, lookupClassOrNull());
       
   572         }
       
   573 
       
   574         /**
       
   575          * Produces a method handle for a virtual method.
       
   576          * The type of the method handle will be that of the method,
       
   577          * with the receiver type (usually {@code refc}) prepended.
       
   578          * The method and all its argument types must be accessible to the lookup class.
       
   579          * <p>
       
   580          * When called, the handle will treat the first argument as a receiver
       
   581          * and dispatch on the receiver's type to determine which method
       
   582          * implementation to enter.
       
   583          * (The dispatching action is identical with that performed by an
       
   584          * {@code invokevirtual} or {@code invokeinterface} instruction.)
       
   585          * <p>
       
   586          * The returned method handle will have
       
   587          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
       
   588          * the method's variable arity modifier bit ({@code 0x0080}) is set.
       
   589          * <p>
       
   590          * Because of the general equivalence between {@code invokevirtual}
       
   591          * instructions and method handles produced by {@code findVirtual},
       
   592          * if the class is {@code MethodHandle} and the name string is
       
   593          * {@code invokeExact} or {@code invokeGeneric}, the resulting
       
   594          * method handle is equivalent to one produced by
       
   595          * {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker} or
       
   596          * {@link java.lang.invoke.MethodHandles#genericInvoker MethodHandles.genericInvoker}
       
   597          * with the same {@code type} argument.
       
   598          *
       
   599          * @param refc the class or interface from which the method is accessed
       
   600          * @param name the name of the method
       
   601          * @param type the type of the method, with the receiver argument omitted
       
   602          * @return the desired method handle
       
   603          * @throws NoSuchMethodException if the method does not exist
       
   604          * @throws IllegalAccessException if access checking fails, or if the method is {@code static}
       
   605          * @exception SecurityException if a security manager is present and it
       
   606          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
       
   607          * @throws NullPointerException if any argument is null
       
   608          */
       
   609         public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
       
   610             MemberName method = resolveOrFail(refc, name, type, false);
       
   611             checkMethod(refc, method, false);
       
   612             MethodHandle mh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
       
   613             return restrictProtectedReceiver(method, mh);
       
   614         }
       
   615 
       
   616         /**
       
   617          * Produces a method handle which creates an object and initializes it, using
       
   618          * the constructor of the specified type.
       
   619          * The parameter types of the method handle will be those of the constructor,
       
   620          * while the return type will be a reference to the constructor's class.
       
   621          * The constructor and all its argument types must be accessible to the lookup class.
       
   622          * If the constructor's class has not yet been initialized, that is done
       
   623          * immediately, before the method handle is returned.
       
   624          * <p>
       
   625          * Note:  The requested type must have a return type of {@code void}.
       
   626          * This is consistent with the JVM's treatment of constructor type descriptors.
       
   627          * <p>
       
   628          * The returned method handle will have
       
   629          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
       
   630          * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
       
   631          * @param refc the class or interface from which the method is accessed
       
   632          * @param type the type of the method, with the receiver argument omitted, and a void return type
       
   633          * @return the desired method handle
       
   634          * @throws NoSuchMethodException if the constructor does not exist
       
   635          * @throws IllegalAccessException if access checking fails
       
   636          * @exception SecurityException if a security manager is present and it
       
   637          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
       
   638          * @throws NullPointerException if any argument is null
       
   639          */
       
   640         public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
       
   641             String name = "<init>";
       
   642             MemberName ctor = resolveOrFail(refc, name, type, false, false, lookupClassOrNull());
       
   643             assert(ctor.isConstructor());
       
   644             checkAccess(refc, ctor);
       
   645             MethodHandle rawMH = MethodHandleImpl.findMethod(ctor, false, lookupClassOrNull());
       
   646             MethodHandle allocMH = MethodHandleImpl.makeAllocator(rawMH);
       
   647             return fixVarargs(allocMH, rawMH);
       
   648         }
       
   649 
       
   650         /** Return a version of MH which matches matchMH w.r.t. isVarargsCollector. */
       
   651         private static MethodHandle fixVarargs(MethodHandle mh, MethodHandle matchMH) {
       
   652             boolean va1 = mh.isVarargsCollector();
       
   653             boolean va2 = matchMH.isVarargsCollector();
       
   654             if (va1 == va2) {
       
   655                 return mh;
       
   656             } else if (va2) {
       
   657                 MethodType type = mh.type();
       
   658                 int arity = type.parameterCount();
       
   659                 return mh.asVarargsCollector(type.parameterType(arity-1));
       
   660             } else {
       
   661                 throw new InternalError("already varargs, but template is not: "+mh);
       
   662             }
       
   663         }
       
   664 
       
   665         /**
       
   666          * Produces an early-bound method handle for a virtual method,
       
   667          * as if called from an {@code invokespecial}
       
   668          * instruction from {@code caller}.
       
   669          * The type of the method handle will be that of the method,
       
   670          * with a suitably restricted receiver type (such as {@code caller}) prepended.
       
   671          * The method and all its argument types must be accessible
       
   672          * to the caller.
       
   673          * <p>
       
   674          * When called, the handle will treat the first argument as a receiver,
       
   675          * but will not dispatch on the receiver's type.
       
   676          * (This direct invocation action is identical with that performed by an
       
   677          * {@code invokespecial} instruction.)
       
   678          * <p>
       
   679          * If the explicitly specified caller class is not identical with the
       
   680          * lookup class, or if this lookup object does not have private access
       
   681          * privileges, the access fails.
       
   682          * <p>
       
   683          * The returned method handle will have
       
   684          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
       
   685          * the method's variable arity modifier bit ({@code 0x0080}) is set.
       
   686          * @param refc the class or interface from which the method is accessed
       
   687          * @param name the name of the method (which must not be "&lt;init&gt;")
       
   688          * @param type the type of the method, with the receiver argument omitted
       
   689          * @param specialCaller the proposed calling class to perform the {@code invokespecial}
       
   690          * @return the desired method handle
       
   691          * @throws NoSuchMethodException if the method does not exist
       
   692          * @throws IllegalAccessException if access checking fails
       
   693          * @exception SecurityException if a security manager is present and it
       
   694          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
       
   695          * @throws NullPointerException if any argument is null
       
   696          */
       
   697         public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
       
   698                                         Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
       
   699             checkSpecialCaller(specialCaller);
       
   700             MemberName method = resolveOrFail(refc, name, type, false, false, specialCaller);
       
   701             checkMethod(refc, method, false);
       
   702             MethodHandle mh = MethodHandleImpl.findMethod(method, false, specialCaller);
       
   703             return restrictReceiver(method, mh, specialCaller);
       
   704         }
       
   705 
       
   706         /**
       
   707          * Produces a method handle giving read access to a non-static field.
       
   708          * The type of the method handle will have a return type of the field's
       
   709          * value type.
       
   710          * The method handle's single argument will be the instance containing
       
   711          * the field.
       
   712          * Access checking is performed immediately on behalf of the lookup class.
       
   713          * @param refc the class or interface from which the method is accessed
       
   714          * @param name the field's name
       
   715          * @param type the field's type
       
   716          * @return a method handle which can load values from the field
       
   717          * @throws NoSuchFieldException if the field does not exist
       
   718          * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
       
   719          * @exception SecurityException if a security manager is present and it
       
   720          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
       
   721          * @throws NullPointerException if any argument is null
       
   722          */
       
   723         public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
       
   724             return makeAccessor(refc, name, type, false, false);
       
   725         }
       
   726 
       
   727         /**
       
   728          * Produces a method handle giving write access to a non-static field.
       
   729          * The type of the method handle will have a void return type.
       
   730          * The method handle will take two arguments, the instance containing
       
   731          * the field, and the value to be stored.
       
   732          * The second argument will be of the field's value type.
       
   733          * Access checking is performed immediately on behalf of the lookup class.
       
   734          * @param refc the class or interface from which the method is accessed
       
   735          * @param name the field's name
       
   736          * @param type the field's type
       
   737          * @return a method handle which can store values into the field
       
   738          * @throws NoSuchFieldException if the field does not exist
       
   739          * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
       
   740          * @exception SecurityException if a security manager is present and it
       
   741          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
       
   742          * @throws NullPointerException if any argument is null
       
   743          */
       
   744         public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
       
   745             return makeAccessor(refc, name, type, false, true);
       
   746         }
       
   747 
       
   748         /**
       
   749          * Produces a method handle giving read access to a static field.
       
   750          * The type of the method handle will have a return type of the field's
       
   751          * value type.
       
   752          * The method handle will take no arguments.
       
   753          * Access checking is performed immediately on behalf of the lookup class.
       
   754          * @param refc the class or interface from which the method is accessed
       
   755          * @param name the field's name
       
   756          * @param type the field's type
       
   757          * @return a method handle which can load values from the field
       
   758          * @throws NoSuchFieldException if the field does not exist
       
   759          * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
       
   760          * @exception SecurityException if a security manager is present and it
       
   761          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
       
   762          * @throws NullPointerException if any argument is null
       
   763          */
       
   764         public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
       
   765             return makeAccessor(refc, name, type, true, false);
       
   766         }
       
   767 
       
   768         /**
       
   769          * Produces a method handle giving write access to a static field.
       
   770          * The type of the method handle will have a void return type.
       
   771          * The method handle will take a single
       
   772          * argument, of the field's value type, the value to be stored.
       
   773          * Access checking is performed immediately on behalf of the lookup class.
       
   774          * @param refc the class or interface from which the method is accessed
       
   775          * @param name the field's name
       
   776          * @param type the field's type
       
   777          * @return a method handle which can store values into the field
       
   778          * @throws NoSuchFieldException if the field does not exist
       
   779          * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
       
   780          * @exception SecurityException if a security manager is present and it
       
   781          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
       
   782          * @throws NullPointerException if any argument is null
       
   783          */
       
   784         public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
       
   785             return makeAccessor(refc, name, type, true, true);
       
   786         }
       
   787 
       
   788         /**
       
   789          * Produces an early-bound method handle for a non-static method.
       
   790          * The receiver must have a supertype {@code defc} in which a method
       
   791          * of the given name and type is accessible to the lookup class.
       
   792          * The method and all its argument types must be accessible to the lookup class.
       
   793          * The type of the method handle will be that of the method,
       
   794          * without any insertion of an additional receiver parameter.
       
   795          * The given receiver will be bound into the method handle,
       
   796          * so that every call to the method handle will invoke the
       
   797          * requested method on the given receiver.
       
   798          * <p>
       
   799          * The returned method handle will have
       
   800          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
       
   801          * the method's variable arity modifier bit ({@code 0x0080}) is set
       
   802          * <em>and</em> the trailing array argument is not the only argument.
       
   803          * (If the trailing array argument is the only argument,
       
   804          * the given receiver value will be bound to it.)
       
   805          * <p>
       
   806          * This is equivalent to the following code:
       
   807          * <blockquote><pre>
       
   808 MethodHandle mh0 = {@link #findVirtual findVirtual}(defc, name, type);
       
   809 MethodHandle mh1 = mh0.{@link MethodHandle#bindTo bindTo}(receiver);
       
   810 MethodType mt1 = mh1.type();
       
   811 if (mh0.isVarargsCollector() && mt1.parameterCount() > 0) {
       
   812   mh1 = mh1.asVarargsCollector(mt1.parameterType(mt1.parameterCount()-1));
       
   813 return mh1;
       
   814          * </pre></blockquote>
       
   815          * where {@code defc} is either {@code receiver.getClass()} or a super
       
   816          * type of that class, in which the requested method is accessible
       
   817          * to the lookup class.
       
   818          * (Note that {@code bindTo} does not preserve variable arity.)
       
   819          * @param receiver the object from which the method is accessed
       
   820          * @param name the name of the method
       
   821          * @param type the type of the method, with the receiver argument omitted
       
   822          * @return the desired method handle
       
   823          * @throws NoSuchMethodException if the method does not exist
       
   824          * @throws IllegalAccessException if access checking fails
       
   825          * @exception SecurityException if a security manager is present and it
       
   826          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
       
   827          * @throws NullPointerException if any argument is null
       
   828          */
       
   829         public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
       
   830             Class<? extends Object> refc = receiver.getClass(); // may get NPE
       
   831             MemberName method = resolveOrFail(refc, name, type, false);
       
   832             checkMethod(refc, method, false);
       
   833             MethodHandle dmh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
       
   834             MethodHandle bmh = MethodHandleImpl.bindReceiver(dmh, receiver);
       
   835             if (bmh == null)
       
   836                 throw method.makeAccessException("no access", this);
       
   837             if (dmh.type().parameterCount() == 0)
       
   838                 return dmh;  // bound the trailing parameter; no varargs possible
       
   839             return fixVarargs(bmh, dmh);
       
   840         }
       
   841 
       
   842         /**
       
   843          * Makes a direct method handle to <i>m</i>, if the lookup class has permission.
       
   844          * If <i>m</i> is non-static, the receiver argument is treated as an initial argument.
       
   845          * If <i>m</i> is virtual, overriding is respected on every call.
       
   846          * Unlike the Core Reflection API, exceptions are <em>not</em> wrapped.
       
   847          * The type of the method handle will be that of the method,
       
   848          * with the receiver type prepended (but only if it is non-static).
       
   849          * If the method's {@code accessible} flag is not set,
       
   850          * access checking is performed immediately on behalf of the lookup class.
       
   851          * If <i>m</i> is not public, do not share the resulting handle with untrusted parties.
       
   852          * <p>
       
   853          * The returned method handle will have
       
   854          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
       
   855          * the method's variable arity modifier bit ({@code 0x0080}) is set.
       
   856          * @param m the reflected method
       
   857          * @return a method handle which can invoke the reflected method
       
   858          * @throws IllegalAccessException if access checking fails
       
   859          * @throws NullPointerException if the argument is null
       
   860          */
       
   861         public MethodHandle unreflect(Method m) throws IllegalAccessException {
       
   862             MemberName method = new MemberName(m);
       
   863             assert(method.isMethod());
       
   864             if (!m.isAccessible())  checkMethod(method.getDeclaringClass(), method, method.isStatic());
       
   865             MethodHandle mh = MethodHandleImpl.findMethod(method, true, lookupClassOrNull());
       
   866             if (!m.isAccessible())  mh = restrictProtectedReceiver(method, mh);
       
   867             return mh;
       
   868         }
       
   869 
       
   870         /**
       
   871          * Produces a method handle for a reflected method.
       
   872          * It will bypass checks for overriding methods on the receiver,
       
   873          * as if by a {@code invokespecial} instruction from within the {@code specialCaller}.
       
   874          * The type of the method handle will be that of the method,
       
   875          * with the special caller type prepended (and <em>not</em> the receiver of the method).
       
   876          * If the method's {@code accessible} flag is not set,
       
   877          * access checking is performed immediately on behalf of the lookup class,
       
   878          * as if {@code invokespecial} instruction were being linked.
       
   879          * <p>
       
   880          * The returned method handle will have
       
   881          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
       
   882          * the method's variable arity modifier bit ({@code 0x0080}) is set.
       
   883          * @param m the reflected method
       
   884          * @param specialCaller the class nominally calling the method
       
   885          * @return a method handle which can invoke the reflected method
       
   886          * @throws IllegalAccessException if access checking fails
       
   887          * @throws NullPointerException if any argument is null
       
   888          */
       
   889         public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException {
       
   890             checkSpecialCaller(specialCaller);
       
   891             MemberName method = new MemberName(m);
       
   892             assert(method.isMethod());
       
   893             // ignore m.isAccessible:  this is a new kind of access
       
   894             checkMethod(m.getDeclaringClass(), method, false);
       
   895             MethodHandle mh = MethodHandleImpl.findMethod(method, false, lookupClassOrNull());
       
   896             return restrictReceiver(method, mh, specialCaller);
       
   897         }
       
   898 
       
   899         /**
       
   900          * Produces a method handle for a reflected constructor.
       
   901          * The type of the method handle will be that of the constructor,
       
   902          * with the return type changed to the declaring class.
       
   903          * The method handle will perform a {@code newInstance} operation,
       
   904          * creating a new instance of the constructor's class on the
       
   905          * arguments passed to the method handle.
       
   906          * <p>
       
   907          * If the constructor's {@code accessible} flag is not set,
       
   908          * access checking is performed immediately on behalf of the lookup class.
       
   909          * <p>
       
   910          * The returned method handle will have
       
   911          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
       
   912          * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
       
   913          * @param c the reflected constructor
       
   914          * @return a method handle which can invoke the reflected constructor
       
   915          * @throws IllegalAccessException if access checking fails
       
   916          * @throws NullPointerException if the argument is null
       
   917          */
       
   918         public MethodHandle unreflectConstructor(Constructor c) throws IllegalAccessException {
       
   919             MemberName ctor = new MemberName(c);
       
   920             assert(ctor.isConstructor());
       
   921             if (!c.isAccessible())  checkAccess(c.getDeclaringClass(), ctor);
       
   922             MethodHandle rawCtor = MethodHandleImpl.findMethod(ctor, false, lookupClassOrNull());
       
   923             MethodHandle allocator = MethodHandleImpl.makeAllocator(rawCtor);
       
   924             return fixVarargs(allocator, rawCtor);
       
   925         }
       
   926 
       
   927         /**
       
   928          * Produces a method handle giving read access to a reflected field.
       
   929          * The type of the method handle will have a return type of the field's
       
   930          * value type.
       
   931          * If the field is static, the method handle will take no arguments.
       
   932          * Otherwise, its single argument will be the instance containing
       
   933          * the field.
       
   934          * If the field's {@code accessible} flag is not set,
       
   935          * access checking is performed immediately on behalf of the lookup class.
       
   936          * @param f the reflected field
       
   937          * @return a method handle which can load values from the reflected field
       
   938          * @throws IllegalAccessException if access checking fails
       
   939          * @throws NullPointerException if the argument is null
       
   940          */
       
   941         public MethodHandle unreflectGetter(Field f) throws IllegalAccessException {
       
   942             return makeAccessor(f.getDeclaringClass(), new MemberName(f), f.isAccessible(), false);
       
   943         }
       
   944 
       
   945         /**
       
   946          * Produces a method handle giving write access to a reflected field.
       
   947          * The type of the method handle will have a void return type.
       
   948          * If the field is static, the method handle will take a single
       
   949          * argument, of the field's value type, the value to be stored.
       
   950          * Otherwise, the two arguments will be the instance containing
       
   951          * the field, and the value to be stored.
       
   952          * If the field's {@code accessible} flag is not set,
       
   953          * access checking is performed immediately on behalf of the lookup class.
       
   954          * @param f the reflected field
       
   955          * @return a method handle which can store values into the reflected field
       
   956          * @throws IllegalAccessException if access checking fails
       
   957          * @throws NullPointerException if the argument is null
       
   958          */
       
   959         public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
       
   960             return makeAccessor(f.getDeclaringClass(), new MemberName(f), f.isAccessible(), true);
       
   961         }
       
   962 
       
   963         /// Helper methods, all package-private.
       
   964 
       
   965         MemberName resolveOrFail(Class<?> refc, String name, Class<?> type, boolean isStatic) throws NoSuchFieldException, IllegalAccessException {
       
   966             checkSymbolicClass(refc);  // do this before attempting to resolve
       
   967             name.getClass(); type.getClass();  // NPE
       
   968             int mods = (isStatic ? Modifier.STATIC : 0);
       
   969             return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull(),
       
   970                                             NoSuchFieldException.class);
       
   971         }
       
   972 
       
   973         MemberName resolveOrFail(Class<?> refc, String name, MethodType type, boolean isStatic) throws NoSuchMethodException, IllegalAccessException {
       
   974             checkSymbolicClass(refc);  // do this before attempting to resolve
       
   975             name.getClass(); type.getClass();  // NPE
       
   976             int mods = (isStatic ? Modifier.STATIC : 0);
       
   977             return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), true, lookupClassOrNull(),
       
   978                                             NoSuchMethodException.class);
       
   979         }
       
   980 
       
   981         MemberName resolveOrFail(Class<?> refc, String name, MethodType type, boolean isStatic,
       
   982                                  boolean searchSupers, Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
       
   983             checkSymbolicClass(refc);  // do this before attempting to resolve
       
   984             name.getClass(); type.getClass();  // NPE
       
   985             int mods = (isStatic ? Modifier.STATIC : 0);
       
   986             return IMPL_NAMES.resolveOrFail(new MemberName(refc, name, type, mods), searchSupers, specialCaller,
       
   987                                             NoSuchMethodException.class);
       
   988         }
       
   989 
       
   990         void checkSymbolicClass(Class<?> refc) throws IllegalAccessException {
       
   991             Class<?> caller = lookupClassOrNull();
       
   992             if (caller != null && !VerifyAccess.isClassAccessible(refc, caller))
       
   993                 throw new MemberName(refc).makeAccessException("symbolic reference class is not public", this);
       
   994         }
       
   995 
       
   996         void checkMethod(Class<?> refc, MemberName m, boolean wantStatic) throws IllegalAccessException {
       
   997             String message;
       
   998             if (m.isConstructor())
       
   999                 message = "expected a method, not a constructor";
       
  1000             else if (!m.isMethod())
       
  1001                 message = "expected a method";
       
  1002             else if (wantStatic != m.isStatic())
       
  1003                 message = wantStatic ? "expected a static method" : "expected a non-static method";
       
  1004             else
       
  1005                 { checkAccess(refc, m); return; }
       
  1006             throw m.makeAccessException(message, this);
       
  1007         }
       
  1008 
       
  1009         void checkAccess(Class<?> refc, MemberName m) throws IllegalAccessException {
       
  1010             int allowedModes = this.allowedModes;
       
  1011             if (allowedModes == TRUSTED)  return;
       
  1012             int mods = m.getModifiers();
       
  1013             if (Modifier.isPublic(mods) && Modifier.isPublic(refc.getModifiers()) && allowedModes != 0)
       
  1014                 return;  // common case
       
  1015             int requestedModes = fixmods(mods);  // adjust 0 => PACKAGE
       
  1016             if ((requestedModes & allowedModes) != 0
       
  1017                 && VerifyAccess.isMemberAccessible(refc, m.getDeclaringClass(),
       
  1018                                                    mods, lookupClass()))
       
  1019                 return;
       
  1020             if (((requestedModes & ~allowedModes) & PROTECTED) != 0
       
  1021                 && VerifyAccess.isSamePackage(m.getDeclaringClass(), lookupClass()))
       
  1022                 // Protected members can also be checked as if they were package-private.
       
  1023                 return;
       
  1024             throw m.makeAccessException(accessFailedMessage(refc, m), this);
       
  1025         }
       
  1026 
       
  1027         String accessFailedMessage(Class<?> refc, MemberName m) {
       
  1028             Class<?> defc = m.getDeclaringClass();
       
  1029             int mods = m.getModifiers();
       
  1030             // check the class first:
       
  1031             boolean classOK = (Modifier.isPublic(defc.getModifiers()) &&
       
  1032                                (defc == refc ||
       
  1033                                 Modifier.isPublic(refc.getModifiers())));
       
  1034             if (!classOK && (allowedModes & PACKAGE) != 0) {
       
  1035                 classOK = (VerifyAccess.isClassAccessible(defc, lookupClass()) &&
       
  1036                            (defc == refc ||
       
  1037                             VerifyAccess.isClassAccessible(refc, lookupClass())));
       
  1038             }
       
  1039             if (!classOK)
       
  1040                 return "class is not public";
       
  1041             if (Modifier.isPublic(mods))
       
  1042                 return "access to public member failed";  // (how?)
       
  1043             if (Modifier.isPrivate(mods))
       
  1044                 return "member is private";
       
  1045             if (Modifier.isProtected(mods))
       
  1046                 return "member is protected";
       
  1047             return "member is private to package";
       
  1048         }
       
  1049 
       
  1050         private static final boolean ALLOW_NESTMATE_ACCESS = false;
       
  1051 
       
  1052         void checkSpecialCaller(Class<?> specialCaller) throws IllegalAccessException {
       
  1053             if (allowedModes == TRUSTED)  return;
       
  1054             if ((allowedModes & PRIVATE) == 0
       
  1055                 || (specialCaller != lookupClass()
       
  1056                     && !(ALLOW_NESTMATE_ACCESS &&
       
  1057                          VerifyAccess.isSamePackageMember(specialCaller, lookupClass()))))
       
  1058                 throw new MemberName(specialCaller).
       
  1059                     makeAccessException("no private access for invokespecial", this);
       
  1060         }
       
  1061 
       
  1062         MethodHandle restrictProtectedReceiver(MemberName method, MethodHandle mh) throws IllegalAccessException {
       
  1063             // The accessing class only has the right to use a protected member
       
  1064             // on itself or a subclass.  Enforce that restriction, from JVMS 5.4.4, etc.
       
  1065             if (!method.isProtected() || method.isStatic()
       
  1066                 || allowedModes == TRUSTED
       
  1067                 || method.getDeclaringClass() == lookupClass()
       
  1068                 || (ALLOW_NESTMATE_ACCESS &&
       
  1069                     VerifyAccess.isSamePackageMember(method.getDeclaringClass(), lookupClass())))
       
  1070                 return mh;
       
  1071             else
       
  1072                 return restrictReceiver(method, mh, lookupClass());
       
  1073         }
       
  1074         MethodHandle restrictReceiver(MemberName method, MethodHandle mh, Class<?> caller) throws IllegalAccessException {
       
  1075             assert(!method.isStatic());
       
  1076             Class<?> defc = method.getDeclaringClass();  // receiver type of mh is too wide
       
  1077             if (defc.isInterface() || !defc.isAssignableFrom(caller)) {
       
  1078                 throw method.makeAccessException("caller class must be a subclass below the method", caller);
       
  1079             }
       
  1080             MethodType rawType = mh.type();
       
  1081             if (rawType.parameterType(0) == caller)  return mh;
       
  1082             MethodType narrowType = rawType.changeParameterType(0, caller);
       
  1083             MethodHandle narrowMH = MethodHandleImpl.convertArguments(mh, narrowType, rawType, null);
       
  1084             return fixVarargs(narrowMH, mh);
       
  1085         }
       
  1086 
       
  1087         MethodHandle makeAccessor(Class<?> refc, String name, Class<?> type,
       
  1088                                   boolean isStatic, boolean isSetter) throws NoSuchFieldException, IllegalAccessException {
       
  1089             MemberName field = resolveOrFail(refc, name, type, isStatic);
       
  1090             if (isStatic != field.isStatic())
       
  1091                 throw field.makeAccessException(isStatic
       
  1092                                                 ? "expected a static field"
       
  1093                                                 : "expected a non-static field", this);
       
  1094             return makeAccessor(refc, field, false, isSetter);
       
  1095         }
       
  1096 
       
  1097         MethodHandle makeAccessor(Class<?> refc, MemberName field,
       
  1098                                   boolean trusted, boolean isSetter) throws IllegalAccessException {
       
  1099             assert(field.isField());
       
  1100             if (trusted)
       
  1101                 return MethodHandleImpl.accessField(field, isSetter, lookupClassOrNull());
       
  1102             checkAccess(refc, field);
       
  1103             MethodHandle mh = MethodHandleImpl.accessField(field, isSetter, lookupClassOrNull());
       
  1104             return restrictProtectedReceiver(field, mh);
       
  1105         }
       
  1106     }
       
  1107 
       
  1108     /**
       
  1109      * Produces a method handle giving read access to elements of an array.
       
  1110      * The type of the method handle will have a return type of the array's
       
  1111      * element type.  Its first argument will be the array type,
       
  1112      * and the second will be {@code int}.
       
  1113      * @param arrayClass an array type
       
  1114      * @return a method handle which can load values from the given array type
       
  1115      * @throws NullPointerException if the argument is null
       
  1116      * @throws  IllegalArgumentException if arrayClass is not an array type
       
  1117      */
       
  1118     public static
       
  1119     MethodHandle arrayElementGetter(Class<?> arrayClass) throws IllegalArgumentException {
       
  1120         return MethodHandleImpl.accessArrayElement(arrayClass, false);
       
  1121     }
       
  1122 
       
  1123     /**
       
  1124      * Produces a method handle giving write access to elements of an array.
       
  1125      * The type of the method handle will have a void return type.
       
  1126      * Its last argument will be the array's element type.
       
  1127      * The first and second arguments will be the array type and int.
       
  1128      * @return a method handle which can store values into the array type
       
  1129      * @throws NullPointerException if the argument is null
       
  1130      * @throws IllegalArgumentException if arrayClass is not an array type
       
  1131      */
       
  1132     public static
       
  1133     MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException {
       
  1134         return MethodHandleImpl.accessArrayElement(arrayClass, true);
       
  1135     }
       
  1136 
       
  1137     /// method handle invocation (reflective style)
       
  1138 
       
  1139     /**
       
  1140      * Produces a method handle which will invoke any method handle of the
       
  1141      * given {@code type} on a standard set of {@code Object} type arguments
       
  1142      * and a single trailing {@code Object[]} array.
       
  1143      * The resulting invoker will be a method handle with the following
       
  1144      * arguments:
       
  1145      * <ul>
       
  1146      * <li>a single {@code MethodHandle} target
       
  1147      * <li>zero or more {@code Object} values (counted by {@code objectArgCount})
       
  1148      * <li>an {@code Object[]} array containing more arguments
       
  1149      * </ul>
       
  1150      * <p>
       
  1151      * The invoker will behave like a call to {@link MethodHandle#invokeGeneric invokeGeneric} with
       
  1152      * the indicated {@code type}.
       
  1153      * That is, if the target is exactly of the given {@code type}, it will behave
       
  1154      * like {@code invokeExact}; otherwise it behave as if {@link MethodHandle#asType asType}
       
  1155      * is used to convert the target to the required {@code type}.
       
  1156      * <p>
       
  1157      * The type of the returned invoker will not be the given {@code type}, but rather
       
  1158      * will have all parameter and return types replaced by {@code Object}, except for
       
  1159      * the last parameter type, which will be the array type {@code Object[]}.
       
  1160      * <p>
       
  1161      * Before invoking its target, the invoker will spread the varargs array, apply
       
  1162      * reference casts as necessary, and unbox and widen primitive arguments.
       
  1163      * The return value of the invoker will be an {@code Object} reference,
       
  1164      * boxing a primitive value if the original type returns a primitive,
       
  1165      * and always null if the original type returns void.
       
  1166      * <p>
       
  1167      * This method is equivalent to the following code (though it may be more efficient):
       
  1168      * <p><blockquote><pre>
       
  1169 MethodHandle invoker = MethodHandles.genericInvoker(type);
       
  1170 int spreadArgCount = type.parameterCount - objectArgCount;
       
  1171 invoker = invoker.asSpreader(Object[].class, spreadArgCount);
       
  1172 return invoker;
       
  1173      * </pre></blockquote>
       
  1174      * <p>
       
  1175      * This method throws no reflective or security exceptions.
       
  1176      * @param type the desired target type
       
  1177      * @param objectArgCount number of fixed (non-varargs) {@code Object} arguments
       
  1178      * @return a method handle suitable for invoking any method handle of the given type
       
  1179      */
       
  1180     static public
       
  1181     MethodHandle spreadInvoker(MethodType type, int objectArgCount) {
       
  1182         if (objectArgCount < 0 || objectArgCount > type.parameterCount())
       
  1183             throw new IllegalArgumentException("bad argument count "+objectArgCount);
       
  1184         return type.invokers().spreadInvoker(objectArgCount);
       
  1185     }
       
  1186 
       
  1187     /**
       
  1188      * Produces a special <em>invoker method handle</em> which can be used to
       
  1189      * invoke any method handle of the given type, as if by {@code invokeExact}.
       
  1190      * The resulting invoker will have a type which is
       
  1191      * exactly equal to the desired type, except that it will accept
       
  1192      * an additional leading argument of type {@code MethodHandle}.
       
  1193      * <p>
       
  1194      * This method is equivalent to the following code (though it may be more efficient):
       
  1195      * <p><blockquote><pre>
       
  1196 publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)
       
  1197      * </pre></blockquote>
       
  1198      *
       
  1199      * <p style="font-size:smaller;">
       
  1200      * <em>Discussion:</em>
       
  1201      * Invoker method handles can be useful when working with variable method handles
       
  1202      * of unknown types.
       
  1203      * For example, to emulate an {@code invokeExact} call to a variable method
       
  1204      * handle {@code M}, extract its type {@code T},
       
  1205      * look up the invoker method {@code X} for {@code T},
       
  1206      * and call the invoker method, as {@code X.invokeGeneric(T, A...)}.
       
  1207      * (It would not work to call {@code X.invokeExact}, since the type {@code T}
       
  1208      * is unknown.)
       
  1209      * If spreading, collecting, or other argument transformations are required,
       
  1210      * they can be applied once to the invoker {@code X} and reused on many {@code M}
       
  1211      * method handle values, as long as they are compatible with the type of {@code X}.
       
  1212      * <p>
       
  1213      * <em>(Note:  The invoker method is not available via the Core Reflection API.
       
  1214      * An attempt to call {@linkplain java.lang.reflect.Method#invoke Method.invoke}
       
  1215      * on the declared {@code invokeExact} or {@code invokeGeneric} method will raise an
       
  1216      * {@link java.lang.UnsupportedOperationException UnsupportedOperationException}.)</em>
       
  1217      * <p>
       
  1218      * This method throws no reflective or security exceptions.
       
  1219      * @param type the desired target type
       
  1220      * @return a method handle suitable for invoking any method handle of the given type
       
  1221      */
       
  1222     static public
       
  1223     MethodHandle exactInvoker(MethodType type) {
       
  1224         return type.invokers().exactInvoker();
       
  1225     }
       
  1226 
       
  1227     /**
       
  1228      * Produces a special <em>invoker method handle</em> which can be used to
       
  1229      * invoke any method handle of the given type, as if by {@code invokeGeneric}.
       
  1230      * The resulting invoker will have a type which is
       
  1231      * exactly equal to the desired type, except that it will accept
       
  1232      * an additional leading argument of type {@code MethodHandle}.
       
  1233      * <p>
       
  1234      * Before invoking its target, the invoker will apply reference casts as
       
  1235      * necessary and unbox and widen primitive arguments, as if by {@link #convertArguments convertArguments}.
       
  1236      * The return value of the invoker will be an {@code Object} reference,
       
  1237      * boxing a primitive value if the original type returns a primitive,
       
  1238      * and always null if the original type returns void.
       
  1239      * <p>
       
  1240      * This method is equivalent to the following code (though it may be more efficient):
       
  1241      * <p><blockquote><pre>
       
  1242 publicLookup().findVirtual(MethodHandle.class, "invokeGeneric", type)
       
  1243      * </pre></blockquote>
       
  1244      * <p>
       
  1245      * This method throws no reflective or security exceptions.
       
  1246      * @param type the desired target type
       
  1247      * @return a method handle suitable for invoking any method handle convertible to the given type
       
  1248      */
       
  1249     static public
       
  1250     MethodHandle genericInvoker(MethodType type) {
       
  1251         return type.invokers().genericInvoker();
       
  1252     }
       
  1253 
       
  1254     /**
       
  1255      * Perform value checking, exactly as if for an adapted method handle.
       
  1256      * It is assumed that the given value is either null, of type T0,
       
  1257      * or (if T0 is primitive) of the wrapper type corresponding to T0.
       
  1258      * The following checks and conversions are made:
       
  1259      * <ul>
       
  1260      * <li>If T0 and T1 are references, then a cast to T1 is applied.
       
  1261      *     (The types do not need to be related in any particular way.)
       
  1262      * <li>If T0 and T1 are primitives, then a widening or narrowing
       
  1263      *     conversion is applied, if one exists.
       
  1264      * <li>If T0 is a primitive and T1 a reference, and
       
  1265      *     T0 has a wrapper type TW, a boxing conversion to TW is applied,
       
  1266      *     possibly followed by a reference conversion.
       
  1267      *     T1 must be TW or a supertype.
       
  1268      * <li>If T0 is a reference and T1 a primitive, and
       
  1269      *     T1 has a wrapper type TW, an unboxing conversion is applied,
       
  1270      *     possibly preceded by a reference conversion.
       
  1271      *     T0 must be TW or a supertype.
       
  1272      * <li>If T1 is void, the return value is discarded
       
  1273      * <li>If T0 is void and T1 a reference, a null value is introduced.
       
  1274      * <li>If T0 is void and T1 a primitive, a zero value is introduced.
       
  1275      * </ul>
       
  1276      * If the value is discarded, null will be returned.
       
  1277      * @param valueType
       
  1278      * @param value
       
  1279      * @return the value, converted if necessary
       
  1280      * @throws java.lang.ClassCastException if a cast fails
       
  1281      */
       
  1282     static
       
  1283     <T0, T1> T1 checkValue(Class<T0> t0, Class<T1> t1, Object value)
       
  1284        throws ClassCastException
       
  1285     {
       
  1286         if (t0 == t1) {
       
  1287             // no conversion needed; just reassert the same type
       
  1288             if (t0.isPrimitive())
       
  1289                 return Wrapper.asPrimitiveType(t1).cast(value);
       
  1290             else
       
  1291                 return Wrapper.OBJECT.convert(value, t1);
       
  1292         }
       
  1293         boolean prim0 = t0.isPrimitive(), prim1 = t1.isPrimitive();
       
  1294         if (!prim0) {
       
  1295             // check contract with caller
       
  1296             Wrapper.OBJECT.convert(value, t0);
       
  1297             if (!prim1) {
       
  1298                 return Wrapper.OBJECT.convert(value, t1);
       
  1299             }
       
  1300             // convert reference to primitive by unboxing
       
  1301             Wrapper w1 = Wrapper.forPrimitiveType(t1);
       
  1302             return w1.convert(value, t1);
       
  1303         }
       
  1304         // check contract with caller:
       
  1305         Wrapper.asWrapperType(t0).cast(value);
       
  1306         Wrapper w1 = Wrapper.forPrimitiveType(t1);
       
  1307         return w1.convert(value, t1);
       
  1308     }
       
  1309 
       
  1310     static
       
  1311     Object checkValue(Class<?> T1, Object value)
       
  1312        throws ClassCastException
       
  1313     {
       
  1314         Class<?> T0;
       
  1315         if (value == null)
       
  1316             T0 = Object.class;
       
  1317         else
       
  1318             T0 = value.getClass();
       
  1319         return checkValue(T0, T1, value);
       
  1320     }
       
  1321 
       
  1322     /// method handle modification (creation from other method handles)
       
  1323 
       
  1324     /**
       
  1325      * Produces a method handle which adapts the type of the
       
  1326      * given method handle to a new type by pairwise argument conversion.
       
  1327      * The original type and new type must have the same number of arguments.
       
  1328      * The resulting method handle is guaranteed to report a type
       
  1329      * which is equal to the desired new type.
       
  1330      * <p>
       
  1331      * If the original type and new type are equal, returns target.
       
  1332      * <p>
       
  1333      * The following conversions are applied as needed both to
       
  1334      * arguments and return types.  Let T0 and T1 be the differing
       
  1335      * new and old parameter types (or old and new return types)
       
  1336      * for corresponding values passed by the new and old method types.
       
  1337      * Given those types T0, T1, one of the following conversions is applied
       
  1338      * if possible:
       
  1339      * <ul>
       
  1340      * <li>If T0 and T1 are references, then a cast to T1 is applied.
       
  1341      *     (The types do not need to be related in any particular way.)
       
  1342      * <li>If T0 and T1 are primitives, then a Java method invocation
       
  1343      *     conversion (JLS 5.3) is applied, if one exists.
       
  1344      * <li>If T0 is a primitive and T1 a reference, a boxing
       
  1345      *     conversion is applied if one exists, possibly followed by
       
  1346      *     a reference conversion to a superclass.
       
  1347      *     T1 must be a wrapper class or a supertype of one.
       
  1348      * <li>If T0 is a reference and T1 a primitive, an unboxing
       
  1349      *     conversion will be applied at runtime, possibly followed
       
  1350      *     by a Java method invocation conversion (JLS 5.3)
       
  1351      *     on the primitive value.  (These are the widening conversions.)
       
  1352      *     T0 must be a wrapper class or a supertype of one.
       
  1353      *     (In the case where T0 is Object, these are the conversions
       
  1354      *     allowed by java.lang.reflect.Method.invoke.)
       
  1355      * <li>If the return type T1 is void, any returned value is discarded
       
  1356      * <li>If the return type T0 is void and T1 a reference, a null value is introduced.
       
  1357      * <li>If the return type T0 is void and T1 a primitive, a zero value is introduced.
       
  1358      * </ul>
       
  1359      * @param target the method handle to invoke after arguments are retyped
       
  1360      * @param newType the expected type of the new method handle
       
  1361      * @return a method handle which delegates to {@code target} after performing
       
  1362      *           any necessary argument conversions, and arranges for any
       
  1363      *           necessary return value conversions
       
  1364      * @throws NullPointerException if either argument is null
       
  1365      * @throws WrongMethodTypeException if the conversion cannot be made
       
  1366      * @see MethodHandle#asType
       
  1367      * @see MethodHandles#explicitCastArguments
       
  1368      */
       
  1369     public static
       
  1370     MethodHandle convertArguments(MethodHandle target, MethodType newType) {
       
  1371         MethodType oldType = target.type();
       
  1372         if (oldType.equals(newType))
       
  1373             return target;
       
  1374         MethodHandle res = null;
       
  1375         try {
       
  1376             res = MethodHandleImpl.convertArguments(target,
       
  1377                                                     newType, oldType, null);
       
  1378         } catch (IllegalArgumentException ex) {
       
  1379         }
       
  1380         if (res == null)
       
  1381             throw new WrongMethodTypeException("cannot convert to "+newType+": "+target);
       
  1382         return res;
       
  1383     }
       
  1384 
       
  1385     /**
       
  1386      * Produces a method handle which adapts the type of the
       
  1387      * given method handle to a new type by pairwise argument conversion.
       
  1388      * The original type and new type must have the same number of arguments.
       
  1389      * The resulting method handle is guaranteed to report a type
       
  1390      * which is equal to the desired new type.
       
  1391      * <p>
       
  1392      * If the original type and new type are equal, returns target.
       
  1393      * <p>
       
  1394      * The same conversions are allowed as for {@link #convertArguments convertArguments},
       
  1395      * and some additional conversions are also applied if those conversions fail.
       
  1396      * Given types T0, T1, one of the following conversions is applied
       
  1397      * in addition, if the conversions specified for {@code convertArguments}
       
  1398      * would be insufficient:
       
  1399      * <ul>
       
  1400      * <li>If T0 and T1 are references, and T1 is an interface type,
       
  1401      *     then the value of type T0 is passed as a T1 without a cast.
       
  1402      *     (This treatment of interfaces follows the usage of the bytecode verifier.)
       
  1403      * <li>If T0 and T1 are primitives and one is boolean,
       
  1404      *     the boolean is treated as a one-bit unsigned integer.
       
  1405      *     (This treatment follows the usage of the bytecode verifier.)
       
  1406      *     A conversion from another primitive type behaves as if
       
  1407      *     it first converts to byte, and then masks all but the low bit.
       
  1408      * <li>If a primitive value would be converted by {@code convertArguments}
       
  1409      *     using Java method invocation conversion (JLS 5.3),
       
  1410      *     Java casting conversion (JLS 5.5) may be used also.
       
  1411      *     This allows primitives to be narrowed as well as widened.
       
  1412      * </ul>
       
  1413      * @param target the method handle to invoke after arguments are retyped
       
  1414      * @param newType the expected type of the new method handle
       
  1415      * @return a method handle which delegates to {@code target} after performing
       
  1416      *           any necessary argument conversions, and arranges for any
       
  1417      *           necessary return value conversions
       
  1418      * @throws NullPointerException if either argument is null
       
  1419      * @throws WrongMethodTypeException if the conversion cannot be made
       
  1420      * @see MethodHandle#asType
       
  1421      * @see MethodHandles#convertArguments
       
  1422      */
       
  1423     public static
       
  1424     MethodHandle explicitCastArguments(MethodHandle target, MethodType newType) {
       
  1425         return convertArguments(target, newType);  // FIXME!
       
  1426     }
       
  1427 
       
  1428     /*
       
  1429       FIXME: Reconcile javadoc with 10/22/2010 EG notes on conversion:
       
  1430 
       
  1431       Both converters arrange for their method handles to convert arguments
       
  1432       and return values.  The conversion rules are the same for arguments
       
  1433       and return values, and depend only on source and target types, S and
       
  1434       T.  The conversions allowed by castConvertArguments are a strict
       
  1435       superset of those performed by convertArguments.
       
  1436 
       
  1437       In all cases, if S and T are references, a simple checkcast is done.
       
  1438       If neither S nor T is a primitive, no attempt is made to unbox and
       
  1439       box.  A failed conversion throws ClassCastException.
       
  1440 
       
  1441       If T is void, the value is dropped.
       
  1442 
       
  1443       For compatibility with reflection, if S is void and T is a reference,
       
  1444       a null value is produced.
       
  1445 
       
  1446       For compatibility with reflection, if S is a reference and T is a
       
  1447       primitive, S is first unboxed and then undergoes primitive conversion.
       
  1448       In the case of 'convertArguments', only assignment conversion is
       
  1449       performed (no narrowing primitive conversion).
       
  1450 
       
  1451       If S is a primitive, S is boxed, and then the above rules are applied.
       
  1452       If S and T are both primitives, the boxing will be undetectable; only
       
  1453       the primitive conversions will be apparent to the user.  The key point
       
  1454       is that if S is a primitive type, the implementation may box it and
       
  1455       treat is as Object, without loss of information, or it may use a "fast
       
  1456       path" which does not use boxing.
       
  1457 
       
  1458       Notwithstanding the rules above, for compatibility with the verifier,
       
  1459       if T is an interface, it is treated as if it were Object.  [KEEP THIS?]
       
  1460 
       
  1461       Also, for compatibility with the verifier, a boolean may be undergo
       
  1462       widening or narrowing conversion to any other primitive type.  [KEEP THIS?]
       
  1463     */
       
  1464 
       
  1465     /**
       
  1466      * Produces a method handle which adapts the calling sequence of the
       
  1467      * given method handle to a new type, by reordering the arguments.
       
  1468      * The resulting method handle is guaranteed to report a type
       
  1469      * which is equal to the desired new type.
       
  1470      * <p>
       
  1471      * The given array controls the reordering.
       
  1472      * Call {@code #I} the number of incoming parameters (the value
       
  1473      * {@code newType.parameterCount()}, and call {@code #O} the number
       
  1474      * of outgoing parameters (the value {@code target.type().parameterCount()}).
       
  1475      * Then the length of the reordering array must be {@code #O},
       
  1476      * and each element must be a non-negative number less than {@code #I}.
       
  1477      * For every {@code N} less than {@code #O}, the {@code N}-th
       
  1478      * outgoing argument will be taken from the {@code I}-th incoming
       
  1479      * argument, where {@code I} is {@code reorder[N]}.
       
  1480      * <p>
       
  1481      * No argument or return value conversions are applied.
       
  1482      * The type of each incoming argument, as determined by {@code newType},
       
  1483      * must be identical to the type of the corresponding outgoing argument
       
  1484      * or arguments in the target method handle.
       
  1485      * The return type of {@code newType} must be identical to the return
       
  1486      * type of the original target.
       
  1487      * <p>
       
  1488      * The reordering array need not specify an actual permutation.
       
  1489      * An incoming argument will be duplicated if its index appears
       
  1490      * more than once in the array, and an incoming argument will be dropped
       
  1491      * if its index does not appear in the array.
       
  1492      * As in the case of {@link #dropArguments(MethodHandle,int,List) dropArguments},
       
  1493      * incoming arguments which are not mentioned in the reordering array
       
  1494      * are may be any type, as determined only by {@code newType}.
       
  1495      * <blockquote><pre>
       
  1496 MethodType intfn1 = MethodType.methodType(int.class, int.class);
       
  1497 MethodType intfn2 = MethodType.methodType(int.class, int.class, int.class);
       
  1498 MethodHandle sub = ... {int x, int y => x-y} ...;
       
  1499 assert(sub.type().equals(intfn2));
       
  1500 MethodHandle sub1 = MethodHandles.permuteArguments(sub, intfn2, 0, 1);
       
  1501 MethodHandle rsub = MethodHandles.permuteArguments(sub, intfn2, 1, 0);
       
  1502 assert((int)rsub.invokeExact(1, 100) == 99);
       
  1503 MethodHandle add = ... {int x, int y => x+y} ...;
       
  1504 assert(add.type().equals(intfn2));
       
  1505 MethodHandle twice = MethodHandles.permuteArguments(add, intfn1, 0, 0);
       
  1506 assert(twice.type().equals(intfn1));
       
  1507 assert((int)twice.invokeExact(21) == 42);
       
  1508      * </pre></blockquote>
       
  1509      * @param target the method handle to invoke after arguments are reordered
       
  1510      * @param newType the expected type of the new method handle
       
  1511      * @param reorder a string which controls the reordering
       
  1512      * @return a method handle which delegates to {@code target} after it
       
  1513      *           drops unused arguments and moves and/or duplicates the other arguments
       
  1514      * @throws NullPointerException if any argument is null
       
  1515      */
       
  1516     public static
       
  1517     MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder) {
       
  1518         MethodType oldType = target.type();
       
  1519         checkReorder(reorder, newType, oldType);
       
  1520         return MethodHandleImpl.convertArguments(target,
       
  1521                                                  newType, oldType,
       
  1522                                                  reorder);
       
  1523     }
       
  1524 
       
  1525     private static void checkReorder(int[] reorder, MethodType newType, MethodType oldType) {
       
  1526         if (reorder.length == oldType.parameterCount()) {
       
  1527             int limit = newType.parameterCount();
       
  1528             boolean bad = false;
       
  1529             for (int i : reorder) {
       
  1530                 if (i < 0 || i >= limit) {
       
  1531                     bad = true; break;
       
  1532                 }
       
  1533             }
       
  1534             if (!bad)  return;
       
  1535         }
       
  1536         throw newIllegalArgumentException("bad reorder array");
       
  1537     }
       
  1538 
       
  1539     /**
       
  1540      * Equivalent to the following code:
       
  1541      * <p><blockquote><pre>
       
  1542      * int spreadPos = newType.parameterCount() - 1;
       
  1543      * Class&lt;?&gt; spreadType = newType.parameterType(spreadPos);
       
  1544      * int spreadCount = target.type().parameterCount() - spreadPos;
       
  1545      * MethodHandle adapter = target.asSpreader(spreadType, spreadCount);
       
  1546      * adapter = adapter.asType(newType);
       
  1547      * return adapter;
       
  1548      * </pre></blockquote>
       
  1549      * @param target the method handle to invoke after argument spreading
       
  1550      * @param newType the expected type of the new method handle
       
  1551      * @return a method handle which spreads its final argument,
       
  1552      *         before calling the original method handle
       
  1553      */
       
  1554     /*non-public*/ static
       
  1555     MethodHandle spreadArguments(MethodHandle target, MethodType newType) {
       
  1556         MethodType oldType = target.type();
       
  1557         int inargs  = newType.parameterCount();
       
  1558         int outargs = oldType.parameterCount();
       
  1559         int spreadPos = inargs - 1;
       
  1560         int numSpread = (outargs - spreadPos);
       
  1561         MethodHandle res = null;
       
  1562         if (spreadPos >= 0 && numSpread >= 0) {
       
  1563             res = MethodHandleImpl.spreadArguments(target, newType, spreadPos);
       
  1564         }
       
  1565         if (res == null) {
       
  1566             throw newIllegalArgumentException("cannot spread "+newType+" to " +oldType);
       
  1567         }
       
  1568         return res;
       
  1569     }
       
  1570 
       
  1571     /**
       
  1572      * Equivalent to the following code:
       
  1573      * <p><blockquote><pre>
       
  1574      * int collectPos = target.type().parameterCount() - 1;
       
  1575      * Class&lt;?&gt; collectType = target.type().parameterType(collectPos);
       
  1576      * if (!collectType.isArray())  collectType = Object[].class;
       
  1577      * int collectCount = newType.parameterCount() - collectPos;
       
  1578      * MethodHandle adapter = target.asCollector(collectType, collectCount);
       
  1579      * adapter = adapter.asType(newType);
       
  1580      * return adapter;
       
  1581      * </pre></blockquote>
       
  1582      * @param target the method handle to invoke after argument collection
       
  1583      * @param newType the expected type of the new method handle
       
  1584      * @return a method handle which collects some trailing argument
       
  1585      *         into an array, before calling the original method handle
       
  1586      */
       
  1587     /*non-public*/ static
       
  1588     MethodHandle collectArguments(MethodHandle target, MethodType newType) {
       
  1589         MethodType oldType = target.type();
       
  1590         int inargs  = newType.parameterCount();
       
  1591         int outargs = oldType.parameterCount();
       
  1592         int collectPos = outargs - 1;
       
  1593         int numCollect = (inargs - collectPos);
       
  1594         if (collectPos < 0 || numCollect < 0)
       
  1595             throw newIllegalArgumentException("wrong number of arguments");
       
  1596         MethodHandle res = MethodHandleImpl.collectArguments(target, newType, collectPos, null);
       
  1597         if (res == null) {
       
  1598             throw newIllegalArgumentException("cannot collect from "+newType+" to " +oldType);
       
  1599         }
       
  1600         return res;
       
  1601     }
       
  1602 
       
  1603     /**
       
  1604      * Produces a method handle of the requested return type which returns the given
       
  1605      * constant value every time it is invoked.
       
  1606      * <p>
       
  1607      * Before the method handle is returned, the passed-in value is converted to the requested type.
       
  1608      * If the requested type is primitive, widening primitive conversions are attempted,
       
  1609      * else reference conversions are attempted.
       
  1610      * <p>The returned method handle is equivalent to {@code identity(type).bindTo(value)},
       
  1611      * unless the type is {@code void}, in which case it is {@code identity(type)}.
       
  1612      * @param type the return type of the desired method handle
       
  1613      * @param value the value to return
       
  1614      * @return a method handle of the given return type and no arguments, which always returns the given value
       
  1615      * @throws NullPointerException if the {@code type} argument is null
       
  1616      * @throws ClassCastException if the value cannot be converted to the required return type
       
  1617      * @throws IllegalArgumentException if the given type is {@code void.class}
       
  1618      */
       
  1619     public static
       
  1620     MethodHandle constant(Class<?> type, Object value) {
       
  1621         if (type.isPrimitive()) {
       
  1622             if (type == void.class)
       
  1623                 throw newIllegalArgumentException("void type");
       
  1624             Wrapper w = Wrapper.forPrimitiveType(type);
       
  1625             return identity(type).bindTo(w.convert(value, type));
       
  1626         } else {
       
  1627             return identity(type).bindTo(type.cast(value));
       
  1628         }
       
  1629     }
       
  1630 
       
  1631     /**
       
  1632      * Produces a method handle which returns its sole argument when invoked.
       
  1633      * <p>The identity function for {@code void} takes no arguments and returns no values.
       
  1634      * @param type the type of the sole parameter and return value of the desired method handle
       
  1635      * @return a unary method handle which accepts and returns the given type
       
  1636      * @throws NullPointerException if the argument is null
       
  1637      * @throws IllegalArgumentException if the given type is {@code void.class}
       
  1638      */
       
  1639     public static
       
  1640     MethodHandle identity(Class<?> type) {
       
  1641         if (type == void.class)
       
  1642             throw newIllegalArgumentException("void type");
       
  1643         else if (type == Object.class)
       
  1644             return ValueConversions.identity();
       
  1645         else if (type.isPrimitive())
       
  1646             return ValueConversions.identity(Wrapper.forPrimitiveType(type));
       
  1647         else
       
  1648             return AdapterMethodHandle.makeRetypeRaw(
       
  1649                     MethodType.methodType(type, type), ValueConversions.identity());
       
  1650     }
       
  1651 
       
  1652     /**
       
  1653      * Produces a method handle which calls the original method handle {@code target},
       
  1654      * after inserting the given argument(s) at the given position.
       
  1655      * The formal parameters to {@code target} which will be supplied by those
       
  1656      * arguments are called <em>bound parameters</em>, because the new method
       
  1657      * will contain bindings for those parameters take from {@code values}.
       
  1658      * The type of the new method handle will drop the types for the bound
       
  1659      * parameters from the original target type, since the new method handle
       
  1660      * will no longer require those arguments to be supplied by its callers.
       
  1661      * <p>
       
  1662      * Each given argument object must match the corresponding bound parameter type.
       
  1663      * If a bound parameter type is a primitive, the argument object
       
  1664      * must be a wrapper, and will be unboxed to produce the primitive value.
       
  1665      * <p>
       
  1666      * The  <i>pos</i> may range between zero and <i>N</i> (inclusively),
       
  1667      * where <i>N</i> is the number of argument types in resulting method handle
       
  1668      * (after bound parameter types are dropped).
       
  1669      * @param target the method handle to invoke after the argument is inserted
       
  1670      * @param pos where to insert the argument (zero for the first)
       
  1671      * @param values the series of arguments to insert
       
  1672      * @return a method handle which inserts an additional argument,
       
  1673      *         before calling the original method handle
       
  1674      * @throws NullPointerException if the {@code target} argument or the {@code values} array is null
       
  1675      * @see MethodHandle#bindTo
       
  1676      */
       
  1677     public static
       
  1678     MethodHandle insertArguments(MethodHandle target, int pos, Object... values) {
       
  1679         int insCount = values.length;
       
  1680         MethodType oldType = target.type();
       
  1681         int outargs = oldType.parameterCount();
       
  1682         int inargs  = outargs - insCount;
       
  1683         if (inargs < 0)
       
  1684             throw newIllegalArgumentException("too many values to insert");
       
  1685         if (pos < 0 || pos > inargs)
       
  1686             throw newIllegalArgumentException("no argument type to append");
       
  1687         MethodHandle result = target;
       
  1688         for (int i = 0; i < insCount; i++) {
       
  1689             Object value = values[i];
       
  1690             Class<?> valueType = oldType.parameterType(pos+i);
       
  1691             value = checkValue(valueType, value);
       
  1692             if (pos == 0 && !valueType.isPrimitive()) {
       
  1693                 // At least for now, make bound method handles a special case.
       
  1694                 MethodHandle bmh = MethodHandleImpl.bindReceiver(result, value);
       
  1695                 if (bmh != null) {
       
  1696                     result = bmh;
       
  1697                     continue;
       
  1698                 }
       
  1699                 // else fall through to general adapter machinery
       
  1700             }
       
  1701             result = MethodHandleImpl.bindArgument(result, pos, value);
       
  1702         }
       
  1703         return result;
       
  1704     }
       
  1705 
       
  1706     /**
       
  1707      * Produces a method handle which calls the original method handle,
       
  1708      * after dropping the given argument(s) at the given position.
       
  1709      * The type of the new method handle will insert the given argument
       
  1710      * type(s), at that position, into the original handle's type.
       
  1711      * <p>
       
  1712      * The <i>pos</i> may range between zero and <i>N</i>,
       
  1713      * where <i>N</i> is the number of argument types in <i>target</i>,
       
  1714      * meaning to drop the first or last argument (respectively),
       
  1715      * or an argument somewhere in between.
       
  1716      * <p>
       
  1717      * <b>Example:</b>
       
  1718      * <p><blockquote><pre>
       
  1719 import static java.lang.invoke.MethodHandles.*;
       
  1720 import static java.lang.invoke.MethodType.*;
       
  1721 ...
       
  1722 MethodHandle cat = lookup().findVirtual(String.class,
       
  1723   "concat", methodType(String.class, String.class));
       
  1724 assertEquals("xy", (String) cat.invokeExact("x", "y"));
       
  1725 MethodType bigType = cat.type().insertParameterTypes(0, int.class, String.class);
       
  1726 MethodHandle d0 = dropArguments(cat, 0, bigType.parameterList().subList(0,2));
       
  1727 assertEquals(bigType, d0.type());
       
  1728 assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));
       
  1729      * </pre></blockquote>
       
  1730      * <p>
       
  1731      * This method is also equivalent to the following code:
       
  1732      * <p><blockquote><pre>
       
  1733      * {@link #dropArguments(MethodHandle,int,Class...) dropArguments}(target, pos, valueTypes.toArray(new Class[0]))
       
  1734      * </pre></blockquote>
       
  1735      * @param target the method handle to invoke after the arguments are dropped
       
  1736      * @param valueTypes the type(s) of the argument(s) to drop
       
  1737      * @param pos position of first argument to drop (zero for the leftmost)
       
  1738      * @return a method handle which drops arguments of the given types,
       
  1739      *         before calling the original method handle
       
  1740      * @throws NullPointerException if the {@code target} argument is null,
       
  1741      *                              or if the {@code valueTypes} list or any of its elements is null
       
  1742      * @throws IllegalArgumentException if any of the {@code valueTypes} is {@code void.class}
       
  1743      */
       
  1744     public static
       
  1745     MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) {
       
  1746         if (valueTypes.size() == 0)  return target;
       
  1747         MethodType oldType = target.type();
       
  1748         int outargs = oldType.parameterCount();
       
  1749         int inargs  = outargs + valueTypes.size();
       
  1750         if (pos < 0 || pos >= inargs)
       
  1751             throw newIllegalArgumentException("no argument type to remove");
       
  1752         ArrayList<Class<?>> ptypes =
       
  1753                 new ArrayList<Class<?>>(oldType.parameterList());
       
  1754         ptypes.addAll(pos, valueTypes);
       
  1755         MethodType newType = MethodType.methodType(oldType.returnType(), ptypes);
       
  1756         return MethodHandleImpl.dropArguments(target, newType, pos);
       
  1757     }
       
  1758 
       
  1759     /**
       
  1760      * Produces a method handle which calls the original method handle,
       
  1761      * after dropping the given argument(s) at the given position.
       
  1762      * The type of the new method handle will insert the given argument
       
  1763      * type(s), at that position, into the original handle's type.
       
  1764      * <p>
       
  1765      * The <i>pos</i> may range between zero and <i>N</i>,
       
  1766      * where <i>N</i> is the number of argument types in <i>target</i>,
       
  1767      * meaning to drop the first or last argument (respectively),
       
  1768      * or an argument somewhere in between.
       
  1769      * <p>
       
  1770      * <b>Example:</b>
       
  1771      * <p><blockquote><pre>
       
  1772 import static java.lang.invoke.MethodHandles.*;
       
  1773 import static java.lang.invoke.MethodType.*;
       
  1774 ...
       
  1775 MethodHandle cat = lookup().findVirtual(String.class,
       
  1776   "concat", methodType(String.class, String.class));
       
  1777 assertEquals("xy", (String) cat.invokeExact("x", "y"));
       
  1778 MethodHandle d0 = dropArguments(cat, 0, String.class);
       
  1779 assertEquals("yz", (String) d0.invokeExact("x", "y", "z"));
       
  1780 MethodHandle d1 = dropArguments(cat, 1, String.class);
       
  1781 assertEquals("xz", (String) d1.invokeExact("x", "y", "z"));
       
  1782 MethodHandle d2 = dropArguments(cat, 2, String.class);
       
  1783 assertEquals("xy", (String) d2.invokeExact("x", "y", "z"));
       
  1784 MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class);
       
  1785 assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
       
  1786      * </pre></blockquote>
       
  1787      * <p>
       
  1788      * This method is also equivalent to the following code:
       
  1789      * <p><blockquote><pre>
       
  1790      * {@link #dropArguments(MethodHandle,int,List) dropArguments}(target, pos, Arrays.asList(valueTypes))
       
  1791      * </pre></blockquote>
       
  1792      * @param target the method handle to invoke after the arguments are dropped
       
  1793      * @param valueTypes the type(s) of the argument(s) to drop
       
  1794      * @param pos position of first argument to drop (zero for the leftmost)
       
  1795      * @return a method handle which drops arguments of the given types,
       
  1796      *         before calling the original method handle
       
  1797      * @throws NullPointerException if the {@code target} argument is null,
       
  1798      *                              or if the {@code valueTypes} array or any of its elements is null
       
  1799      * @throws IllegalArgumentException if any of the {@code valueTypes} is {@code void.class}
       
  1800      */
       
  1801     public static
       
  1802     MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes) {
       
  1803         return dropArguments(target, pos, Arrays.asList(valueTypes));
       
  1804     }
       
  1805 
       
  1806     /**
       
  1807      * Adapts a target method handle {@code target} by pre-processing
       
  1808      * one or more of its arguments, each with its own unary filter function,
       
  1809      * and then calling the target with each pre-processed argument
       
  1810      * replaced by the result of its corresponding filter function.
       
  1811      * <p>
       
  1812      * The pre-processing is performed by one or more method handles,
       
  1813      * specified in the elements of the {@code filters} array.
       
  1814      * Null arguments in the array are ignored, and the corresponding arguments left unchanged.
       
  1815      * (If there are no non-null elements in the array, the original target is returned.)
       
  1816      * Each filter is applied to the corresponding argument of the adapter.
       
  1817      * <p>
       
  1818      * If a filter {@code F} applies to the {@code N}th argument of
       
  1819      * the method handle, then {@code F} must be a method handle which
       
  1820      * takes exactly one argument.  The type of {@code F}'s sole argument
       
  1821      * replaces the corresponding argument type of the target
       
  1822      * in the resulting adapted method handle.
       
  1823      * The return type of {@code F} must be identical to the corresponding
       
  1824      * parameter type of the target.
       
  1825      * <p>
       
  1826      * It is an error if there are elements of {@code filters}
       
  1827      * which do not correspond to argument positions in the target.
       
  1828      * <b>Example:</b>
       
  1829      * <p><blockquote><pre>
       
  1830 import static java.lang.invoke.MethodHandles.*;
       
  1831 import static java.lang.invoke.MethodType.*;
       
  1832 ...
       
  1833 MethodHandle cat = lookup().findVirtual(String.class,
       
  1834   "concat", methodType(String.class, String.class));
       
  1835 MethodHandle upcase = lookup().findVirtual(String.class,
       
  1836   "toUpperCase", methodType(String.class));
       
  1837 assertEquals("xy", (String) cat.invokeExact("x", "y"));
       
  1838 MethodHandle f0 = filterArguments(cat, 0, upcase);
       
  1839 assertEquals("Xy", (String) f0.invokeExact("x", "y")); // Xy
       
  1840 MethodHandle f1 = filterArguments(cat, 1, upcase);
       
  1841 assertEquals("xY", (String) f1.invokeExact("x", "y")); // xY
       
  1842 MethodHandle f2 = filterArguments(cat, 0, upcase, upcase);
       
  1843 assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
       
  1844      * </pre></blockquote>
       
  1845      *
       
  1846      * @param target the method handle to invoke after arguments are filtered
       
  1847      * @param pos the position of the first argument to filter
       
  1848      * @param filters method handles to call initially on filtered arguments
       
  1849      * @return method handle which incorporates the specified argument filtering logic
       
  1850      * @throws NullPointerException if the {@code target} argument is null
       
  1851      *                              or if the {@code filters} array is null
       
  1852      * @throws IllegalArgumentException if a non-null element of {@code filters}
       
  1853      *          does not match a corresponding argument type of {@code target} as described above,
       
  1854      *          or if the {@code pos+filters.length} is greater than {@code target.type().parameterCount()}
       
  1855      */
       
  1856     public static
       
  1857     MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters) {
       
  1858         MethodType targetType = target.type();
       
  1859         MethodHandle adapter = target;
       
  1860         MethodType adapterType = targetType;
       
  1861         int maxPos = targetType.parameterCount();
       
  1862         if (pos + filters.length > maxPos)
       
  1863             throw newIllegalArgumentException("too many filters");
       
  1864         int curPos = pos-1;  // pre-incremented
       
  1865         for (MethodHandle filter : filters) {
       
  1866             curPos += 1;
       
  1867             if (filter == null)  continue;  // ignore null elements of filters
       
  1868             MethodType filterType = filter.type();
       
  1869             if (filterType.parameterCount() != 1
       
  1870                 || filterType.returnType() != targetType.parameterType(curPos))
       
  1871                 throw newIllegalArgumentException("target and filter types do not match");
       
  1872             adapterType = adapterType.changeParameterType(curPos, filterType.parameterType(0));
       
  1873             adapter = MethodHandleImpl.filterArgument(adapter, curPos, filter);
       
  1874         }
       
  1875         MethodType midType = adapter.type();
       
  1876         if (midType != adapterType)
       
  1877             adapter = MethodHandleImpl.convertArguments(adapter, adapterType, midType, null);
       
  1878         return adapter;
       
  1879     }
       
  1880 
       
  1881     /**
       
  1882      * Adapts a target method handle {@code target} by post-processing
       
  1883      * its return value with a unary filter function.
       
  1884      * <p>
       
  1885      * If a filter {@code F} applies to the return value of
       
  1886      * the target method handle, then {@code F} must be a method handle which
       
  1887      * takes exactly one argument.  The return type of {@code F}
       
  1888      * replaces the return type of the target
       
  1889      * in the resulting adapted method handle.
       
  1890      * The argument type of {@code F} must be identical to the
       
  1891      * return type of the target.
       
  1892      * <b>Example:</b>
       
  1893      * <p><blockquote><pre>
       
  1894 import static java.lang.invoke.MethodHandles.*;
       
  1895 import static java.lang.invoke.MethodType.*;
       
  1896 ...
       
  1897 MethodHandle cat = lookup().findVirtual(String.class,
       
  1898   "concat", methodType(String.class, String.class));
       
  1899 MethodHandle length = lookup().findVirtual(String.class,
       
  1900   "length", methodType(int.class));
       
  1901 System.out.println((String) cat.invokeExact("x", "y")); // xy
       
  1902 MethodHandle f0 = filterReturnValue(cat, length);
       
  1903 System.out.println((int) f0.invokeExact("x", "y")); // 2
       
  1904      * </pre></blockquote>
       
  1905      * @param target the method handle to invoke before filtering the return value
       
  1906      * @param filter method handle to call on the return value
       
  1907      * @return method handle which incorporates the specified return value filtering logic
       
  1908      * @throws NullPointerException if either argument is null
       
  1909      * @throws IllegalArgumentException if {@code filter}
       
  1910      *          does not match the return type of {@code target} as described above
       
  1911      */
       
  1912     public static
       
  1913     MethodHandle filterReturnValue(MethodHandle target, MethodHandle filter) {
       
  1914         MethodType targetType = target.type();
       
  1915         MethodType filterType = filter.type();
       
  1916         if (filterType.parameterCount() != 1
       
  1917             || filterType.parameterType(0) != targetType.returnType())
       
  1918             throw newIllegalArgumentException("target and filter types do not match");
       
  1919         // result = fold( lambda(retval, arg...) { filter(retval) },
       
  1920         //                lambda(        arg...) { target(arg...) } )
       
  1921         // FIXME: Too many nodes here.
       
  1922         MethodHandle returner = dropArguments(filter, 1, targetType.parameterList());
       
  1923         return foldArguments(returner, target);
       
  1924     }
       
  1925 
       
  1926     /**
       
  1927      * Adapts a target method handle {@code target} by pre-processing
       
  1928      * some of its arguments, and then calling the target with
       
  1929      * the result of the pre-processing, plus all original arguments.
       
  1930      * <p>
       
  1931      * The pre-processing is performed by a second method handle, the {@code combiner}.
       
  1932      * The first {@code N} arguments passed to the adapter,
       
  1933      * are copied to the combiner, which then produces a result.
       
  1934      * (Here, {@code N} is defined as the parameter count of the adapter.)
       
  1935      * After this, control passes to the {@code target}, with both the result
       
  1936      * of the combiner, and all the original incoming arguments.
       
  1937      * <p>
       
  1938      * The first argument type of the target must be identical with the
       
  1939      * return type of the combiner.
       
  1940      * The resulting adapter is the same type as the target, except that the
       
  1941      * initial argument type of the target is dropped.
       
  1942      * <p>
       
  1943      * (Note that {@link #dropArguments(MethodHandle,int,List) dropArguments} can be used to remove any arguments
       
  1944      * that either the {@code combiner} or {@code target} does not wish to receive.
       
  1945      * If some of the incoming arguments are destined only for the combiner,
       
  1946      * consider using {@link MethodHandle#asCollector asCollector} instead, since those
       
  1947      * arguments will not need to be live on the stack on entry to the
       
  1948      * target.)
       
  1949      * <p>
       
  1950      * The first argument of the target must be identical with the
       
  1951      * return value of the combiner.
       
  1952      * <p> Here is pseudocode for the resulting adapter:
       
  1953      * <blockquote><pre>
       
  1954      * // there are N arguments in the A sequence
       
  1955      * T target(V, A[N]..., B...);
       
  1956      * V combiner(A...);
       
  1957      * T adapter(A... a, B... b) {
       
  1958      *   V v = combiner(a...);
       
  1959      *   return target(v, a..., b...);
       
  1960      * }
       
  1961      * </pre></blockquote>
       
  1962      * @param target the method handle to invoke after arguments are combined
       
  1963      * @param combiner method handle to call initially on the incoming arguments
       
  1964      * @return method handle which incorporates the specified argument folding logic
       
  1965      * @throws NullPointerException if either argument is null
       
  1966      * @throws IllegalArgumentException if the first argument type of
       
  1967      *          {@code target} is not the same as {@code combiner}'s return type,
       
  1968      *          or if the following argument types of {@code target}
       
  1969      *          are not identical with the argument types of {@code combiner}
       
  1970      */
       
  1971     public static
       
  1972     MethodHandle foldArguments(MethodHandle target, MethodHandle combiner) {
       
  1973         MethodType targetType = target.type();
       
  1974         MethodType combinerType = combiner.type();
       
  1975         int foldArgs = combinerType.parameterCount();
       
  1976         boolean ok = (targetType.parameterCount() >= 1 + foldArgs);
       
  1977         if (ok && !combinerType.parameterList().equals(targetType.parameterList().subList(1, foldArgs+1)))
       
  1978             ok = false;
       
  1979         if (ok && !combinerType.returnType().equals(targetType.parameterType(0)))
       
  1980             ok = false;
       
  1981         if (!ok)
       
  1982             throw misMatchedTypes("target and combiner types", targetType, combinerType);
       
  1983         MethodType newType = targetType.dropParameterTypes(0, 1);
       
  1984         return MethodHandleImpl.foldArguments(target, newType, combiner);
       
  1985     }
       
  1986 
       
  1987     /**
       
  1988      * Makes a method handle which adapts a target method handle,
       
  1989      * by guarding it with a test, a boolean-valued method handle.
       
  1990      * If the guard fails, a fallback handle is called instead.
       
  1991      * All three method handles must have the same corresponding
       
  1992      * argument and return types, except that the return type
       
  1993      * of the test must be boolean, and the test is allowed
       
  1994      * to have fewer arguments than the other two method handles.
       
  1995      * <p> Here is pseudocode for the resulting adapter:
       
  1996      * <blockquote><pre>
       
  1997      * boolean test(A...);
       
  1998      * T target(A...,B...);
       
  1999      * T fallback(A...,B...);
       
  2000      * T adapter(A... a,B... b) {
       
  2001      *   if (test(a...))
       
  2002      *     return target(a..., b...);
       
  2003      *   else
       
  2004      *     return fallback(a..., b...);
       
  2005      * }
       
  2006      * </pre></blockquote>
       
  2007      * Note that the test arguments ({@code a...} in the pseudocode) cannot
       
  2008      * be modified by execution of the test, and so are passed unchanged
       
  2009      * from the caller to the target or fallback as appropriate.
       
  2010      * @param test method handle used for test, must return boolean
       
  2011      * @param target method handle to call if test passes
       
  2012      * @param fallback method handle to call if test fails
       
  2013      * @return method handle which incorporates the specified if/then/else logic
       
  2014      * @throws NullPointerException if any argument is null
       
  2015      * @throws IllegalArgumentException if {@code test} does not return boolean,
       
  2016      *          or if all three method types do not match (with the return
       
  2017      *          type of {@code test} changed to match that of {@code target}).
       
  2018      */
       
  2019     public static
       
  2020     MethodHandle guardWithTest(MethodHandle test,
       
  2021                                MethodHandle target,
       
  2022                                MethodHandle fallback) {
       
  2023         MethodType gtype = test.type();
       
  2024         MethodType ttype = target.type();
       
  2025         MethodType ftype = fallback.type();
       
  2026         if (!ttype.equals(ftype))
       
  2027             throw misMatchedTypes("target and fallback types", ttype, ftype);
       
  2028         if (gtype.returnType() != boolean.class)
       
  2029             throw newIllegalArgumentException("guard type is not a predicate "+gtype);
       
  2030         List<Class<?>> targs = ttype.parameterList();
       
  2031         List<Class<?>> gargs = gtype.parameterList();
       
  2032         if (!targs.equals(gargs)) {
       
  2033             int gpc = gargs.size(), tpc = targs.size();
       
  2034             if (gpc >= tpc || !targs.subList(0, gpc).equals(gargs))
       
  2035                 throw misMatchedTypes("target and test types", ttype, gtype);
       
  2036             test = dropArguments(test, gpc, targs.subList(gpc, tpc));
       
  2037             gtype = test.type();
       
  2038         }
       
  2039         return MethodHandleImpl.makeGuardWithTest(test, target, fallback);
       
  2040     }
       
  2041 
       
  2042     static RuntimeException misMatchedTypes(String what, MethodType t1, MethodType t2) {
       
  2043         return newIllegalArgumentException(what + " must match: " + t1 + " != " + t2);
       
  2044     }
       
  2045 
       
  2046     /**
       
  2047      * Makes a method handle which adapts a target method handle,
       
  2048      * by running it inside an exception handler.
       
  2049      * If the target returns normally, the adapter returns that value.
       
  2050      * If an exception matching the specified type is thrown, the fallback
       
  2051      * handle is called instead on the exception, plus the original arguments.
       
  2052      * <p>
       
  2053      * The target and handler must have the same corresponding
       
  2054      * argument and return types, except that handler may omit trailing arguments
       
  2055      * (similarly to the predicate in {@link #guardWithTest guardWithTest}).
       
  2056      * Also, the handler must have an extra leading parameter of {@code exType} or a supertype.
       
  2057      * <p> Here is pseudocode for the resulting adapter:
       
  2058      * <blockquote><pre>
       
  2059      * T target(A..., B...);
       
  2060      * T handler(ExType, A...);
       
  2061      * T adapter(A... a, B... b) {
       
  2062      *   try {
       
  2063      *     return target(a..., b...);
       
  2064      *   } catch (ExType ex) {
       
  2065      *     return handler(ex, a...);
       
  2066      *   }
       
  2067      * }
       
  2068      * </pre></blockquote>
       
  2069      * Note that the saved arguments ({@code a...} in the pseudocode) cannot
       
  2070      * be modified by execution of the target, and so are passed unchanged
       
  2071      * from the caller to the handler, if the handler is invoked.
       
  2072      * <p>
       
  2073      * The target and handler must return the same type, even if the handler
       
  2074      * always throws.  (This might happen, for instance, because the handler
       
  2075      * is simulating a {@code finally} clause).
       
  2076      * To create such a throwing handler, compose the handler creation logic
       
  2077      * with {@link #throwException throwException},
       
  2078      * in order to create a method handle of the correct return type.
       
  2079      * @param target method handle to call
       
  2080      * @param exType the type of exception which the handler will catch
       
  2081      * @param handler method handle to call if a matching exception is thrown
       
  2082      * @return method handle which incorporates the specified try/catch logic
       
  2083      * @throws NullPointerException if any argument is null
       
  2084      * @throws IllegalArgumentException if {@code handler} does not accept
       
  2085      *          the given exception type, or if the method handle types do
       
  2086      *          not match in their return types and their
       
  2087      *          corresponding parameters
       
  2088      */
       
  2089     public static
       
  2090     MethodHandle catchException(MethodHandle target,
       
  2091                                 Class<? extends Throwable> exType,
       
  2092                                 MethodHandle handler) {
       
  2093         MethodType ttype = target.type();
       
  2094         MethodType htype = handler.type();
       
  2095         if (htype.parameterCount() < 1 ||
       
  2096             !htype.parameterType(0).isAssignableFrom(exType))
       
  2097             throw newIllegalArgumentException("handler does not accept exception type "+exType);
       
  2098         if (htype.returnType() != ttype.returnType())
       
  2099             throw misMatchedTypes("target and handler return types", ttype, htype);
       
  2100         List<Class<?>> targs = ttype.parameterList();
       
  2101         List<Class<?>> hargs = htype.parameterList();
       
  2102         hargs = hargs.subList(1, hargs.size());  // omit leading parameter from handler
       
  2103         if (!targs.equals(hargs)) {
       
  2104             int hpc = hargs.size(), tpc = targs.size();
       
  2105             if (hpc >= tpc || !targs.subList(0, hpc).equals(hargs))
       
  2106                 throw misMatchedTypes("target and handler types", ttype, htype);
       
  2107             handler = dropArguments(handler, hpc, hargs.subList(hpc, tpc));
       
  2108             htype = handler.type();
       
  2109         }
       
  2110         return MethodHandleImpl.makeGuardWithCatch(target, exType, handler);
       
  2111     }
       
  2112 
       
  2113     /**
       
  2114      * Produces a method handle which will throw exceptions of the given {@code exType}.
       
  2115      * The method handle will accept a single argument of {@code exType},
       
  2116      * and immediately throw it as an exception.
       
  2117      * The method type will nominally specify a return of {@code returnType}.
       
  2118      * The return type may be anything convenient:  It doesn't matter to the
       
  2119      * method handle's behavior, since it will never return normally.
       
  2120      * @return method handle which can throw the given exceptions
       
  2121      * @throws NullPointerException if either argument is null
       
  2122      */
       
  2123     public static
       
  2124     MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType) {
       
  2125         return MethodHandleImpl.throwException(MethodType.methodType(returnType, exType));
       
  2126     }
       
  2127 
       
  2128     /**
       
  2129      * Produces an instance of the given single-method interface which redirects
       
  2130      * its calls to the given method handle.
       
  2131      * <p>
       
  2132      * A single-method interface is an interface which declares a unique method.
       
  2133      * When determining the unique method of a single-method interface,
       
  2134      * the public {@code Object} methods ({@code toString}, {@code equals}, {@code hashCode})
       
  2135      * are disregarded.  For example, {@link java.util.Comparator} is a single-method interface,
       
  2136      * even though it re-declares the {@code Object.equals} method.
       
  2137      * <p>
       
  2138      * The type must be public.  No additional access checks are performed.
       
  2139      * <p>
       
  2140      * The resulting instance of the required type will respond to
       
  2141      * invocation of the type's single abstract method by calling
       
  2142      * the given {@code target} on the incoming arguments,
       
  2143      * and returning or throwing whatever the {@code target}
       
  2144      * returns or throws.  The invocation will be as if by
       
  2145      * {@code target.invokeGeneric}.
       
  2146      * The target's type will be checked before the
       
  2147      * instance is created, as if by a call to {@code asType},
       
  2148      * which may result in a {@code WrongMethodTypeException}.
       
  2149      * <p>
       
  2150      * The wrapper instance will implement the requested interface
       
  2151      * and its super-types, but no other single-method interfaces.
       
  2152      * This means that the instance will not unexpectedly
       
  2153      * pass an {@code instanceof} test for any unrequested type.
       
  2154      * <p style="font-size:smaller;">
       
  2155      * <em>Implementation Note:</em>
       
  2156      * Therefore, each instance must implement a unique single-method interface.
       
  2157      * Implementations may not bundle together
       
  2158      * multiple single-method interfaces onto single implementation classes
       
  2159      * in the style of {@link java.awt.AWTEventMulticaster}.
       
  2160      * <p>
       
  2161      * The method handle may throw an <em>undeclared exception</em>,
       
  2162      * which means any checked exception (or other checked throwable)
       
  2163      * not declared by the requested type's single abstract method.
       
  2164      * If this happens, the throwable will be wrapped in an instance of
       
  2165      * {@link java.lang.reflect.UndeclaredThrowableException UndeclaredThrowableException}
       
  2166      * and thrown in that wrapped form.
       
  2167      * <p>
       
  2168      * Like {@link java.lang.Integer#valueOf Integer.valueOf},
       
  2169      * {@code asInstance} is a factory method whose results are defined
       
  2170      * by their behavior.
       
  2171      * It is not guaranteed to return a new instance for every call.
       
  2172      * <p>
       
  2173      * Because of the possibility of {@linkplain java.lang.reflect.Method#isBridge bridge methods}
       
  2174      * and other corner cases, the interface may also have several abstract methods
       
  2175      * with the same name but having distinct descriptors (types of returns and parameters).
       
  2176      * In this case, all the methods are bound in common to the one given {@code target}.
       
  2177      * The type check and effective {@code asType} conversion is applied to each
       
  2178      * method type descriptor, and all abstract methods are bound to the {@code target} in common.
       
  2179      * Beyond this type check, no further checks are made to determine that the
       
  2180      * abstract methods are related in any way.
       
  2181      * <p>
       
  2182      * Future versions of this API may accept additional types,
       
  2183      * such as abstract classes with single abstract methods.
       
  2184      * Future versions of this API may also equip wrapper instances
       
  2185      * with one or more additional public "marker" interfaces.
       
  2186      *
       
  2187      * @param target the method handle to invoke from the wrapper
       
  2188      * @param smType the desired type of the wrapper, a single-method interface
       
  2189      * @return a correctly-typed wrapper for the given {@code target}
       
  2190      * @throws NullPointerException if either argument is null
       
  2191      * @throws IllegalArgumentException if the {@code smType} is not a
       
  2192      *         valid argument to this method
       
  2193      * @throws WrongMethodTypeException if the {@code target} cannot
       
  2194      *         be converted to the type required by the requested interface
       
  2195      */
       
  2196     // Other notes to implementors:
       
  2197     // <p>
       
  2198     // No stable mapping is promised between the single-method interface and
       
  2199     // the implementation class C.  Over time, several implementation
       
  2200     // classes might be used for the same type.
       
  2201     // <p>
       
  2202     // If the implementation is able
       
  2203     // to prove that a wrapper of the required type
       
  2204     // has already been created for a given
       
  2205     // method handle, or for another method handle with the
       
  2206     // same behavior, the implementation may return that wrapper in place of
       
  2207     // a new wrapper.
       
  2208     // <p>
       
  2209     // This method is designed to apply to common use cases
       
  2210     // where a single method handle must interoperate with
       
  2211     // an interface that implements a function-like
       
  2212     // API.  Additional variations, such as single-abstract-method classes with
       
  2213     // private constructors, or interfaces with multiple but related
       
  2214     // entry points, must be covered by hand-written or automatically
       
  2215     // generated adapter classes.
       
  2216     //
       
  2217     public static
       
  2218     <T> T asInstance(final MethodHandle target, final Class<T> smType) {
       
  2219         // POC implementation only; violates the above contract several ways
       
  2220         final Method sm = getSingleMethod(smType);
       
  2221         if (sm == null)
       
  2222             throw new IllegalArgumentException("not a single-method interface: "+smType.getName());
       
  2223         MethodType smMT = MethodType.methodType(sm.getReturnType(), sm.getParameterTypes());
       
  2224         MethodHandle checkTarget = target.asType(smMT);  // make throw WMT
       
  2225         checkTarget = checkTarget.asType(checkTarget.type().changeReturnType(Object.class));
       
  2226         final MethodHandle vaTarget = checkTarget.asSpreader(Object[].class, smMT.parameterCount());
       
  2227         return smType.cast(Proxy.newProxyInstance(
       
  2228                 smType.getClassLoader(),
       
  2229                 new Class[]{ smType, WrapperInstance.class },
       
  2230                 new InvocationHandler() {
       
  2231                     private Object getArg(String name) {
       
  2232                         if ((Object)name == "getWrapperInstanceTarget")  return target;
       
  2233                         if ((Object)name == "getWrapperInstanceType")    return smType;
       
  2234                         throw new AssertionError();
       
  2235                     }
       
  2236                     public Object invoke(Object proxy, Method method, Object[] args) throws Throwable {
       
  2237                         if (method.getDeclaringClass() == WrapperInstance.class)
       
  2238                             return getArg(method.getName());
       
  2239                         if (method.equals(sm))
       
  2240                             return vaTarget.invokeExact(args);
       
  2241                         if (isObjectMethod(method))
       
  2242                             return callObjectMethod(this, method, args);
       
  2243                         throw new InternalError();
       
  2244                     }
       
  2245                 }));
       
  2246     }
       
  2247 
       
  2248     /**
       
  2249      * Determines if the given object was produced by a call to {@link #asInstance asInstance}.
       
  2250      * @param x any reference
       
  2251      * @return true if the reference is not null and points to an object produced by {@code asInstance}
       
  2252      */
       
  2253     public static
       
  2254     boolean isWrapperInstance(Object x) {
       
  2255         return x instanceof WrapperInstance;
       
  2256     }
       
  2257 
       
  2258     private static WrapperInstance asWrapperInstance(Object x) {
       
  2259         try {
       
  2260             if (x != null)
       
  2261                 return (WrapperInstance) x;
       
  2262         } catch (ClassCastException ex) {
       
  2263         }
       
  2264         throw new IllegalArgumentException("not a wrapper instance");
       
  2265     }
       
  2266 
       
  2267     /**
       
  2268      * Produces or recovers a target method handle which is behaviorally
       
  2269      * equivalent to the unique method of this wrapper instance.
       
  2270      * The object {@code x} must have been produced by a call to {@link #asInstance asInstance}.
       
  2271      * This requirement may be tested via {@link #isWrapperInstance isWrapperInstance}.
       
  2272      * @param x any reference
       
  2273      * @return a method handle implementing the unique method
       
  2274      * @throws IllegalArgumentException if the reference x is not to a wrapper instance
       
  2275      */
       
  2276     public static
       
  2277     MethodHandle wrapperInstanceTarget(Object x) {
       
  2278         return asWrapperInstance(x).getWrapperInstanceTarget();
       
  2279     }
       
  2280 
       
  2281     /**
       
  2282      * Recovers the unique single-method interface type for which this wrapper instance was created.
       
  2283      * The object {@code x} must have been produced by a call to {@link #asInstance asInstance}.
       
  2284      * This requirement may be tested via {@link #isWrapperInstance isWrapperInstance}.
       
  2285      * @param x any reference
       
  2286      * @return the single-method interface type for which the wrapper was created
       
  2287      * @throws IllegalArgumentException if the reference x is not to a wrapper instance
       
  2288      */
       
  2289     public static
       
  2290     Class<?> wrapperInstanceType(Object x) {
       
  2291         return asWrapperInstance(x).getWrapperInstanceType();
       
  2292     }
       
  2293 
       
  2294     private static
       
  2295     boolean isObjectMethod(Method m) {
       
  2296         switch (m.getName()) {
       
  2297         case "toString":
       
  2298             return (m.getReturnType() == String.class
       
  2299                     && m.getParameterTypes().length == 0);
       
  2300         case "hashCode":
       
  2301             return (m.getReturnType() == int.class
       
  2302                     && m.getParameterTypes().length == 0);
       
  2303         case "equals":
       
  2304             return (m.getReturnType() == boolean.class
       
  2305                     && m.getParameterTypes().length == 1
       
  2306                     && m.getParameterTypes()[0] == Object.class);
       
  2307         }
       
  2308         return false;
       
  2309     }
       
  2310 
       
  2311     private static
       
  2312     Object callObjectMethod(Object self, Method m, Object[] args) {
       
  2313         assert(isObjectMethod(m)) : m;
       
  2314         switch (m.getName()) {
       
  2315         case "toString":
       
  2316             return self.getClass().getName() + "@" + Integer.toHexString(self.hashCode());
       
  2317         case "hashCode":
       
  2318             return System.identityHashCode(self);
       
  2319         case "equals":
       
  2320             return (self == args[0]);
       
  2321         }
       
  2322         return null;
       
  2323     }
       
  2324 
       
  2325     private static
       
  2326     Method getSingleMethod(Class<?> smType) {
       
  2327         Method sm = null;
       
  2328         for (Method m : smType.getMethods()) {
       
  2329             int mod = m.getModifiers();
       
  2330             if (Modifier.isAbstract(mod)) {
       
  2331                 if (sm != null && !isObjectMethod(sm))
       
  2332                     return null;  // too many abstract methods
       
  2333                 sm = m;
       
  2334             }
       
  2335         }
       
  2336         if (!smType.isInterface() && getSingleConstructor(smType) == null)
       
  2337             return null;  // wrong kind of constructor
       
  2338         return sm;
       
  2339     }
       
  2340 
       
  2341     private static
       
  2342     Constructor getSingleConstructor(Class<?> smType) {
       
  2343         for (Constructor c : smType.getDeclaredConstructors()) {
       
  2344             if (c.getParameterTypes().length == 0) {
       
  2345                 int mod = c.getModifiers();
       
  2346                 if (Modifier.isPublic(mod) || Modifier.isProtected(mod))
       
  2347                     return c;
       
  2348             }
       
  2349         }
       
  2350         return null;
       
  2351     }
       
  2352 
       
  2353     /*non-public*/
       
  2354     static MethodHandle asVarargsCollector(MethodHandle target, Class<?> arrayType) {
       
  2355         return MethodHandleImpl.asVarargsCollector(target, arrayType);
       
  2356     }
       
  2357 }