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