Home » openjdk-7 » java.lang.invoke » [javadoc | source]

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

Home » openjdk-7 » java.lang.invoke » [javadoc | source]