• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 /*
2  * Copyright (c) 2008, 2017, 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 java.nio.ByteOrder;
30 import java.util.List;
31 import java.util.Arrays;
32 import java.util.ArrayList;
33 import java.util.NoSuchElementException;
34 
35 import sun.invoke.util.VerifyAccess;
36 import sun.invoke.util.Wrapper;
37 import sun.reflect.Reflection;
38 
39 import static java.lang.invoke.MethodHandleStatics.*;
40 
41 /**
42  * This class consists exclusively of static methods that operate on or return
43  * method handles. They fall into several categories:
44  * <ul>
45  * <li>Lookup methods which help create method handles for methods and fields.
46  * <li>Combinator methods, which combine or transform pre-existing method handles into new ones.
47  * <li>Other factory methods to create method handles that emulate other common JVM operations or control flow patterns.
48  * </ul>
49  * <p>
50  * @author John Rose, JSR 292 EG
51  * @since 1.7
52  */
53 public class MethodHandles {
54 
MethodHandles()55     private MethodHandles() { }  // do not instantiate
56 
57     // Android-changed: We do not use MemberName / MethodHandleImpl.
58     //
59     // private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
60     // static { MethodHandleImpl.initStatics(); }
61     // See IMPL_LOOKUP below.
62 
63     //// Method handle creation from ordinary methods.
64 
65     /**
66      * Returns a {@link Lookup lookup object} with
67      * full capabilities to emulate all supported bytecode behaviors of the caller.
68      * These capabilities include <a href="MethodHandles.Lookup.html#privacc">private access</a> to the caller.
69      * Factory methods on the lookup object can create
70      * <a href="MethodHandleInfo.html#directmh">direct method handles</a>
71      * for any member that the caller has access to via bytecodes,
72      * including protected and private fields and methods.
73      * This lookup object is a <em>capability</em> which may be delegated to trusted agents.
74      * Do not store it in place where untrusted code can access it.
75      * <p>
76      * This method is caller sensitive, which means that it may return different
77      * values to different callers.
78      * <p>
79      * For any given caller class {@code C}, the lookup object returned by this call
80      * has equivalent capabilities to any lookup object
81      * supplied by the JVM to the bootstrap method of an
82      * <a href="package-summary.html#indyinsn">invokedynamic instruction</a>
83      * executing in the same caller class {@code C}.
84      * @return a lookup object for the caller of this method, with private access
85      */
86     // Android-changed: Remove caller sensitive.
87     // @CallerSensitive
lookup()88     public static Lookup lookup() {
89         return new Lookup(Reflection.getCallerClass());
90     }
91 
92     /**
93      * Returns a {@link Lookup lookup object} which is trusted minimally.
94      * It can only be used to create method handles to
95      * publicly accessible fields and methods.
96      * <p>
97      * As a matter of pure convention, the {@linkplain Lookup#lookupClass lookup class}
98      * of this lookup object will be {@link java.lang.Object}.
99      *
100      * <p style="font-size:smaller;">
101      * <em>Discussion:</em>
102      * The lookup class can be changed to any other class {@code C} using an expression of the form
103      * {@link Lookup#in publicLookup().in(C.class)}.
104      * Since all classes have equal access to public names,
105      * such a change would confer no new access rights.
106      * A public lookup object is always subject to
107      * <a href="MethodHandles.Lookup.html#secmgr">security manager checks</a>.
108      * Also, it cannot access
109      * <a href="MethodHandles.Lookup.html#callsens">caller sensitive methods</a>.
110      * @return a lookup object which is trusted minimally
111      */
publicLookup()112     public static Lookup publicLookup() {
113         return Lookup.PUBLIC_LOOKUP;
114     }
115 
116     /**
117      * Performs an unchecked "crack" of a
118      * <a href="MethodHandleInfo.html#directmh">direct method handle</a>.
119      * The result is as if the user had obtained a lookup object capable enough
120      * to crack the target method handle, called
121      * {@link java.lang.invoke.MethodHandles.Lookup#revealDirect Lookup.revealDirect}
122      * on the target to obtain its symbolic reference, and then called
123      * {@link java.lang.invoke.MethodHandleInfo#reflectAs MethodHandleInfo.reflectAs}
124      * to resolve the symbolic reference to a member.
125      * <p>
126      * If there is a security manager, its {@code checkPermission} method
127      * is called with a {@code ReflectPermission("suppressAccessChecks")} permission.
128      * @param <T> the desired type of the result, either {@link Member} or a subtype
129      * @param target a direct method handle to crack into symbolic reference components
130      * @param expected a class object representing the desired result type {@code T}
131      * @return a reference to the method, constructor, or field object
132      * @exception SecurityException if the caller is not privileged to call {@code setAccessible}
133      * @exception NullPointerException if either argument is {@code null}
134      * @exception IllegalArgumentException if the target is not a direct method handle
135      * @exception ClassCastException if the member is not of the expected type
136      * @since 1.8
137      */
138     public static <T extends Member> T
reflectAs(Class<T> expected, MethodHandle target)139     reflectAs(Class<T> expected, MethodHandle target) {
140         MethodHandleImpl directTarget = getMethodHandleImpl(target);
141         // Given that this is specified to be an "unchecked" crack, we can directly allocate
142         // a member from the underlying ArtField / Method and bypass all associated access checks.
143         return expected.cast(directTarget.getMemberInternal());
144     }
145 
146     /**
147      * A <em>lookup object</em> is a factory for creating method handles,
148      * when the creation requires access checking.
149      * Method handles do not perform
150      * access checks when they are called, but rather when they are created.
151      * Therefore, method handle access
152      * restrictions must be enforced when a method handle is created.
153      * The caller class against which those restrictions are enforced
154      * is known as the {@linkplain #lookupClass lookup class}.
155      * <p>
156      * A lookup class which needs to create method handles will call
157      * {@link #lookup MethodHandles.lookup} to create a factory for itself.
158      * When the {@code Lookup} factory object is created, the identity of the lookup class is
159      * determined, and securely stored in the {@code Lookup} object.
160      * The lookup class (or its delegates) may then use factory methods
161      * on the {@code Lookup} object to create method handles for access-checked members.
162      * This includes all methods, constructors, and fields which are allowed to the lookup class,
163      * even private ones.
164      *
165      * <h1><a name="lookups"></a>Lookup Factory Methods</h1>
166      * The factory methods on a {@code Lookup} object correspond to all major
167      * use cases for methods, constructors, and fields.
168      * Each method handle created by a factory method is the functional
169      * equivalent of a particular <em>bytecode behavior</em>.
170      * (Bytecode behaviors are described in section 5.4.3.5 of the Java Virtual Machine Specification.)
171      * Here is a summary of the correspondence between these factory methods and
172      * the behavior the resulting method handles:
173      * <table border=1 cellpadding=5 summary="lookup method behaviors">
174      * <tr>
175      *     <th><a name="equiv"></a>lookup expression</th>
176      *     <th>member</th>
177      *     <th>bytecode behavior</th>
178      * </tr>
179      * <tr>
180      *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}</td>
181      *     <td>{@code FT f;}</td><td>{@code (T) this.f;}</td>
182      * </tr>
183      * <tr>
184      *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findStaticGetter lookup.findStaticGetter(C.class,"f",FT.class)}</td>
185      *     <td>{@code static}<br>{@code FT f;}</td><td>{@code (T) C.f;}</td>
186      * </tr>
187      * <tr>
188      *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findSetter lookup.findSetter(C.class,"f",FT.class)}</td>
189      *     <td>{@code FT f;}</td><td>{@code this.f = x;}</td>
190      * </tr>
191      * <tr>
192      *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findStaticSetter lookup.findStaticSetter(C.class,"f",FT.class)}</td>
193      *     <td>{@code static}<br>{@code FT f;}</td><td>{@code C.f = arg;}</td>
194      * </tr>
195      * <tr>
196      *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findVirtual lookup.findVirtual(C.class,"m",MT)}</td>
197      *     <td>{@code T m(A*);}</td><td>{@code (T) this.m(arg*);}</td>
198      * </tr>
199      * <tr>
200      *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findStatic lookup.findStatic(C.class,"m",MT)}</td>
201      *     <td>{@code static}<br>{@code T m(A*);}</td><td>{@code (T) C.m(arg*);}</td>
202      * </tr>
203      * <tr>
204      *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findSpecial lookup.findSpecial(C.class,"m",MT,this.class)}</td>
205      *     <td>{@code T m(A*);}</td><td>{@code (T) super.m(arg*);}</td>
206      * </tr>
207      * <tr>
208      *     <td>{@link java.lang.invoke.MethodHandles.Lookup#findConstructor lookup.findConstructor(C.class,MT)}</td>
209      *     <td>{@code C(A*);}</td><td>{@code new C(arg*);}</td>
210      * </tr>
211      * <tr>
212      *     <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectGetter lookup.unreflectGetter(aField)}</td>
213      *     <td>({@code static})?<br>{@code FT f;}</td><td>{@code (FT) aField.get(thisOrNull);}</td>
214      * </tr>
215      * <tr>
216      *     <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectSetter lookup.unreflectSetter(aField)}</td>
217      *     <td>({@code static})?<br>{@code FT f;}</td><td>{@code aField.set(thisOrNull, arg);}</td>
218      * </tr>
219      * <tr>
220      *     <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
221      *     <td>({@code static})?<br>{@code T m(A*);}</td><td>{@code (T) aMethod.invoke(thisOrNull, arg*);}</td>
222      * </tr>
223      * <tr>
224      *     <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor lookup.unreflectConstructor(aConstructor)}</td>
225      *     <td>{@code C(A*);}</td><td>{@code (C) aConstructor.newInstance(arg*);}</td>
226      * </tr>
227      * <tr>
228      *     <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
229      *     <td>({@code static})?<br>{@code T m(A*);}</td><td>{@code (T) aMethod.invoke(thisOrNull, arg*);}</td>
230      * </tr>
231      * </table>
232      *
233      * Here, the type {@code C} is the class or interface being searched for a member,
234      * documented as a parameter named {@code refc} in the lookup methods.
235      * The method type {@code MT} is composed from the return type {@code T}
236      * and the sequence of argument types {@code A*}.
237      * The constructor also has a sequence of argument types {@code A*} and
238      * is deemed to return the newly-created object of type {@code C}.
239      * Both {@code MT} and the field type {@code FT} are documented as a parameter named {@code type}.
240      * The formal parameter {@code this} stands for the self-reference of type {@code C};
241      * if it is present, it is always the leading argument to the method handle invocation.
242      * (In the case of some {@code protected} members, {@code this} may be
243      * restricted in type to the lookup class; see below.)
244      * The name {@code arg} stands for all the other method handle arguments.
245      * In the code examples for the Core Reflection API, the name {@code thisOrNull}
246      * stands for a null reference if the accessed method or field is static,
247      * and {@code this} otherwise.
248      * The names {@code aMethod}, {@code aField}, and {@code aConstructor} stand
249      * for reflective objects corresponding to the given members.
250      * <p>
251      * In cases where the given member is of variable arity (i.e., a method or constructor)
252      * the returned method handle will also be of {@linkplain MethodHandle#asVarargsCollector variable arity}.
253      * In all other cases, the returned method handle will be of fixed arity.
254      * <p style="font-size:smaller;">
255      * <em>Discussion:</em>
256      * The equivalence between looked-up method handles and underlying
257      * class members and bytecode behaviors
258      * can break down in a few ways:
259      * <ul style="font-size:smaller;">
260      * <li>If {@code C} is not symbolically accessible from the lookup class's loader,
261      * the lookup can still succeed, even when there is no equivalent
262      * Java expression or bytecoded constant.
263      * <li>Likewise, if {@code T} or {@code MT}
264      * is not symbolically accessible from the lookup class's loader,
265      * the lookup can still succeed.
266      * For example, lookups for {@code MethodHandle.invokeExact} and
267      * {@code MethodHandle.invoke} will always succeed, regardless of requested type.
268      * <li>If there is a security manager installed, it can forbid the lookup
269      * on various grounds (<a href="MethodHandles.Lookup.html#secmgr">see below</a>).
270      * By contrast, the {@code ldc} instruction on a {@code CONSTANT_MethodHandle}
271      * constant is not subject to security manager checks.
272      * <li>If the looked-up method has a
273      * <a href="MethodHandle.html#maxarity">very large arity</a>,
274      * the method handle creation may fail, due to the method handle
275      * type having too many parameters.
276      * </ul>
277      *
278      * <h1><a name="access"></a>Access checking</h1>
279      * Access checks are applied in the factory methods of {@code Lookup},
280      * when a method handle is created.
281      * This is a key difference from the Core Reflection API, since
282      * {@link java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}
283      * performs access checking against every caller, on every call.
284      * <p>
285      * All access checks start from a {@code Lookup} object, which
286      * compares its recorded lookup class against all requests to
287      * create method handles.
288      * A single {@code Lookup} object can be used to create any number
289      * of access-checked method handles, all checked against a single
290      * lookup class.
291      * <p>
292      * A {@code Lookup} object can be shared with other trusted code,
293      * such as a metaobject protocol.
294      * A shared {@code Lookup} object delegates the capability
295      * to create method handles on private members of the lookup class.
296      * Even if privileged code uses the {@code Lookup} object,
297      * the access checking is confined to the privileges of the
298      * original lookup class.
299      * <p>
300      * A lookup can fail, because
301      * the containing class is not accessible to the lookup class, or
302      * because the desired class member is missing, or because the
303      * desired class member is not accessible to the lookup class, or
304      * because the lookup object is not trusted enough to access the member.
305      * In any of these cases, a {@code ReflectiveOperationException} will be
306      * thrown from the attempted lookup.  The exact class will be one of
307      * the following:
308      * <ul>
309      * <li>NoSuchMethodException &mdash; if a method is requested but does not exist
310      * <li>NoSuchFieldException &mdash; if a field is requested but does not exist
311      * <li>IllegalAccessException &mdash; if the member exists but an access check fails
312      * </ul>
313      * <p>
314      * In general, the conditions under which a method handle may be
315      * looked up for a method {@code M} are no more restrictive than the conditions
316      * under which the lookup class could have compiled, verified, and resolved a call to {@code M}.
317      * Where the JVM would raise exceptions like {@code NoSuchMethodError},
318      * a method handle lookup will generally raise a corresponding
319      * checked exception, such as {@code NoSuchMethodException}.
320      * And the effect of invoking the method handle resulting from the lookup
321      * is <a href="MethodHandles.Lookup.html#equiv">exactly equivalent</a>
322      * to executing the compiled, verified, and resolved call to {@code M}.
323      * The same point is true of fields and constructors.
324      * <p style="font-size:smaller;">
325      * <em>Discussion:</em>
326      * Access checks only apply to named and reflected methods,
327      * constructors, and fields.
328      * Other method handle creation methods, such as
329      * {@link MethodHandle#asType MethodHandle.asType},
330      * do not require any access checks, and are used
331      * independently of any {@code Lookup} object.
332      * <p>
333      * If the desired member is {@code protected}, the usual JVM rules apply,
334      * including the requirement that the lookup class must be either be in the
335      * same package as the desired member, or must inherit that member.
336      * (See the Java Virtual Machine Specification, sections 4.9.2, 5.4.3.5, and 6.4.)
337      * In addition, if the desired member is a non-static field or method
338      * in a different package, the resulting method handle may only be applied
339      * to objects of the lookup class or one of its subclasses.
340      * This requirement is enforced by narrowing the type of the leading
341      * {@code this} parameter from {@code C}
342      * (which will necessarily be a superclass of the lookup class)
343      * to the lookup class itself.
344      * <p>
345      * The JVM imposes a similar requirement on {@code invokespecial} instruction,
346      * that the receiver argument must match both the resolved method <em>and</em>
347      * the current class.  Again, this requirement is enforced by narrowing the
348      * type of the leading parameter to the resulting method handle.
349      * (See the Java Virtual Machine Specification, section 4.10.1.9.)
350      * <p>
351      * The JVM represents constructors and static initializer blocks as internal methods
352      * with special names ({@code "<init>"} and {@code "<clinit>"}).
353      * The internal syntax of invocation instructions allows them to refer to such internal
354      * methods as if they were normal methods, but the JVM bytecode verifier rejects them.
355      * A lookup of such an internal method will produce a {@code NoSuchMethodException}.
356      * <p>
357      * In some cases, access between nested classes is obtained by the Java compiler by creating
358      * an wrapper method to access a private method of another class
359      * in the same top-level declaration.
360      * For example, a nested class {@code C.D}
361      * can access private members within other related classes such as
362      * {@code C}, {@code C.D.E}, or {@code C.B},
363      * but the Java compiler may need to generate wrapper methods in
364      * those related classes.  In such cases, a {@code Lookup} object on
365      * {@code C.E} would be unable to those private members.
366      * A workaround for this limitation is the {@link Lookup#in Lookup.in} method,
367      * which can transform a lookup on {@code C.E} into one on any of those other
368      * classes, without special elevation of privilege.
369      * <p>
370      * The accesses permitted to a given lookup object may be limited,
371      * according to its set of {@link #lookupModes lookupModes},
372      * to a subset of members normally accessible to the lookup class.
373      * For example, the {@link #publicLookup publicLookup}
374      * method produces a lookup object which is only allowed to access
375      * public members in public classes.
376      * The caller sensitive method {@link #lookup lookup}
377      * produces a lookup object with full capabilities relative to
378      * its caller class, to emulate all supported bytecode behaviors.
379      * Also, the {@link Lookup#in Lookup.in} method may produce a lookup object
380      * with fewer access modes than the original lookup object.
381      *
382      * <p style="font-size:smaller;">
383      * <a name="privacc"></a>
384      * <em>Discussion of private access:</em>
385      * We say that a lookup has <em>private access</em>
386      * if its {@linkplain #lookupModes lookup modes}
387      * include the possibility of accessing {@code private} members.
388      * As documented in the relevant methods elsewhere,
389      * only lookups with private access possess the following capabilities:
390      * <ul style="font-size:smaller;">
391      * <li>access private fields, methods, and constructors of the lookup class
392      * <li>create method handles which invoke <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a> methods,
393      *     such as {@code Class.forName}
394      * <li>create method handles which {@link Lookup#findSpecial emulate invokespecial} instructions
395      * <li>avoid <a href="MethodHandles.Lookup.html#secmgr">package access checks</a>
396      *     for classes accessible to the lookup class
397      * <li>create {@link Lookup#in delegated lookup objects} which have private access to other classes
398      *     within the same package member
399      * </ul>
400      * <p style="font-size:smaller;">
401      * Each of these permissions is a consequence of the fact that a lookup object
402      * with private access can be securely traced back to an originating class,
403      * whose <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> and Java language access permissions
404      * can be reliably determined and emulated by method handles.
405      *
406      * <h1><a name="secmgr"></a>Security manager interactions</h1>
407      * Although bytecode instructions can only refer to classes in
408      * a related class loader, this API can search for methods in any
409      * class, as long as a reference to its {@code Class} object is
410      * available.  Such cross-loader references are also possible with the
411      * Core Reflection API, and are impossible to bytecode instructions
412      * such as {@code invokestatic} or {@code getfield}.
413      * There is a {@linkplain java.lang.SecurityManager security manager API}
414      * to allow applications to check such cross-loader references.
415      * These checks apply to both the {@code MethodHandles.Lookup} API
416      * and the Core Reflection API
417      * (as found on {@link java.lang.Class Class}).
418      * <p>
419      * If a security manager is present, member lookups are subject to
420      * additional checks.
421      * From one to three calls are made to the security manager.
422      * Any of these calls can refuse access by throwing a
423      * {@link java.lang.SecurityException SecurityException}.
424      * Define {@code smgr} as the security manager,
425      * {@code lookc} as the lookup class of the current lookup object,
426      * {@code refc} as the containing class in which the member
427      * is being sought, and {@code defc} as the class in which the
428      * member is actually defined.
429      * The value {@code lookc} is defined as <em>not present</em>
430      * if the current lookup object does not have
431      * <a href="MethodHandles.Lookup.html#privacc">private access</a>.
432      * The calls are made according to the following rules:
433      * <ul>
434      * <li><b>Step 1:</b>
435      *     If {@code lookc} is not present, or if its class loader is not
436      *     the same as or an ancestor of the class loader of {@code refc},
437      *     then {@link SecurityManager#checkPackageAccess
438      *     smgr.checkPackageAccess(refcPkg)} is called,
439      *     where {@code refcPkg} is the package of {@code refc}.
440      * <li><b>Step 2:</b>
441      *     If the retrieved member is not public and
442      *     {@code lookc} is not present, then
443      *     {@link SecurityManager#checkPermission smgr.checkPermission}
444      *     with {@code RuntimePermission("accessDeclaredMembers")} is called.
445      * <li><b>Step 3:</b>
446      *     If the retrieved member is not public,
447      *     and if {@code lookc} is not present,
448      *     and if {@code defc} and {@code refc} are different,
449      *     then {@link SecurityManager#checkPackageAccess
450      *     smgr.checkPackageAccess(defcPkg)} is called,
451      *     where {@code defcPkg} is the package of {@code defc}.
452      * </ul>
453      * Security checks are performed after other access checks have passed.
454      * Therefore, the above rules presuppose a member that is public,
455      * or else that is being accessed from a lookup class that has
456      * rights to access the member.
457      *
458      * <h1><a name="callsens"></a>Caller sensitive methods</h1>
459      * A small number of Java methods have a special property called caller sensitivity.
460      * A <em>caller-sensitive</em> method can behave differently depending on the
461      * identity of its immediate caller.
462      * <p>
463      * If a method handle for a caller-sensitive method is requested,
464      * the general rules for <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> apply,
465      * but they take account of the lookup class in a special way.
466      * The resulting method handle behaves as if it were called
467      * from an instruction contained in the lookup class,
468      * so that the caller-sensitive method detects the lookup class.
469      * (By contrast, the invoker of the method handle is disregarded.)
470      * Thus, in the case of caller-sensitive methods,
471      * different lookup classes may give rise to
472      * differently behaving method handles.
473      * <p>
474      * In cases where the lookup object is
475      * {@link #publicLookup publicLookup()},
476      * or some other lookup object without
477      * <a href="MethodHandles.Lookup.html#privacc">private access</a>,
478      * the lookup class is disregarded.
479      * In such cases, no caller-sensitive method handle can be created,
480      * access is forbidden, and the lookup fails with an
481      * {@code IllegalAccessException}.
482      * <p style="font-size:smaller;">
483      * <em>Discussion:</em>
484      * For example, the caller-sensitive method
485      * {@link java.lang.Class#forName(String) Class.forName(x)}
486      * can return varying classes or throw varying exceptions,
487      * depending on the class loader of the class that calls it.
488      * A public lookup of {@code Class.forName} will fail, because
489      * there is no reasonable way to determine its bytecode behavior.
490      * <p style="font-size:smaller;">
491      * If an application caches method handles for broad sharing,
492      * it should use {@code publicLookup()} to create them.
493      * If there is a lookup of {@code Class.forName}, it will fail,
494      * and the application must take appropriate action in that case.
495      * It may be that a later lookup, perhaps during the invocation of a
496      * bootstrap method, can incorporate the specific identity
497      * of the caller, making the method accessible.
498      * <p style="font-size:smaller;">
499      * The function {@code MethodHandles.lookup} is caller sensitive
500      * so that there can be a secure foundation for lookups.
501      * Nearly all other methods in the JSR 292 API rely on lookup
502      * objects to check access requests.
503      */
504     // Android-changed: Change link targets from MethodHandles#[public]Lookup to
505     // #[public]Lookup to work around complaints from javadoc.
506     public static final
507     class Lookup {
508         /** The class on behalf of whom the lookup is being performed. */
509         /* @NonNull */ private final Class<?> lookupClass;
510 
511         /** The allowed sorts of members which may be looked up (PUBLIC, etc.). */
512         private final int allowedModes;
513 
514         /** A single-bit mask representing {@code public} access,
515          *  which may contribute to the result of {@link #lookupModes lookupModes}.
516          *  The value, {@code 0x01}, happens to be the same as the value of the
517          *  {@code public} {@linkplain java.lang.reflect.Modifier#PUBLIC modifier bit}.
518          */
519         public static final int PUBLIC = Modifier.PUBLIC;
520 
521         /** A single-bit mask representing {@code private} access,
522          *  which may contribute to the result of {@link #lookupModes lookupModes}.
523          *  The value, {@code 0x02}, happens to be the same as the value of the
524          *  {@code private} {@linkplain java.lang.reflect.Modifier#PRIVATE modifier bit}.
525          */
526         public static final int PRIVATE = Modifier.PRIVATE;
527 
528         /** A single-bit mask representing {@code protected} access,
529          *  which may contribute to the result of {@link #lookupModes lookupModes}.
530          *  The value, {@code 0x04}, happens to be the same as the value of the
531          *  {@code protected} {@linkplain java.lang.reflect.Modifier#PROTECTED modifier bit}.
532          */
533         public static final int PROTECTED = Modifier.PROTECTED;
534 
535         /** A single-bit mask representing {@code package} access (default access),
536          *  which may contribute to the result of {@link #lookupModes lookupModes}.
537          *  The value is {@code 0x08}, which does not correspond meaningfully to
538          *  any particular {@linkplain java.lang.reflect.Modifier modifier bit}.
539          */
540         public static final int PACKAGE = Modifier.STATIC;
541 
542         private static final int ALL_MODES = (PUBLIC | PRIVATE | PROTECTED | PACKAGE);
543 
544         // Android-note: Android has no notion of a trusted lookup. If required, such lookups
545         // are performed by the runtime. As a result, we always use lookupClass, which will always
546         // be non-null in our implementation.
547         //
548         // private static final int TRUSTED   = -1;
549 
fixmods(int mods)550         private static int fixmods(int mods) {
551             mods &= (ALL_MODES - PACKAGE);
552             return (mods != 0) ? mods : PACKAGE;
553         }
554 
555         /** Tells which class is performing the lookup.  It is this class against
556          *  which checks are performed for visibility and access permissions.
557          *  <p>
558          *  The class implies a maximum level of access permission,
559          *  but the permissions may be additionally limited by the bitmask
560          *  {@link #lookupModes lookupModes}, which controls whether non-public members
561          *  can be accessed.
562          *  @return the lookup class, on behalf of which this lookup object finds members
563          */
lookupClass()564         public Class<?> lookupClass() {
565             return lookupClass;
566         }
567 
568         /** Tells which access-protection classes of members this lookup object can produce.
569          *  The result is a bit-mask of the bits
570          *  {@linkplain #PUBLIC PUBLIC (0x01)},
571          *  {@linkplain #PRIVATE PRIVATE (0x02)},
572          *  {@linkplain #PROTECTED PROTECTED (0x04)},
573          *  and {@linkplain #PACKAGE PACKAGE (0x08)}.
574          *  <p>
575          *  A freshly-created lookup object
576          *  on the {@linkplain java.lang.invoke.MethodHandles#lookup() caller's class}
577          *  has all possible bits set, since the caller class can access all its own members.
578          *  A lookup object on a new lookup class
579          *  {@linkplain java.lang.invoke.MethodHandles.Lookup#in created from a previous lookup object}
580          *  may have some mode bits set to zero.
581          *  The purpose of this is to restrict access via the new lookup object,
582          *  so that it can access only names which can be reached by the original
583          *  lookup object, and also by the new lookup class.
584          *  @return the lookup modes, which limit the kinds of access performed by this lookup object
585          */
lookupModes()586         public int lookupModes() {
587             return allowedModes & ALL_MODES;
588         }
589 
590         /** Embody the current class (the lookupClass) as a lookup class
591          * for method handle creation.
592          * Must be called by from a method in this package,
593          * which in turn is called by a method not in this package.
594          */
Lookup(Class<?> lookupClass)595         Lookup(Class<?> lookupClass) {
596             this(lookupClass, ALL_MODES);
597             // make sure we haven't accidentally picked up a privileged class:
598             checkUnprivilegedlookupClass(lookupClass, ALL_MODES);
599         }
600 
Lookup(Class<?> lookupClass, int allowedModes)601         private Lookup(Class<?> lookupClass, int allowedModes) {
602             this.lookupClass = lookupClass;
603             this.allowedModes = allowedModes;
604         }
605 
606         /**
607          * Creates a lookup on the specified new lookup class.
608          * The resulting object will report the specified
609          * class as its own {@link #lookupClass lookupClass}.
610          * <p>
611          * However, the resulting {@code Lookup} object is guaranteed
612          * to have no more access capabilities than the original.
613          * In particular, access capabilities can be lost as follows:<ul>
614          * <li>If the new lookup class differs from the old one,
615          * protected members will not be accessible by virtue of inheritance.
616          * (Protected members may continue to be accessible because of package sharing.)
617          * <li>If the new lookup class is in a different package
618          * than the old one, protected and default (package) members will not be accessible.
619          * <li>If the new lookup class is not within the same package member
620          * as the old one, private members will not be accessible.
621          * <li>If the new lookup class is not accessible to the old lookup class,
622          * then no members, not even public members, will be accessible.
623          * (In all other cases, public members will continue to be accessible.)
624          * </ul>
625          *
626          * @param requestedLookupClass the desired lookup class for the new lookup object
627          * @return a lookup object which reports the desired lookup class
628          * @throws NullPointerException if the argument is null
629          */
in(Class<?> requestedLookupClass)630         public Lookup in(Class<?> requestedLookupClass) {
631             requestedLookupClass.getClass();  // null check
632             // Android-changed: There's no notion of a trusted lookup.
633             // if (allowedModes == TRUSTED)  // IMPL_LOOKUP can make any lookup at all
634             //    return new Lookup(requestedLookupClass, ALL_MODES);
635 
636             if (requestedLookupClass == this.lookupClass)
637                 return this;  // keep same capabilities
638             int newModes = (allowedModes & (ALL_MODES & ~PROTECTED));
639             if ((newModes & PACKAGE) != 0
640                 && !VerifyAccess.isSamePackage(this.lookupClass, requestedLookupClass)) {
641                 newModes &= ~(PACKAGE|PRIVATE);
642             }
643             // Allow nestmate lookups to be created without special privilege:
644             if ((newModes & PRIVATE) != 0
645                 && !VerifyAccess.isSamePackageMember(this.lookupClass, requestedLookupClass)) {
646                 newModes &= ~PRIVATE;
647             }
648             if ((newModes & PUBLIC) != 0
649                 && !VerifyAccess.isClassAccessible(requestedLookupClass, this.lookupClass, allowedModes)) {
650                 // The requested class it not accessible from the lookup class.
651                 // No permissions.
652                 newModes = 0;
653             }
654             checkUnprivilegedlookupClass(requestedLookupClass, newModes);
655             return new Lookup(requestedLookupClass, newModes);
656         }
657 
658         // Make sure outer class is initialized first.
659         //
660         // Android-changed: Removed unnecessary reference to IMPL_NAMES.
661         // static { IMPL_NAMES.getClass(); }
662 
663         /** Version of lookup which is trusted minimally.
664          *  It can only be used to create method handles to
665          *  publicly accessible members.
666          */
667         static final Lookup PUBLIC_LOOKUP = new Lookup(Object.class, PUBLIC);
668 
669         /** Package-private version of lookup which is trusted. */
670         static final Lookup IMPL_LOOKUP = new Lookup(Object.class, ALL_MODES);
671 
checkUnprivilegedlookupClass(Class<?> lookupClass, int allowedModes)672         private static void checkUnprivilegedlookupClass(Class<?> lookupClass, int allowedModes) {
673             String name = lookupClass.getName();
674             if (name.startsWith("java.lang.invoke."))
675                 throw newIllegalArgumentException("illegal lookupClass: "+lookupClass);
676 
677             // For caller-sensitive MethodHandles.lookup()
678             // disallow lookup more restricted packages
679             //
680             // Android-changed: The bootstrap classloader isn't null.
681             if (allowedModes == ALL_MODES &&
682                     lookupClass.getClassLoader() == Object.class.getClassLoader()) {
683                 if (name.startsWith("java.") ||
684                         (name.startsWith("sun.")
685                                 && !name.startsWith("sun.invoke.")
686                                 && !name.equals("sun.reflect.ReflectionFactory"))) {
687                     throw newIllegalArgumentException("illegal lookupClass: " + lookupClass);
688                 }
689             }
690         }
691 
692         /**
693          * Displays the name of the class from which lookups are to be made.
694          * (The name is the one reported by {@link java.lang.Class#getName() Class.getName}.)
695          * If there are restrictions on the access permitted to this lookup,
696          * this is indicated by adding a suffix to the class name, consisting
697          * of a slash and a keyword.  The keyword represents the strongest
698          * allowed access, and is chosen as follows:
699          * <ul>
700          * <li>If no access is allowed, the suffix is "/noaccess".
701          * <li>If only public access is allowed, the suffix is "/public".
702          * <li>If only public and package access are allowed, the suffix is "/package".
703          * <li>If only public, package, and private access are allowed, the suffix is "/private".
704          * </ul>
705          * If none of the above cases apply, it is the case that full
706          * access (public, package, private, and protected) is allowed.
707          * In this case, no suffix is added.
708          * This is true only of an object obtained originally from
709          * {@link java.lang.invoke.MethodHandles#lookup MethodHandles.lookup}.
710          * Objects created by {@link java.lang.invoke.MethodHandles.Lookup#in Lookup.in}
711          * always have restricted access, and will display a suffix.
712          * <p>
713          * (It may seem strange that protected access should be
714          * stronger than private access.  Viewed independently from
715          * package access, protected access is the first to be lost,
716          * because it requires a direct subclass relationship between
717          * caller and callee.)
718          * @see #in
719          */
720         @Override
toString()721         public String toString() {
722             String cname = lookupClass.getName();
723             switch (allowedModes) {
724             case 0:  // no privileges
725                 return cname + "/noaccess";
726             case PUBLIC:
727                 return cname + "/public";
728             case PUBLIC|PACKAGE:
729                 return cname + "/package";
730             case ALL_MODES & ~PROTECTED:
731                 return cname + "/private";
732             case ALL_MODES:
733                 return cname;
734             // Android-changed: No support for TRUSTED callers.
735             // case TRUSTED:
736             //    return "/trusted";  // internal only; not exported
737             default:  // Should not happen, but it's a bitfield...
738                 cname = cname + "/" + Integer.toHexString(allowedModes);
739                 assert(false) : cname;
740                 return cname;
741             }
742         }
743 
744         /**
745          * Produces a method handle for a static method.
746          * The type of the method handle will be that of the method.
747          * (Since static methods do not take receivers, there is no
748          * additional receiver argument inserted into the method handle type,
749          * as there would be with {@link #findVirtual findVirtual} or {@link #findSpecial findSpecial}.)
750          * The method and all its argument types must be accessible to the lookup object.
751          * <p>
752          * The returned method handle will have
753          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
754          * the method's variable arity modifier bit ({@code 0x0080}) is set.
755          * <p>
756          * If the returned method handle is invoked, the method's class will
757          * be initialized, if it has not already been initialized.
758          * <p><b>Example:</b>
759          * <blockquote><pre>{@code
760 import static java.lang.invoke.MethodHandles.*;
761 import static java.lang.invoke.MethodType.*;
762 ...
763 MethodHandle MH_asList = publicLookup().findStatic(Arrays.class,
764   "asList", methodType(List.class, Object[].class));
765 assertEquals("[x, y]", MH_asList.invoke("x", "y").toString());
766          * }</pre></blockquote>
767          * @param refc the class from which the method is accessed
768          * @param name the name of the method
769          * @param type the type of the method
770          * @return the desired method handle
771          * @throws NoSuchMethodException if the method does not exist
772          * @throws IllegalAccessException if access checking fails,
773          *                                or if the method is not {@code static},
774          *                                or if the method's variable arity modifier bit
775          *                                is set and {@code asVarargsCollector} fails
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
findStatic(Class<?> refc, String name, MethodType type)781         MethodHandle findStatic(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
782             Method method = refc.getDeclaredMethod(name, type.ptypes());
783             final int modifiers = method.getModifiers();
784             if (!Modifier.isStatic(modifiers)) {
785                 throw new IllegalAccessException("Method" + method + " is not static");
786             }
787             checkReturnType(method, type);
788             checkAccess(refc, method.getDeclaringClass(), modifiers, method.getName());
789             return createMethodHandle(method, MethodHandle.INVOKE_STATIC, type);
790         }
791 
findVirtualForMH(String name, MethodType type)792         private MethodHandle findVirtualForMH(String name, MethodType type) {
793             // these names require special lookups because of the implicit MethodType argument
794             if ("invoke".equals(name))
795                 return invoker(type);
796             if ("invokeExact".equals(name))
797                 return exactInvoker(type);
798             return null;
799         }
800 
findVirtualForVH(String name, MethodType type)801         private MethodHandle findVirtualForVH(String name, MethodType type) {
802             VarHandle.AccessMode accessMode;
803             try {
804                 accessMode = VarHandle.AccessMode.valueFromMethodName(name);
805             } catch (IllegalArgumentException e) {
806                 return null;
807             }
808             return varHandleInvoker(accessMode, type);
809         }
810 
createMethodHandle(Method method, int handleKind, MethodType methodType)811         private static MethodHandle createMethodHandle(Method method, int handleKind,
812                                                        MethodType methodType) {
813             MethodHandle mh = new MethodHandleImpl(method.getArtMethod(), handleKind, methodType);
814             if (method.isVarArgs()) {
815                 return new Transformers.VarargsCollector(mh);
816             } else {
817                 return mh;
818             }
819         }
820 
821         /**
822          * Produces a method handle for a virtual method.
823          * The type of the method handle will be that of the method,
824          * with the receiver type (usually {@code refc}) prepended.
825          * The method and all its argument types must be accessible to the lookup object.
826          * <p>
827          * When called, the handle will treat the first argument as a receiver
828          * and dispatch on the receiver's type to determine which method
829          * implementation to enter.
830          * (The dispatching action is identical with that performed by an
831          * {@code invokevirtual} or {@code invokeinterface} instruction.)
832          * <p>
833          * The first argument will be of type {@code refc} if the lookup
834          * class has full privileges to access the member.  Otherwise
835          * the member must be {@code protected} and the first argument
836          * will be restricted in type to the lookup class.
837          * <p>
838          * The returned method handle will have
839          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
840          * the method's variable arity modifier bit ({@code 0x0080}) is set.
841          * <p>
842          * Because of the general <a href="MethodHandles.Lookup.html#equiv">equivalence</a> between {@code invokevirtual}
843          * instructions and method handles produced by {@code findVirtual},
844          * if the class is {@code MethodHandle} and the name string is
845          * {@code invokeExact} or {@code invoke}, the resulting
846          * method handle is equivalent to one produced by
847          * {@link java.lang.invoke.MethodHandles#exactInvoker MethodHandles.exactInvoker} or
848          * {@link java.lang.invoke.MethodHandles#invoker MethodHandles.invoker}
849          * with the same {@code type} argument.
850          *
851          * <b>Example:</b>
852          * <blockquote><pre>{@code
853 import static java.lang.invoke.MethodHandles.*;
854 import static java.lang.invoke.MethodType.*;
855 ...
856 MethodHandle MH_concat = publicLookup().findVirtual(String.class,
857   "concat", methodType(String.class, String.class));
858 MethodHandle MH_hashCode = publicLookup().findVirtual(Object.class,
859   "hashCode", methodType(int.class));
860 MethodHandle MH_hashCode_String = publicLookup().findVirtual(String.class,
861   "hashCode", methodType(int.class));
862 assertEquals("xy", (String) MH_concat.invokeExact("x", "y"));
863 assertEquals("xy".hashCode(), (int) MH_hashCode.invokeExact((Object)"xy"));
864 assertEquals("xy".hashCode(), (int) MH_hashCode_String.invokeExact("xy"));
865 // interface method:
866 MethodHandle MH_subSequence = publicLookup().findVirtual(CharSequence.class,
867   "subSequence", methodType(CharSequence.class, int.class, int.class));
868 assertEquals("def", MH_subSequence.invoke("abcdefghi", 3, 6).toString());
869 // constructor "internal method" must be accessed differently:
870 MethodType MT_newString = methodType(void.class); //()V for new String()
871 try { assertEquals("impossible", lookup()
872         .findVirtual(String.class, "<init>", MT_newString));
873  } catch (NoSuchMethodException ex) { } // OK
874 MethodHandle MH_newString = publicLookup()
875   .findConstructor(String.class, MT_newString);
876 assertEquals("", (String) MH_newString.invokeExact());
877          * }</pre></blockquote>
878          *
879          * @param refc the class or interface from which the method is accessed
880          * @param name the name of the method
881          * @param type the type of the method, with the receiver argument omitted
882          * @return the desired method handle
883          * @throws NoSuchMethodException if the method does not exist
884          * @throws IllegalAccessException if access checking fails,
885          *                                or if the method is {@code static}
886          *                                or if the method's variable arity modifier bit
887          *                                is set and {@code asVarargsCollector} fails
888          * @exception SecurityException if a security manager is present and it
889          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
890          * @throws NullPointerException if any argument is null
891          */
findVirtual(Class<?> refc, String name, MethodType type)892         public MethodHandle findVirtual(Class<?> refc, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
893             // Special case : when we're looking up a virtual method on the MethodHandles class
894             // itself, we can return one of our specialized invokers.
895             if (refc == MethodHandle.class) {
896                 MethodHandle mh = findVirtualForMH(name, type);
897                 if (mh != null) {
898                     return mh;
899                 }
900             } else if (refc == VarHandle.class) {
901                 // Returns an non-exact invoker.
902                 MethodHandle mh = findVirtualForVH(name, type);
903                 if (mh != null) {
904                     return mh;
905                 }
906             }
907 
908             Method method = refc.getInstanceMethod(name, type.ptypes());
909             if (method == null) {
910                 // This is pretty ugly and a consequence of the MethodHandles API. We have to throw
911                 // an IAE and not an NSME if the method exists but is static (even though the RI's
912                 // IAE has a message that says "no such method"). We confine the ugliness and
913                 // slowness to the failure case, and allow getInstanceMethod to remain fairly
914                 // general.
915                 try {
916                     Method m = refc.getDeclaredMethod(name, type.ptypes());
917                     if (Modifier.isStatic(m.getModifiers())) {
918                         throw new IllegalAccessException("Method" + m + " is static");
919                     }
920                 } catch (NoSuchMethodException ignored) {
921                 }
922 
923                 throw new NoSuchMethodException(name + " "  + Arrays.toString(type.ptypes()));
924             }
925             checkReturnType(method, type);
926 
927             // We have a valid method, perform access checks.
928             checkAccess(refc, method.getDeclaringClass(), method.getModifiers(), method.getName());
929 
930             // Insert the leading reference parameter.
931             MethodType handleType = type.insertParameterTypes(0, refc);
932             return createMethodHandle(method, MethodHandle.INVOKE_VIRTUAL, handleType);
933         }
934 
935         /**
936          * Produces a method handle which creates an object and initializes it, using
937          * the constructor of the specified type.
938          * The parameter types of the method handle will be those of the constructor,
939          * while the return type will be a reference to the constructor's class.
940          * The constructor and all its argument types must be accessible to the lookup object.
941          * <p>
942          * The requested type must have a return type of {@code void}.
943          * (This is consistent with the JVM's treatment of constructor type descriptors.)
944          * <p>
945          * The returned method handle will have
946          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
947          * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
948          * <p>
949          * If the returned method handle is invoked, the constructor's class will
950          * be initialized, if it has not already been initialized.
951          * <p><b>Example:</b>
952          * <blockquote><pre>{@code
953 import static java.lang.invoke.MethodHandles.*;
954 import static java.lang.invoke.MethodType.*;
955 ...
956 MethodHandle MH_newArrayList = publicLookup().findConstructor(
957   ArrayList.class, methodType(void.class, Collection.class));
958 Collection orig = Arrays.asList("x", "y");
959 Collection copy = (ArrayList) MH_newArrayList.invokeExact(orig);
960 assert(orig != copy);
961 assertEquals(orig, copy);
962 // a variable-arity constructor:
963 MethodHandle MH_newProcessBuilder = publicLookup().findConstructor(
964   ProcessBuilder.class, methodType(void.class, String[].class));
965 ProcessBuilder pb = (ProcessBuilder)
966   MH_newProcessBuilder.invoke("x", "y", "z");
967 assertEquals("[x, y, z]", pb.command().toString());
968          * }</pre></blockquote>
969          * @param refc the class or interface from which the method is accessed
970          * @param type the type of the method, with the receiver argument omitted, and a void return type
971          * @return the desired method handle
972          * @throws NoSuchMethodException if the constructor does not exist
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          * @exception SecurityException if a security manager is present and it
977          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
978          * @throws NullPointerException if any argument is null
979          */
findConstructor(Class<?> refc, MethodType type)980         public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
981             if (refc.isArray()) {
982                 throw new NoSuchMethodException("no constructor for array class: " + refc.getName());
983             }
984             // The queried |type| is (PT1,PT2,..)V
985             Constructor constructor = refc.getDeclaredConstructor(type.ptypes());
986             if (constructor == null) {
987                 throw new NoSuchMethodException(
988                     "No constructor for " + constructor.getDeclaringClass() + " matching " + type);
989             }
990             checkAccess(refc, constructor.getDeclaringClass(), constructor.getModifiers(),
991                     constructor.getName());
992 
993             return createMethodHandleForConstructor(constructor);
994         }
995 
createMethodHandleForConstructor(Constructor constructor)996         private MethodHandle createMethodHandleForConstructor(Constructor constructor) {
997             Class<?> refc = constructor.getDeclaringClass();
998             MethodType constructorType =
999                     MethodType.methodType(refc, constructor.getParameterTypes());
1000             MethodHandle mh;
1001             if (refc == String.class) {
1002                 // String constructors have optimized StringFactory methods
1003                 // that matches returned type. These factory methods combine the
1004                 // memory allocation and initialization calls for String objects.
1005                 mh = new MethodHandleImpl(constructor.getArtMethod(), MethodHandle.INVOKE_DIRECT,
1006                                           constructorType);
1007             } else {
1008                 // Constructors for all other classes use a Construct transformer to perform
1009                 // their memory allocation and call to <init>.
1010                 MethodType initType = initMethodType(constructorType);
1011                 MethodHandle initHandle = new MethodHandleImpl(
1012                     constructor.getArtMethod(), MethodHandle.INVOKE_DIRECT, initType);
1013                 mh = new Transformers.Construct(initHandle, constructorType);
1014             }
1015 
1016             if (constructor.isVarArgs()) {
1017                 mh = new Transformers.VarargsCollector(mh);
1018             }
1019             return mh;
1020         }
1021 
initMethodType(MethodType constructorType)1022         private static MethodType initMethodType(MethodType constructorType) {
1023             // Returns a MethodType appropriate for class <init>
1024             // methods. Constructor MethodTypes have the form
1025             // (PT1,PT2,...)C and class <init> MethodTypes have the
1026             // form (C,PT1,PT2,...)V.
1027             assert constructorType.rtype() != void.class;
1028 
1029             // Insert constructorType C as the first parameter type in
1030             // the MethodType for <init>.
1031             Class<?> [] initPtypes = new Class<?> [constructorType.ptypes().length + 1];
1032             initPtypes[0] = constructorType.rtype();
1033             System.arraycopy(constructorType.ptypes(), 0, initPtypes, 1,
1034                              constructorType.ptypes().length);
1035 
1036             // Set the return type for the <init> MethodType to be void.
1037             return MethodType.methodType(void.class, initPtypes);
1038         }
1039 
1040         /**
1041          * Produces an early-bound method handle for a virtual method.
1042          * It will bypass checks for overriding methods on the receiver,
1043          * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial}
1044          * instruction from within the explicitly specified {@code specialCaller}.
1045          * The type of the method handle will be that of the method,
1046          * with a suitably restricted receiver type prepended.
1047          * (The receiver type will be {@code specialCaller} or a subtype.)
1048          * The method and all its argument types must be accessible
1049          * to the lookup object.
1050          * <p>
1051          * Before method resolution,
1052          * if the explicitly specified caller class is not identical with the
1053          * lookup class, or if this lookup object does not have
1054          * <a href="MethodHandles.Lookup.html#privacc">private access</a>
1055          * privileges, the access fails.
1056          * <p>
1057          * The returned method handle will have
1058          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1059          * the method's variable arity modifier bit ({@code 0x0080}) is set.
1060          * <p style="font-size:smaller;">
1061          * <em>(Note:  JVM internal methods named {@code "<init>"} are not visible to this API,
1062          * even though the {@code invokespecial} instruction can refer to them
1063          * in special circumstances.  Use {@link #findConstructor findConstructor}
1064          * to access instance initialization methods in a safe manner.)</em>
1065          * <p><b>Example:</b>
1066          * <blockquote><pre>{@code
1067 import static java.lang.invoke.MethodHandles.*;
1068 import static java.lang.invoke.MethodType.*;
1069 ...
1070 static class Listie extends ArrayList {
1071   public String toString() { return "[wee Listie]"; }
1072   static Lookup lookup() { return MethodHandles.lookup(); }
1073 }
1074 ...
1075 // no access to constructor via invokeSpecial:
1076 MethodHandle MH_newListie = Listie.lookup()
1077   .findConstructor(Listie.class, methodType(void.class));
1078 Listie l = (Listie) MH_newListie.invokeExact();
1079 try { assertEquals("impossible", Listie.lookup().findSpecial(
1080         Listie.class, "<init>", methodType(void.class), Listie.class));
1081  } catch (NoSuchMethodException ex) { } // OK
1082 // access to super and self methods via invokeSpecial:
1083 MethodHandle MH_super = Listie.lookup().findSpecial(
1084   ArrayList.class, "toString" , methodType(String.class), Listie.class);
1085 MethodHandle MH_this = Listie.lookup().findSpecial(
1086   Listie.class, "toString" , methodType(String.class), Listie.class);
1087 MethodHandle MH_duper = Listie.lookup().findSpecial(
1088   Object.class, "toString" , methodType(String.class), Listie.class);
1089 assertEquals("[]", (String) MH_super.invokeExact(l));
1090 assertEquals(""+l, (String) MH_this.invokeExact(l));
1091 assertEquals("[]", (String) MH_duper.invokeExact(l)); // ArrayList method
1092 try { assertEquals("inaccessible", Listie.lookup().findSpecial(
1093         String.class, "toString", methodType(String.class), Listie.class));
1094  } catch (IllegalAccessException ex) { } // OK
1095 Listie subl = new Listie() { public String toString() { return "[subclass]"; } };
1096 assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method
1097          * }</pre></blockquote>
1098          *
1099          * @param refc the class or interface from which the method is accessed
1100          * @param name the name of the method (which must not be "&lt;init&gt;")
1101          * @param type the type of the method, with the receiver argument omitted
1102          * @param specialCaller the proposed calling class to perform the {@code invokespecial}
1103          * @return the desired method handle
1104          * @throws NoSuchMethodException if the method does not exist
1105          * @throws IllegalAccessException if access checking fails
1106          *                                or if the method's variable arity modifier bit
1107          *                                is set and {@code asVarargsCollector} fails
1108          * @exception SecurityException if a security manager is present and it
1109          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1110          * @throws NullPointerException if any argument is null
1111          */
findSpecial(Class<?> refc, String name, MethodType type, Class<?> specialCaller)1112         public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
1113                                         Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
1114             if (specialCaller == null) {
1115                 throw new NullPointerException("specialCaller == null");
1116             }
1117 
1118             if (type == null) {
1119                 throw new NullPointerException("type == null");
1120             }
1121 
1122             if (name == null) {
1123                 throw new NullPointerException("name == null");
1124             }
1125 
1126             if (refc == null) {
1127                 throw new NullPointerException("ref == null");
1128             }
1129 
1130             // Make sure that the special caller is identical to the lookup class or that we have
1131             // private access.
1132             // Android-changed: Also allow access to any interface methods.
1133             checkSpecialCaller(specialCaller, refc);
1134 
1135             // Even though constructors are invoked using a "special" invoke, handles to them can't
1136             // be created using findSpecial. Callers must use findConstructor instead. Similarly,
1137             // there is no path for calling static class initializers.
1138             if (name.startsWith("<")) {
1139                 throw new NoSuchMethodException(name + " is not a valid method name.");
1140             }
1141 
1142             Method method = refc.getDeclaredMethod(name, type.ptypes());
1143             checkReturnType(method, type);
1144             return findSpecial(method, type, refc, specialCaller);
1145         }
1146 
findSpecial(Method method, MethodType type, Class<?> refc, Class<?> specialCaller)1147         private MethodHandle findSpecial(Method method, MethodType type,
1148                                          Class<?> refc, Class<?> specialCaller)
1149                 throws IllegalAccessException {
1150             if (Modifier.isStatic(method.getModifiers())) {
1151                 throw new IllegalAccessException("expected a non-static method:" + method);
1152             }
1153 
1154             if (Modifier.isPrivate(method.getModifiers())) {
1155                 // Since this is a private method, we'll need to also make sure that the
1156                 // lookup class is the same as the refering class. We've already checked that
1157                 // the specialCaller is the same as the special lookup class, both of these must
1158                 // be the same as the declaring class(*) in order to access the private method.
1159                 //
1160                 // (*) Well, this isn't true for nested classes but OpenJDK doesn't support those
1161                 // either.
1162                 if (refc != lookupClass()) {
1163                     throw new IllegalAccessException("no private access for invokespecial : "
1164                             + refc + ", from" + this);
1165                 }
1166 
1167                 // This is a private method, so there's nothing special to do.
1168                 MethodType handleType = type.insertParameterTypes(0, refc);
1169                 return createMethodHandle(method, MethodHandle.INVOKE_DIRECT, handleType);
1170             }
1171 
1172             // This is a public, protected or package-private method, which means we're expecting
1173             // invoke-super semantics. We'll have to restrict the receiver type appropriately on the
1174             // handle once we check that there really is a "super" relationship between them.
1175             if (!method.getDeclaringClass().isAssignableFrom(specialCaller)) {
1176                 throw new IllegalAccessException(refc + "is not assignable from " + specialCaller);
1177             }
1178 
1179             // Note that we restrict the receiver to "specialCaller" instances.
1180             MethodType handleType = type.insertParameterTypes(0, specialCaller);
1181             return createMethodHandle(method, MethodHandle.INVOKE_SUPER, handleType);
1182         }
1183 
1184         /**
1185          * Produces a method handle giving read access to a non-static field.
1186          * The type of the method handle will have a return type of the field's
1187          * value type.
1188          * The method handle's single argument will be the instance containing
1189          * the field.
1190          * Access checking is performed immediately on behalf of the lookup class.
1191          * @param refc the class or interface from which the method is accessed
1192          * @param name the field's name
1193          * @param type the field's type
1194          * @return a method handle which can load values from the field
1195          * @throws NoSuchFieldException if the field does not exist
1196          * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
1197          * @exception SecurityException if a security manager is present and it
1198          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1199          * @throws NullPointerException if any argument is null
1200          */
findGetter(Class<?> refc, String name, Class<?> type)1201         public MethodHandle findGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
1202             return findAccessor(refc, name, type, MethodHandle.IGET);
1203         }
1204 
findAccessor(Class<?> refc, String name, Class<?> type, int kind)1205         private MethodHandle findAccessor(Class<?> refc, String name, Class<?> type, int kind)
1206             throws NoSuchFieldException, IllegalAccessException {
1207             final Field field = findFieldOfType(refc, name, type);
1208             return findAccessor(field, refc, type, kind, true /* performAccessChecks */);
1209         }
1210 
findAccessor(Field field, Class<?> refc, Class<?> type, int kind, boolean performAccessChecks)1211         private MethodHandle findAccessor(Field field, Class<?> refc, Class<?> type, int kind,
1212                                           boolean performAccessChecks)
1213                 throws IllegalAccessException {
1214             final boolean isSetterKind = kind == MethodHandle.IPUT || kind == MethodHandle.SPUT;
1215             final boolean isStaticKind = kind == MethodHandle.SGET || kind == MethodHandle.SPUT;
1216             commonFieldChecks(field, refc, type, isStaticKind, performAccessChecks);
1217             if (performAccessChecks) {
1218                 final int modifiers = field.getModifiers();
1219                 if (isSetterKind && Modifier.isFinal(modifiers)) {
1220                     throw new IllegalAccessException("Field " + field + " is final");
1221                 }
1222             }
1223 
1224             final MethodType methodType;
1225             switch (kind) {
1226                 case MethodHandle.SGET:
1227                     methodType = MethodType.methodType(type);
1228                     break;
1229                 case MethodHandle.SPUT:
1230                     methodType = MethodType.methodType(void.class, type);
1231                     break;
1232                 case MethodHandle.IGET:
1233                     methodType = MethodType.methodType(type, refc);
1234                     break;
1235                 case MethodHandle.IPUT:
1236                     methodType = MethodType.methodType(void.class, refc, type);
1237                     break;
1238                 default:
1239                     throw new IllegalArgumentException("Invalid kind " + kind);
1240             }
1241             return new MethodHandleImpl(field.getArtField(), kind, methodType);
1242         }
1243 
1244         /**
1245          * Produces a method handle giving write access to a non-static field.
1246          * The type of the method handle will have a void return type.
1247          * The method handle will take two arguments, the instance containing
1248          * the field, and the value to be stored.
1249          * The second argument will be of the field's value type.
1250          * Access checking is performed immediately on behalf of the lookup class.
1251          * @param refc the class or interface from which the method is accessed
1252          * @param name the field's name
1253          * @param type the field's type
1254          * @return a method handle which can store values into the field
1255          * @throws NoSuchFieldException if the field does not exist
1256          * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
1257          * @exception SecurityException if a security manager is present and it
1258          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1259          * @throws NullPointerException if any argument is null
1260          */
findSetter(Class<?> refc, String name, Class<?> type)1261         public MethodHandle findSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
1262             return findAccessor(refc, name, type, MethodHandle.IPUT);
1263         }
1264 
1265         // BEGIN Android-changed: OpenJDK 9+181 VarHandle API factory method.
1266         /**
1267          * Produces a VarHandle giving access to a non-static field {@code name}
1268          * of type {@code type} declared in a class of type {@code recv}.
1269          * The VarHandle's variable type is {@code type} and it has one
1270          * coordinate type, {@code recv}.
1271          * <p>
1272          * Access checking is performed immediately on behalf of the lookup
1273          * class.
1274          * <p>
1275          * Certain access modes of the returned VarHandle are unsupported under
1276          * the following conditions:
1277          * <ul>
1278          * <li>if the field is declared {@code final}, then the write, atomic
1279          *     update, numeric atomic update, and bitwise atomic update access
1280          *     modes are unsupported.
1281          * <li>if the field type is anything other than {@code byte},
1282          *     {@code short}, {@code char}, {@code int}, {@code long},
1283          *     {@code float}, or {@code double} then numeric atomic update
1284          *     access modes are unsupported.
1285          * <li>if the field type is anything other than {@code boolean},
1286          *     {@code byte}, {@code short}, {@code char}, {@code int} or
1287          *     {@code long} then bitwise atomic update access modes are
1288          *     unsupported.
1289          * </ul>
1290          * <p>
1291          * If the field is declared {@code volatile} then the returned VarHandle
1292          * will override access to the field (effectively ignore the
1293          * {@code volatile} declaration) in accordance to its specified
1294          * access modes.
1295          * <p>
1296          * If the field type is {@code float} or {@code double} then numeric
1297          * and atomic update access modes compare values using their bitwise
1298          * representation (see {@link Float#floatToRawIntBits} and
1299          * {@link Double#doubleToRawLongBits}, respectively).
1300          * @apiNote
1301          * Bitwise comparison of {@code float} values or {@code double} values,
1302          * as performed by the numeric and atomic update access modes, differ
1303          * from the primitive {@code ==} operator and the {@link Float#equals}
1304          * and {@link Double#equals} methods, specifically with respect to
1305          * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
1306          * Care should be taken when performing a compare and set or a compare
1307          * and exchange operation with such values since the operation may
1308          * unexpectedly fail.
1309          * There are many possible NaN values that are considered to be
1310          * {@code NaN} in Java, although no IEEE 754 floating-point operation
1311          * provided by Java can distinguish between them.  Operation failure can
1312          * occur if the expected or witness value is a NaN value and it is
1313          * transformed (perhaps in a platform specific manner) into another NaN
1314          * value, and thus has a different bitwise representation (see
1315          * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
1316          * details).
1317          * The values {@code -0.0} and {@code +0.0} have different bitwise
1318          * representations but are considered equal when using the primitive
1319          * {@code ==} operator.  Operation failure can occur if, for example, a
1320          * numeric algorithm computes an expected value to be say {@code -0.0}
1321          * and previously computed the witness value to be say {@code +0.0}.
1322          * @param recv the receiver class, of type {@code R}, that declares the
1323          * non-static field
1324          * @param name the field's name
1325          * @param type the field's type, of type {@code T}
1326          * @return a VarHandle giving access to non-static fields.
1327          * @throws NoSuchFieldException if the field does not exist
1328          * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
1329          * @exception SecurityException if a security manager is present and it
1330          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1331          * @throws NullPointerException if any argument is null
1332          * @since 9
1333          * @hide
1334          */
findVarHandle(Class<?> recv, String name, Class<?> type)1335         public VarHandle findVarHandle(Class<?> recv, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
1336             final Field field = findFieldOfType(recv, name, type);
1337             final boolean isStatic = false;
1338             final boolean performAccessChecks = true;
1339             commonFieldChecks(field, recv, type, isStatic, performAccessChecks);
1340             return FieldVarHandle.create(field);
1341         }
1342         // END Android-changed: OpenJDK 9+181 VarHandle API factory method.
1343 
1344         // BEGIN Android-added: Common field resolution and access check methods.
findFieldOfType(final Class<?> refc, String name, Class<?> type)1345         private Field findFieldOfType(final Class<?> refc, String name, Class<?> type)
1346                 throws NoSuchFieldException {
1347             Field field = null;
1348 
1349             // Search refc and super classes for the field.
1350             for (Class<?> cls = refc; cls != null; cls = cls.getSuperclass()) {
1351                 try {
1352                     field = cls.getDeclaredField(name);
1353                     break;
1354                 } catch (NoSuchFieldException e) {
1355                 }
1356             }
1357 
1358             if (field == null) {
1359                 // Force failure citing refc.
1360                 field = refc.getDeclaredField(name);
1361             }
1362 
1363             final Class<?> fieldType = field.getType();
1364             if (fieldType != type) {
1365                 throw new NoSuchFieldException(name);
1366             }
1367             return field;
1368         }
1369 
commonFieldChecks(Field field, Class<?> refc, Class<?> type, boolean isStatic, boolean performAccessChecks)1370         private void commonFieldChecks(Field field, Class<?> refc, Class<?> type,
1371                                        boolean isStatic, boolean performAccessChecks)
1372                 throws IllegalAccessException {
1373             final int modifiers = field.getModifiers();
1374             if (performAccessChecks) {
1375                 checkAccess(refc, field.getDeclaringClass(), modifiers, field.getName());
1376             }
1377             if (Modifier.isStatic(modifiers) != isStatic) {
1378                 String reason = "Field " + field + " is " +
1379                         (isStatic ? "not " : "") + "static";
1380                 throw new IllegalAccessException(reason);
1381             }
1382         }
1383         // END Android-added: Common field resolution and access check methods.
1384 
1385         /**
1386          * Produces a method handle giving read access to a static field.
1387          * The type of the method handle will have a return type of the field's
1388          * value type.
1389          * The method handle will take no arguments.
1390          * Access checking is performed immediately on behalf of the lookup class.
1391          * <p>
1392          * If the returned method handle is invoked, the field's class will
1393          * be initialized, if it has not already been initialized.
1394          * @param refc the class or interface from which the method is accessed
1395          * @param name the field's name
1396          * @param type the field's type
1397          * @return a method handle which can load values from the field
1398          * @throws NoSuchFieldException if the field does not exist
1399          * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
1400          * @exception SecurityException if a security manager is present and it
1401          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1402          * @throws NullPointerException if any argument is null
1403          */
findStaticGetter(Class<?> refc, String name, Class<?> type)1404         public MethodHandle findStaticGetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
1405             return findAccessor(refc, name, type, MethodHandle.SGET);
1406         }
1407 
1408         /**
1409          * Produces a method handle giving write access to a static field.
1410          * The type of the method handle will have a void return type.
1411          * The method handle will take a single
1412          * argument, of the field's value type, the value to be stored.
1413          * Access checking is performed immediately on behalf of the lookup class.
1414          * <p>
1415          * If the returned method handle is invoked, the field's class will
1416          * be initialized, if it has not already been initialized.
1417          * @param refc the class or interface from which the method is accessed
1418          * @param name the field's name
1419          * @param type the field's type
1420          * @return a method handle which can store values into the field
1421          * @throws NoSuchFieldException if the field does not exist
1422          * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
1423          * @exception SecurityException if a security manager is present and it
1424          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1425          * @throws NullPointerException if any argument is null
1426          */
findStaticSetter(Class<?> refc, String name, Class<?> type)1427         public MethodHandle findStaticSetter(Class<?> refc, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
1428             return findAccessor(refc, name, type, MethodHandle.SPUT);
1429         }
1430 
1431         // BEGIN Android-changed: OpenJDK 9+181 VarHandle API factory method.
1432         /**
1433          * Produces a VarHandle giving access to a static field {@code name} of
1434          * type {@code type} declared in a class of type {@code decl}.
1435          * The VarHandle's variable type is {@code type} and it has no
1436          * coordinate types.
1437          * <p>
1438          * Access checking is performed immediately on behalf of the lookup
1439          * class.
1440          * <p>
1441          * If the returned VarHandle is operated on, the declaring class will be
1442          * initialized, if it has not already been initialized.
1443          * <p>
1444          * Certain access modes of the returned VarHandle are unsupported under
1445          * the following conditions:
1446          * <ul>
1447          * <li>if the field is declared {@code final}, then the write, atomic
1448          *     update, numeric atomic update, and bitwise atomic update access
1449          *     modes are unsupported.
1450          * <li>if the field type is anything other than {@code byte},
1451          *     {@code short}, {@code char}, {@code int}, {@code long},
1452          *     {@code float}, or {@code double}, then numeric atomic update
1453          *     access modes are unsupported.
1454          * <li>if the field type is anything other than {@code boolean},
1455          *     {@code byte}, {@code short}, {@code char}, {@code int} or
1456          *     {@code long} then bitwise atomic update access modes are
1457          *     unsupported.
1458          * </ul>
1459          * <p>
1460          * If the field is declared {@code volatile} then the returned VarHandle
1461          * will override access to the field (effectively ignore the
1462          * {@code volatile} declaration) in accordance to its specified
1463          * access modes.
1464          * <p>
1465          * If the field type is {@code float} or {@code double} then numeric
1466          * and atomic update access modes compare values using their bitwise
1467          * representation (see {@link Float#floatToRawIntBits} and
1468          * {@link Double#doubleToRawLongBits}, respectively).
1469          * @apiNote
1470          * Bitwise comparison of {@code float} values or {@code double} values,
1471          * as performed by the numeric and atomic update access modes, differ
1472          * from the primitive {@code ==} operator and the {@link Float#equals}
1473          * and {@link Double#equals} methods, specifically with respect to
1474          * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
1475          * Care should be taken when performing a compare and set or a compare
1476          * and exchange operation with such values since the operation may
1477          * unexpectedly fail.
1478          * There are many possible NaN values that are considered to be
1479          * {@code NaN} in Java, although no IEEE 754 floating-point operation
1480          * provided by Java can distinguish between them.  Operation failure can
1481          * occur if the expected or witness value is a NaN value and it is
1482          * transformed (perhaps in a platform specific manner) into another NaN
1483          * value, and thus has a different bitwise representation (see
1484          * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
1485          * details).
1486          * The values {@code -0.0} and {@code +0.0} have different bitwise
1487          * representations but are considered equal when using the primitive
1488          * {@code ==} operator.  Operation failure can occur if, for example, a
1489          * numeric algorithm computes an expected value to be say {@code -0.0}
1490          * and previously computed the witness value to be say {@code +0.0}.
1491          * @param decl the class that declares the static field
1492          * @param name the field's name
1493          * @param type the field's type, of type {@code T}
1494          * @return a VarHandle giving access to a static field
1495          * @throws NoSuchFieldException if the field does not exist
1496          * @throws IllegalAccessException if access checking fails, or if the field is not {@code static}
1497          * @exception SecurityException if a security manager is present and it
1498          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1499          * @throws NullPointerException if any argument is null
1500          * @since 9
1501          * @hide
1502          */
findStaticVarHandle(Class<?> decl, String name, Class<?> type)1503         public VarHandle findStaticVarHandle(Class<?> decl, String name, Class<?> type) throws NoSuchFieldException, IllegalAccessException {
1504             final Field field = findFieldOfType(decl, name, type);
1505             final boolean isStatic = true;
1506             final boolean performAccessChecks = true;
1507             commonFieldChecks(field, decl, type, isStatic, performAccessChecks);
1508             return FieldVarHandle.create(field);
1509         }
1510         // END Android-changed: OpenJDK 9+181 VarHandle API factory method.
1511 
1512         /**
1513          * Produces an early-bound method handle for a non-static method.
1514          * The receiver must have a supertype {@code defc} in which a method
1515          * of the given name and type is accessible to the lookup class.
1516          * The method and all its argument types must be accessible to the lookup object.
1517          * The type of the method handle will be that of the method,
1518          * without any insertion of an additional receiver parameter.
1519          * The given receiver will be bound into the method handle,
1520          * so that every call to the method handle will invoke the
1521          * requested method on the given receiver.
1522          * <p>
1523          * The returned method handle will have
1524          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1525          * the method's variable arity modifier bit ({@code 0x0080}) is set
1526          * <em>and</em> the trailing array argument is not the only argument.
1527          * (If the trailing array argument is the only argument,
1528          * the given receiver value will be bound to it.)
1529          * <p>
1530          * This is equivalent to the following code:
1531          * <blockquote><pre>{@code
1532 import static java.lang.invoke.MethodHandles.*;
1533 import static java.lang.invoke.MethodType.*;
1534 ...
1535 MethodHandle mh0 = lookup().findVirtual(defc, name, type);
1536 MethodHandle mh1 = mh0.bindTo(receiver);
1537 MethodType mt1 = mh1.type();
1538 if (mh0.isVarargsCollector())
1539   mh1 = mh1.asVarargsCollector(mt1.parameterType(mt1.parameterCount()-1));
1540 return mh1;
1541          * }</pre></blockquote>
1542          * where {@code defc} is either {@code receiver.getClass()} or a super
1543          * type of that class, in which the requested method is accessible
1544          * to the lookup class.
1545          * (Note that {@code bindTo} does not preserve variable arity.)
1546          * @param receiver the object from which the method is accessed
1547          * @param name the name of the method
1548          * @param type the type of the method, with the receiver argument omitted
1549          * @return the desired method handle
1550          * @throws NoSuchMethodException if the method does not exist
1551          * @throws IllegalAccessException if access checking fails
1552          *                                or if the method's variable arity modifier bit
1553          *                                is set and {@code asVarargsCollector} fails
1554          * @exception SecurityException if a security manager is present and it
1555          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1556          * @throws NullPointerException if any argument is null
1557          * @see MethodHandle#bindTo
1558          * @see #findVirtual
1559          */
bind(Object receiver, String name, MethodType type)1560         public MethodHandle bind(Object receiver, String name, MethodType type) throws NoSuchMethodException, IllegalAccessException {
1561             MethodHandle handle = findVirtual(receiver.getClass(), name, type);
1562             MethodHandle adapter = handle.bindTo(receiver);
1563             MethodType adapterType = adapter.type();
1564             if (handle.isVarargsCollector()) {
1565                 adapter = adapter.asVarargsCollector(
1566                         adapterType.parameterType(adapterType.parameterCount() - 1));
1567             }
1568 
1569             return adapter;
1570         }
1571 
1572         /**
1573          * Makes a <a href="MethodHandleInfo.html#directmh">direct method handle</a>
1574          * to <i>m</i>, if the lookup class has permission.
1575          * If <i>m</i> is non-static, the receiver argument is treated as an initial argument.
1576          * If <i>m</i> is virtual, overriding is respected on every call.
1577          * Unlike the Core Reflection API, exceptions are <em>not</em> wrapped.
1578          * The type of the method handle will be that of the method,
1579          * with the receiver type prepended (but only if it is non-static).
1580          * If the method's {@code accessible} flag is not set,
1581          * access checking is performed immediately on behalf of the lookup class.
1582          * If <i>m</i> is not public, do not share the resulting handle with untrusted parties.
1583          * <p>
1584          * The returned method handle will have
1585          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1586          * the method's variable arity modifier bit ({@code 0x0080}) is set.
1587          * <p>
1588          * If <i>m</i> is static, and
1589          * if the returned method handle is invoked, the method's class will
1590          * be initialized, if it has not already been initialized.
1591          * @param m the reflected method
1592          * @return a method handle which can invoke the reflected method
1593          * @throws IllegalAccessException if access checking fails
1594          *                                or if the method's variable arity modifier bit
1595          *                                is set and {@code asVarargsCollector} fails
1596          * @throws NullPointerException if the argument is null
1597          */
unreflect(Method m)1598         public MethodHandle unreflect(Method m) throws IllegalAccessException {
1599             if (m == null) {
1600                 throw new NullPointerException("m == null");
1601             }
1602 
1603             MethodType methodType = MethodType.methodType(m.getReturnType(),
1604                     m.getParameterTypes());
1605 
1606             // We should only perform access checks if setAccessible hasn't been called yet.
1607             if (!m.isAccessible()) {
1608                 checkAccess(m.getDeclaringClass(), m.getDeclaringClass(), m.getModifiers(),
1609                         m.getName());
1610             }
1611 
1612             if (Modifier.isStatic(m.getModifiers())) {
1613                 return createMethodHandle(m, MethodHandle.INVOKE_STATIC, methodType);
1614             } else {
1615                 methodType = methodType.insertParameterTypes(0, m.getDeclaringClass());
1616                 return createMethodHandle(m, MethodHandle.INVOKE_VIRTUAL, methodType);
1617             }
1618         }
1619 
1620         /**
1621          * Produces a method handle for a reflected method.
1622          * It will bypass checks for overriding methods on the receiver,
1623          * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial}
1624          * instruction from within the explicitly specified {@code specialCaller}.
1625          * The type of the method handle will be that of the method,
1626          * with a suitably restricted receiver type prepended.
1627          * (The receiver type will be {@code specialCaller} or a subtype.)
1628          * If the method's {@code accessible} flag is not set,
1629          * access checking is performed immediately on behalf of the lookup class,
1630          * as if {@code invokespecial} instruction were being linked.
1631          * <p>
1632          * Before method resolution,
1633          * if the explicitly specified caller class is not identical with the
1634          * lookup class, or if this lookup object does not have
1635          * <a href="MethodHandles.Lookup.html#privacc">private access</a>
1636          * privileges, the access fails.
1637          * <p>
1638          * The returned method handle will have
1639          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1640          * the method's variable arity modifier bit ({@code 0x0080}) is set.
1641          * @param m the reflected method
1642          * @param specialCaller the class nominally calling the method
1643          * @return a method handle which can invoke the reflected method
1644          * @throws IllegalAccessException if access checking fails
1645          *                                or if the method's variable arity modifier bit
1646          *                                is set and {@code asVarargsCollector} fails
1647          * @throws NullPointerException if any argument is null
1648          */
unreflectSpecial(Method m, Class<?> specialCaller)1649         public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException {
1650             if (m == null) {
1651                 throw new NullPointerException("m == null");
1652             }
1653 
1654             if (specialCaller == null) {
1655                 throw new NullPointerException("specialCaller == null");
1656             }
1657 
1658             if (!m.isAccessible()) {
1659                 // Android-changed: Match Java language 9 behavior where unreflectSpecial continues
1660                 // to require exact caller lookupClass match.
1661                 checkSpecialCaller(specialCaller, null);
1662             }
1663 
1664             final MethodType methodType = MethodType.methodType(m.getReturnType(),
1665                     m.getParameterTypes());
1666             return findSpecial(m, methodType, m.getDeclaringClass() /* refc */, specialCaller);
1667         }
1668 
1669         /**
1670          * Produces a method handle for a reflected constructor.
1671          * The type of the method handle will be that of the constructor,
1672          * with the return type changed to the declaring class.
1673          * The method handle will perform a {@code newInstance} operation,
1674          * creating a new instance of the constructor's class on the
1675          * arguments passed to the method handle.
1676          * <p>
1677          * If the constructor's {@code accessible} flag is not set,
1678          * access checking is performed immediately on behalf of the lookup class.
1679          * <p>
1680          * The returned method handle will have
1681          * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1682          * the constructor's variable arity modifier bit ({@code 0x0080}) is set.
1683          * <p>
1684          * If the returned method handle is invoked, the constructor's class will
1685          * be initialized, if it has not already been initialized.
1686          * @param c the reflected constructor
1687          * @return a method handle which can invoke the reflected constructor
1688          * @throws IllegalAccessException if access checking fails
1689          *                                or if the method's variable arity modifier bit
1690          *                                is set and {@code asVarargsCollector} fails
1691          * @throws NullPointerException if the argument is null
1692          */
unreflectConstructor(Constructor<?> c)1693         public MethodHandle unreflectConstructor(Constructor<?> c) throws IllegalAccessException {
1694             if (c == null) {
1695                 throw new NullPointerException("c == null");
1696             }
1697 
1698             if (!c.isAccessible()) {
1699                 checkAccess(c.getDeclaringClass(), c.getDeclaringClass(), c.getModifiers(),
1700                         c.getName());
1701             }
1702 
1703             return createMethodHandleForConstructor(c);
1704         }
1705 
1706         /**
1707          * Produces a method handle giving read access to a reflected field.
1708          * The type of the method handle will have a return type of the field's
1709          * value type.
1710          * If the field is static, the method handle will take no arguments.
1711          * Otherwise, its single argument will be the instance containing
1712          * the field.
1713          * If the field's {@code accessible} flag is not set,
1714          * access checking is performed immediately on behalf of the lookup class.
1715          * <p>
1716          * If the field is static, and
1717          * if the returned method handle is invoked, the field's class will
1718          * be initialized, if it has not already been initialized.
1719          * @param f the reflected field
1720          * @return a method handle which can load values from the reflected field
1721          * @throws IllegalAccessException if access checking fails
1722          * @throws NullPointerException if the argument is null
1723          */
unreflectGetter(Field f)1724         public MethodHandle unreflectGetter(Field f) throws IllegalAccessException {
1725             return findAccessor(f, f.getDeclaringClass(), f.getType(),
1726                     Modifier.isStatic(f.getModifiers()) ? MethodHandle.SGET : MethodHandle.IGET,
1727                     !f.isAccessible() /* performAccessChecks */);
1728         }
1729 
1730         /**
1731          * Produces a method handle giving write access to a reflected field.
1732          * The type of the method handle will have a void return type.
1733          * If the field is static, the method handle will take a single
1734          * argument, of the field's value type, the value to be stored.
1735          * Otherwise, the two arguments will be the instance containing
1736          * the field, and the value to be stored.
1737          * If the field's {@code accessible} flag is not set,
1738          * access checking is performed immediately on behalf of the lookup class.
1739          * <p>
1740          * If the field is static, and
1741          * if the returned method handle is invoked, the field's class will
1742          * be initialized, if it has not already been initialized.
1743          * @param f the reflected field
1744          * @return a method handle which can store values into the reflected field
1745          * @throws IllegalAccessException if access checking fails
1746          * @throws NullPointerException if the argument is null
1747          */
unreflectSetter(Field f)1748         public MethodHandle unreflectSetter(Field f) throws IllegalAccessException {
1749             return findAccessor(f, f.getDeclaringClass(), f.getType(),
1750                     Modifier.isStatic(f.getModifiers()) ? MethodHandle.SPUT : MethodHandle.IPUT,
1751                     !f.isAccessible() /* performAccessChecks */);
1752         }
1753 
1754         // BEGIN Android-changed: OpenJDK 9+181 VarHandle API factory method.
1755         /**
1756          * Produces a VarHandle giving access to a reflected field {@code f}
1757          * of type {@code T} declared in a class of type {@code R}.
1758          * The VarHandle's variable type is {@code T}.
1759          * If the field is non-static the VarHandle has one coordinate type,
1760          * {@code R}.  Otherwise, the field is static, and the VarHandle has no
1761          * coordinate types.
1762          * <p>
1763          * Access checking is performed immediately on behalf of the lookup
1764          * class, regardless of the value of the field's {@code accessible}
1765          * flag.
1766          * <p>
1767          * If the field is static, and if the returned VarHandle is operated
1768          * on, the field's declaring class will be initialized, if it has not
1769          * already been initialized.
1770          * <p>
1771          * Certain access modes of the returned VarHandle are unsupported under
1772          * the following conditions:
1773          * <ul>
1774          * <li>if the field is declared {@code final}, then the write, atomic
1775          *     update, numeric atomic update, and bitwise atomic update access
1776          *     modes are unsupported.
1777          * <li>if the field type is anything other than {@code byte},
1778          *     {@code short}, {@code char}, {@code int}, {@code long},
1779          *     {@code float}, or {@code double} then numeric atomic update
1780          *     access modes are unsupported.
1781          * <li>if the field type is anything other than {@code boolean},
1782          *     {@code byte}, {@code short}, {@code char}, {@code int} or
1783          *     {@code long} then bitwise atomic update access modes are
1784          *     unsupported.
1785          * </ul>
1786          * <p>
1787          * If the field is declared {@code volatile} then the returned VarHandle
1788          * will override access to the field (effectively ignore the
1789          * {@code volatile} declaration) in accordance to its specified
1790          * access modes.
1791          * <p>
1792          * If the field type is {@code float} or {@code double} then numeric
1793          * and atomic update access modes compare values using their bitwise
1794          * representation (see {@link Float#floatToRawIntBits} and
1795          * {@link Double#doubleToRawLongBits}, respectively).
1796          * @apiNote
1797          * Bitwise comparison of {@code float} values or {@code double} values,
1798          * as performed by the numeric and atomic update access modes, differ
1799          * from the primitive {@code ==} operator and the {@link Float#equals}
1800          * and {@link Double#equals} methods, specifically with respect to
1801          * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
1802          * Care should be taken when performing a compare and set or a compare
1803          * and exchange operation with such values since the operation may
1804          * unexpectedly fail.
1805          * There are many possible NaN values that are considered to be
1806          * {@code NaN} in Java, although no IEEE 754 floating-point operation
1807          * provided by Java can distinguish between them.  Operation failure can
1808          * occur if the expected or witness value is a NaN value and it is
1809          * transformed (perhaps in a platform specific manner) into another NaN
1810          * value, and thus has a different bitwise representation (see
1811          * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
1812          * details).
1813          * The values {@code -0.0} and {@code +0.0} have different bitwise
1814          * representations but are considered equal when using the primitive
1815          * {@code ==} operator.  Operation failure can occur if, for example, a
1816          * numeric algorithm computes an expected value to be say {@code -0.0}
1817          * and previously computed the witness value to be say {@code +0.0}.
1818          * @param f the reflected field, with a field of type {@code T}, and
1819          * a declaring class of type {@code R}
1820          * @return a VarHandle giving access to non-static fields or a static
1821          * field
1822          * @throws IllegalAccessException if access checking fails
1823          * @throws NullPointerException if the argument is null
1824          * @since 9
1825          * @hide
1826          */
unreflectVarHandle(Field f)1827         public VarHandle unreflectVarHandle(Field f) throws IllegalAccessException {
1828             final boolean isStatic = Modifier.isStatic(f.getModifiers());
1829             final boolean performAccessChecks = true;
1830             commonFieldChecks(f, f.getDeclaringClass(), f.getType(), isStatic, performAccessChecks);
1831             return FieldVarHandle.create(f);
1832         }
1833         // END Android-changed: OpenJDK 9+181 VarHandle API factory method.
1834 
1835         /**
1836          * Cracks a <a href="MethodHandleInfo.html#directmh">direct method handle</a>
1837          * created by this lookup object or a similar one.
1838          * Security and access checks are performed to ensure that this lookup object
1839          * is capable of reproducing the target method handle.
1840          * This means that the cracking may fail if target is a direct method handle
1841          * but was created by an unrelated lookup object.
1842          * This can happen if the method handle is <a href="MethodHandles.Lookup.html#callsens">caller sensitive</a>
1843          * and was created by a lookup object for a different class.
1844          * @param target a direct method handle to crack into symbolic reference components
1845          * @return a symbolic reference which can be used to reconstruct this method handle from this lookup object
1846          * @exception SecurityException if a security manager is present and it
1847          *                              <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1848          * @throws IllegalArgumentException if the target is not a direct method handle or if access checking fails
1849          * @exception NullPointerException if the target is {@code null}
1850          * @see MethodHandleInfo
1851          * @since 1.8
1852          */
revealDirect(MethodHandle target)1853         public MethodHandleInfo revealDirect(MethodHandle target) {
1854             MethodHandleImpl directTarget = getMethodHandleImpl(target);
1855             MethodHandleInfo info = directTarget.reveal();
1856 
1857             try {
1858                 checkAccess(lookupClass(), info.getDeclaringClass(), info.getModifiers(),
1859                         info.getName());
1860             } catch (IllegalAccessException exception) {
1861                 throw new IllegalArgumentException("Unable to access memeber.", exception);
1862             }
1863 
1864             return info;
1865         }
1866 
hasPrivateAccess()1867         private boolean hasPrivateAccess() {
1868             return (allowedModes & PRIVATE) != 0;
1869         }
1870 
1871         /** Check public/protected/private bits on the symbolic reference class and its member. */
checkAccess(Class<?> refc, Class<?> defc, int mods, String methName)1872         void checkAccess(Class<?> refc, Class<?> defc, int mods, String methName)
1873                 throws IllegalAccessException {
1874             int allowedModes = this.allowedModes;
1875 
1876             if (Modifier.isProtected(mods) &&
1877                     defc == Object.class &&
1878                     "clone".equals(methName) &&
1879                     refc.isArray()) {
1880                 // The JVM does this hack also.
1881                 // (See ClassVerifier::verify_invoke_instructions
1882                 // and LinkResolver::check_method_accessability.)
1883                 // Because the JVM does not allow separate methods on array types,
1884                 // there is no separate method for int[].clone.
1885                 // All arrays simply inherit Object.clone.
1886                 // But for access checking logic, we make Object.clone
1887                 // (normally protected) appear to be public.
1888                 // Later on, when the DirectMethodHandle is created,
1889                 // its leading argument will be restricted to the
1890                 // requested array type.
1891                 // N.B. The return type is not adjusted, because
1892                 // that is *not* the bytecode behavior.
1893                 mods ^= Modifier.PROTECTED | Modifier.PUBLIC;
1894             }
1895 
1896             if (Modifier.isProtected(mods) && Modifier.isConstructor(mods)) {
1897                 // cannot "new" a protected ctor in a different package
1898                 mods ^= Modifier.PROTECTED;
1899             }
1900 
1901             if (Modifier.isPublic(mods) && Modifier.isPublic(refc.getModifiers()) && allowedModes != 0)
1902                 return;  // common case
1903             int requestedModes = fixmods(mods);  // adjust 0 => PACKAGE
1904             if ((requestedModes & allowedModes) != 0) {
1905                 if (VerifyAccess.isMemberAccessible(refc, defc, mods, lookupClass(), allowedModes))
1906                     return;
1907             } else {
1908                 // Protected members can also be checked as if they were package-private.
1909                 if ((requestedModes & PROTECTED) != 0 && (allowedModes & PACKAGE) != 0
1910                         && VerifyAccess.isSamePackage(defc, lookupClass()))
1911                     return;
1912             }
1913 
1914             throwMakeAccessException(accessFailedMessage(refc, defc, mods), this);
1915         }
1916 
accessFailedMessage(Class<?> refc, Class<?> defc, int mods)1917         String accessFailedMessage(Class<?> refc, Class<?> defc, int mods) {
1918             // check the class first:
1919             boolean classOK = (Modifier.isPublic(defc.getModifiers()) &&
1920                     (defc == refc ||
1921                             Modifier.isPublic(refc.getModifiers())));
1922             if (!classOK && (allowedModes & PACKAGE) != 0) {
1923                 classOK = (VerifyAccess.isClassAccessible(defc, lookupClass(), ALL_MODES) &&
1924                         (defc == refc ||
1925                                 VerifyAccess.isClassAccessible(refc, lookupClass(), ALL_MODES)));
1926             }
1927             if (!classOK)
1928                 return "class is not public";
1929             if (Modifier.isPublic(mods))
1930                 return "access to public member failed";  // (how?)
1931             if (Modifier.isPrivate(mods))
1932                 return "member is private";
1933             if (Modifier.isProtected(mods))
1934                 return "member is protected";
1935             return "member is private to package";
1936         }
1937 
1938         // Android-changed: checkSpecialCaller assumes that ALLOW_NESTMATE_ACCESS = false,
1939         // as in upstream OpenJDK.
1940         //
1941         // private static final boolean ALLOW_NESTMATE_ACCESS = false;
1942 
1943         // Android-changed: Match java language 9 behavior allowing special access if the reflected
1944         // class (called 'refc', the class from which the method is being accessed) is an interface
1945         // and is implemented by the caller.
checkSpecialCaller(Class<?> specialCaller, Class<?> refc)1946         private void checkSpecialCaller(Class<?> specialCaller, Class<?> refc) throws IllegalAccessException {
1947             // Android-changed: No support for TRUSTED lookups. Also construct the
1948             // IllegalAccessException by hand because the upstream code implicitly assumes
1949             // that the lookupClass == specialCaller.
1950             //
1951             // if (allowedModes == TRUSTED)  return;
1952             boolean isInterfaceLookup = (refc != null &&
1953                                          refc.isInterface() &&
1954                                          refc.isAssignableFrom(specialCaller));
1955             if (!hasPrivateAccess() || (specialCaller != lookupClass() && !isInterfaceLookup)) {
1956                 throw new IllegalAccessException("no private access for invokespecial : "
1957                         + specialCaller + ", from" + this);
1958             }
1959         }
1960 
throwMakeAccessException(String message, Object from)1961         private void throwMakeAccessException(String message, Object from) throws
1962                 IllegalAccessException{
1963             message = message + ": "+ toString();
1964             if (from != null)  message += ", from " + from;
1965             throw new IllegalAccessException(message);
1966         }
1967 
checkReturnType(Method method, MethodType methodType)1968         private void checkReturnType(Method method, MethodType methodType)
1969                 throws NoSuchMethodException {
1970             if (method.getReturnType() != methodType.rtype()) {
1971                 throw new NoSuchMethodException(method.getName() + methodType);
1972             }
1973         }
1974     }
1975 
1976     /**
1977      * "Cracks" {@code target} to reveal the underlying {@code MethodHandleImpl}.
1978      */
getMethodHandleImpl(MethodHandle target)1979     private static MethodHandleImpl getMethodHandleImpl(MethodHandle target) {
1980         // Special case : We implement handles to constructors as transformers,
1981         // so we must extract the underlying handle from the transformer.
1982         if (target instanceof Transformers.Construct) {
1983             target = ((Transformers.Construct) target).getConstructorHandle();
1984         }
1985 
1986         // Special case: Var-args methods are also implemented as Transformers,
1987         // so we should get the underlying handle in that case as well.
1988         if (target instanceof Transformers.VarargsCollector) {
1989             target = target.asFixedArity();
1990         }
1991 
1992         if (target instanceof MethodHandleImpl) {
1993             return (MethodHandleImpl) target;
1994         }
1995 
1996         throw new IllegalArgumentException(target + " is not a direct handle");
1997     }
1998 
1999     // BEGIN Android-added: method to check if a class is an array.
checkClassIsArray(Class<?> c)2000     private static void checkClassIsArray(Class<?> c) {
2001         if (!c.isArray()) {
2002             throw new IllegalArgumentException("Not an array type: " + c);
2003         }
2004     }
2005 
checkTypeIsViewable(Class<?> componentType)2006     private static void checkTypeIsViewable(Class<?> componentType) {
2007         if (componentType == short.class ||
2008             componentType == char.class ||
2009             componentType == int.class ||
2010             componentType == long.class ||
2011             componentType == float.class ||
2012             componentType == double.class) {
2013             return;
2014         }
2015         throw new UnsupportedOperationException("Component type not supported: " + componentType);
2016     }
2017     // END Android-added: method to check if a class is an array.
2018 
2019     /**
2020      * Produces a method handle giving read access to elements of an array.
2021      * The type of the method handle will have a return type of the array's
2022      * element type.  Its first argument will be the array type,
2023      * and the second will be {@code int}.
2024      * @param arrayClass an array type
2025      * @return a method handle which can load values from the given array type
2026      * @throws NullPointerException if the argument is null
2027      * @throws  IllegalArgumentException if arrayClass is not an array type
2028      */
2029     public static
arrayElementGetter(Class<?> arrayClass)2030     MethodHandle arrayElementGetter(Class<?> arrayClass) throws IllegalArgumentException {
2031         checkClassIsArray(arrayClass);
2032         final Class<?> componentType = arrayClass.getComponentType();
2033         if (componentType.isPrimitive()) {
2034             try {
2035                 return Lookup.PUBLIC_LOOKUP.findStatic(MethodHandles.class,
2036                         "arrayElementGetter",
2037                         MethodType.methodType(componentType, arrayClass, int.class));
2038             } catch (NoSuchMethodException | IllegalAccessException exception) {
2039                 throw new AssertionError(exception);
2040             }
2041         }
2042 
2043         return new Transformers.ReferenceArrayElementGetter(arrayClass);
2044     }
2045 
arrayElementGetter(byte[] array, int i)2046     /** @hide */ public static byte arrayElementGetter(byte[] array, int i) { return array[i]; }
arrayElementGetter(boolean[] array, int i)2047     /** @hide */ public static boolean arrayElementGetter(boolean[] array, int i) { return array[i]; }
arrayElementGetter(char[] array, int i)2048     /** @hide */ public static char arrayElementGetter(char[] array, int i) { return array[i]; }
arrayElementGetter(short[] array, int i)2049     /** @hide */ public static short arrayElementGetter(short[] array, int i) { return array[i]; }
arrayElementGetter(int[] array, int i)2050     /** @hide */ public static int arrayElementGetter(int[] array, int i) { return array[i]; }
arrayElementGetter(long[] array, int i)2051     /** @hide */ public static long arrayElementGetter(long[] array, int i) { return array[i]; }
arrayElementGetter(float[] array, int i)2052     /** @hide */ public static float arrayElementGetter(float[] array, int i) { return array[i]; }
arrayElementGetter(double[] array, int i)2053     /** @hide */ public static double arrayElementGetter(double[] array, int i) { return array[i]; }
2054 
2055     /**
2056      * Produces a method handle giving write access to elements of an array.
2057      * The type of the method handle will have a void return type.
2058      * Its last argument will be the array's element type.
2059      * The first and second arguments will be the array type and int.
2060      * @param arrayClass the class of an array
2061      * @return a method handle which can store values into the array type
2062      * @throws NullPointerException if the argument is null
2063      * @throws IllegalArgumentException if arrayClass is not an array type
2064      */
2065     public static
arrayElementSetter(Class<?> arrayClass)2066     MethodHandle arrayElementSetter(Class<?> arrayClass) throws IllegalArgumentException {
2067         checkClassIsArray(arrayClass);
2068         final Class<?> componentType = arrayClass.getComponentType();
2069         if (componentType.isPrimitive()) {
2070             try {
2071                 return Lookup.PUBLIC_LOOKUP.findStatic(MethodHandles.class,
2072                         "arrayElementSetter",
2073                         MethodType.methodType(void.class, arrayClass, int.class, componentType));
2074             } catch (NoSuchMethodException | IllegalAccessException exception) {
2075                 throw new AssertionError(exception);
2076             }
2077         }
2078 
2079         return new Transformers.ReferenceArrayElementSetter(arrayClass);
2080     }
2081 
2082     /** @hide */
arrayElementSetter(byte[] array, int i, byte val)2083     public static void arrayElementSetter(byte[] array, int i, byte val) { array[i] = val; }
2084     /** @hide */
arrayElementSetter(boolean[] array, int i, boolean val)2085     public static void arrayElementSetter(boolean[] array, int i, boolean val) { array[i] = val; }
2086     /** @hide */
arrayElementSetter(char[] array, int i, char val)2087     public static void arrayElementSetter(char[] array, int i, char val) { array[i] = val; }
2088     /** @hide */
arrayElementSetter(short[] array, int i, short val)2089     public static void arrayElementSetter(short[] array, int i, short val) { array[i] = val; }
2090     /** @hide */
arrayElementSetter(int[] array, int i, int val)2091     public static void arrayElementSetter(int[] array, int i, int val) { array[i] = val; }
2092     /** @hide */
arrayElementSetter(long[] array, int i, long val)2093     public static void arrayElementSetter(long[] array, int i, long val) { array[i] = val; }
2094     /** @hide */
arrayElementSetter(float[] array, int i, float val)2095     public static void arrayElementSetter(float[] array, int i, float val) { array[i] = val; }
2096     /** @hide */
arrayElementSetter(double[] array, int i, double val)2097     public static void arrayElementSetter(double[] array, int i, double val) { array[i] = val; }
2098 
2099     // BEGIN Android-changed: OpenJDK 9+181 VarHandle API factory methods.
2100     /**
2101      * Produces a VarHandle giving access to elements of an array of type
2102      * {@code arrayClass}.  The VarHandle's variable type is the component type
2103      * of {@code arrayClass} and the list of coordinate types is
2104      * {@code (arrayClass, int)}, where the {@code int} coordinate type
2105      * corresponds to an argument that is an index into an array.
2106      * <p>
2107      * Certain access modes of the returned VarHandle are unsupported under
2108      * the following conditions:
2109      * <ul>
2110      * <li>if the component type is anything other than {@code byte},
2111      *     {@code short}, {@code char}, {@code int}, {@code long},
2112      *     {@code float}, or {@code double} then numeric atomic update access
2113      *     modes are unsupported.
2114      * <li>if the field type is anything other than {@code boolean},
2115      *     {@code byte}, {@code short}, {@code char}, {@code int} or
2116      *     {@code long} then bitwise atomic update access modes are
2117      *     unsupported.
2118      * </ul>
2119      * <p>
2120      * If the component type is {@code float} or {@code double} then numeric
2121      * and atomic update access modes compare values using their bitwise
2122      * representation (see {@link Float#floatToRawIntBits} and
2123      * {@link Double#doubleToRawLongBits}, respectively).
2124      * @apiNote
2125      * Bitwise comparison of {@code float} values or {@code double} values,
2126      * as performed by the numeric and atomic update access modes, differ
2127      * from the primitive {@code ==} operator and the {@link Float#equals}
2128      * and {@link Double#equals} methods, specifically with respect to
2129      * comparing NaN values or comparing {@code -0.0} with {@code +0.0}.
2130      * Care should be taken when performing a compare and set or a compare
2131      * and exchange operation with such values since the operation may
2132      * unexpectedly fail.
2133      * There are many possible NaN values that are considered to be
2134      * {@code NaN} in Java, although no IEEE 754 floating-point operation
2135      * provided by Java can distinguish between them.  Operation failure can
2136      * occur if the expected or witness value is a NaN value and it is
2137      * transformed (perhaps in a platform specific manner) into another NaN
2138      * value, and thus has a different bitwise representation (see
2139      * {@link Float#intBitsToFloat} or {@link Double#longBitsToDouble} for more
2140      * details).
2141      * The values {@code -0.0} and {@code +0.0} have different bitwise
2142      * representations but are considered equal when using the primitive
2143      * {@code ==} operator.  Operation failure can occur if, for example, a
2144      * numeric algorithm computes an expected value to be say {@code -0.0}
2145      * and previously computed the witness value to be say {@code +0.0}.
2146      * @param arrayClass the class of an array, of type {@code T[]}
2147      * @return a VarHandle giving access to elements of an array
2148      * @throws NullPointerException if the arrayClass is null
2149      * @throws IllegalArgumentException if arrayClass is not an array type
2150      * @since 9
2151      * @hide
2152      */
2153     public static
arrayElementVarHandle(Class<?> arrayClass)2154     VarHandle arrayElementVarHandle(Class<?> arrayClass) throws IllegalArgumentException {
2155         checkClassIsArray(arrayClass);
2156         return ArrayElementVarHandle.create(arrayClass);
2157     }
2158 
2159     /**
2160      * Produces a VarHandle giving access to elements of a {@code byte[]} array
2161      * viewed as if it were a different primitive array type, such as
2162      * {@code int[]} or {@code long[]}.
2163      * The VarHandle's variable type is the component type of
2164      * {@code viewArrayClass} and the list of coordinate types is
2165      * {@code (byte[], int)}, where the {@code int} coordinate type
2166      * corresponds to an argument that is an index into a {@code byte[]} array.
2167      * The returned VarHandle accesses bytes at an index in a {@code byte[]}
2168      * array, composing bytes to or from a value of the component type of
2169      * {@code viewArrayClass} according to the given endianness.
2170      * <p>
2171      * The supported component types (variables types) are {@code short},
2172      * {@code char}, {@code int}, {@code long}, {@code float} and
2173      * {@code double}.
2174      * <p>
2175      * Access of bytes at a given index will result in an
2176      * {@code IndexOutOfBoundsException} if the index is less than {@code 0}
2177      * or greater than the {@code byte[]} array length minus the size (in bytes)
2178      * of {@code T}.
2179      * <p>
2180      * Access of bytes at an index may be aligned or misaligned for {@code T},
2181      * with respect to the underlying memory address, {@code A} say, associated
2182      * with the array and index.
2183      * If access is misaligned then access for anything other than the
2184      * {@code get} and {@code set} access modes will result in an
2185      * {@code IllegalStateException}.  In such cases atomic access is only
2186      * guaranteed with respect to the largest power of two that divides the GCD
2187      * of {@code A} and the size (in bytes) of {@code T}.
2188      * If access is aligned then following access modes are supported and are
2189      * guaranteed to support atomic access:
2190      * <ul>
2191      * <li>read write access modes for all {@code T}, with the exception of
2192      *     access modes {@code get} and {@code set} for {@code long} and
2193      *     {@code double} on 32-bit platforms.
2194      * <li>atomic update access modes for {@code int}, {@code long},
2195      *     {@code float} or {@code double}.
2196      *     (Future major platform releases of the JDK may support additional
2197      *     types for certain currently unsupported access modes.)
2198      * <li>numeric atomic update access modes for {@code int} and {@code long}.
2199      *     (Future major platform releases of the JDK may support additional
2200      *     numeric types for certain currently unsupported access modes.)
2201      * <li>bitwise atomic update access modes for {@code int} and {@code long}.
2202      *     (Future major platform releases of the JDK may support additional
2203      *     numeric types for certain currently unsupported access modes.)
2204      * </ul>
2205      * <p>
2206      * Misaligned access, and therefore atomicity guarantees, may be determined
2207      * for {@code byte[]} arrays without operating on a specific array.  Given
2208      * an {@code index}, {@code T} and it's corresponding boxed type,
2209      * {@code T_BOX}, misalignment may be determined as follows:
2210      * <pre>{@code
2211      * int sizeOfT = T_BOX.BYTES;  // size in bytes of T
2212      * int misalignedAtZeroIndex = ByteBuffer.wrap(new byte[0]).
2213      *     alignmentOffset(0, sizeOfT);
2214      * int misalignedAtIndex = (misalignedAtZeroIndex + index) % sizeOfT;
2215      * boolean isMisaligned = misalignedAtIndex != 0;
2216      * }</pre>
2217      * <p>
2218      * If the variable type is {@code float} or {@code double} then atomic
2219      * update access modes compare values using their bitwise representation
2220      * (see {@link Float#floatToRawIntBits} and
2221      * {@link Double#doubleToRawLongBits}, respectively).
2222      * @param viewArrayClass the view array class, with a component type of
2223      * type {@code T}
2224      * @param byteOrder the endianness of the view array elements, as
2225      * stored in the underlying {@code byte} array
2226      * @return a VarHandle giving access to elements of a {@code byte[]} array
2227      * viewed as if elements corresponding to the components type of the view
2228      * array class
2229      * @throws NullPointerException if viewArrayClass or byteOrder is null
2230      * @throws IllegalArgumentException if viewArrayClass is not an array type
2231      * @throws UnsupportedOperationException if the component type of
2232      * viewArrayClass is not supported as a variable type
2233      * @since 9
2234      * @hide
2235      */
2236     public static
byteArrayViewVarHandle(Class<?> viewArrayClass, ByteOrder byteOrder)2237     VarHandle byteArrayViewVarHandle(Class<?> viewArrayClass,
2238                                      ByteOrder byteOrder) throws IllegalArgumentException {
2239         checkClassIsArray(viewArrayClass);
2240         checkTypeIsViewable(viewArrayClass.getComponentType());
2241         return ByteArrayViewVarHandle.create(viewArrayClass, byteOrder);
2242     }
2243 
2244     /**
2245      * Produces a VarHandle giving access to elements of a {@code ByteBuffer}
2246      * viewed as if it were an array of elements of a different primitive
2247      * component type to that of {@code byte}, such as {@code int[]} or
2248      * {@code long[]}.
2249      * The VarHandle's variable type is the component type of
2250      * {@code viewArrayClass} and the list of coordinate types is
2251      * {@code (ByteBuffer, int)}, where the {@code int} coordinate type
2252      * corresponds to an argument that is an index into a {@code byte[]} array.
2253      * The returned VarHandle accesses bytes at an index in a
2254      * {@code ByteBuffer}, composing bytes to or from a value of the component
2255      * type of {@code viewArrayClass} according to the given endianness.
2256      * <p>
2257      * The supported component types (variables types) are {@code short},
2258      * {@code char}, {@code int}, {@code long}, {@code float} and
2259      * {@code double}.
2260      * <p>
2261      * Access will result in a {@code ReadOnlyBufferException} for anything
2262      * other than the read access modes if the {@code ByteBuffer} is read-only.
2263      * <p>
2264      * Access of bytes at a given index will result in an
2265      * {@code IndexOutOfBoundsException} if the index is less than {@code 0}
2266      * or greater than the {@code ByteBuffer} limit minus the size (in bytes) of
2267      * {@code T}.
2268      * <p>
2269      * Access of bytes at an index may be aligned or misaligned for {@code T},
2270      * with respect to the underlying memory address, {@code A} say, associated
2271      * with the {@code ByteBuffer} and index.
2272      * If access is misaligned then access for anything other than the
2273      * {@code get} and {@code set} access modes will result in an
2274      * {@code IllegalStateException}.  In such cases atomic access is only
2275      * guaranteed with respect to the largest power of two that divides the GCD
2276      * of {@code A} and the size (in bytes) of {@code T}.
2277      * If access is aligned then following access modes are supported and are
2278      * guaranteed to support atomic access:
2279      * <ul>
2280      * <li>read write access modes for all {@code T}, with the exception of
2281      *     access modes {@code get} and {@code set} for {@code long} and
2282      *     {@code double} on 32-bit platforms.
2283      * <li>atomic update access modes for {@code int}, {@code long},
2284      *     {@code float} or {@code double}.
2285      *     (Future major platform releases of the JDK may support additional
2286      *     types for certain currently unsupported access modes.)
2287      * <li>numeric atomic update access modes for {@code int} and {@code long}.
2288      *     (Future major platform releases of the JDK may support additional
2289      *     numeric types for certain currently unsupported access modes.)
2290      * <li>bitwise atomic update access modes for {@code int} and {@code long}.
2291      *     (Future major platform releases of the JDK may support additional
2292      *     numeric types for certain currently unsupported access modes.)
2293      * </ul>
2294      * <p>
2295      * Misaligned access, and therefore atomicity guarantees, may be determined
2296      * for a {@code ByteBuffer}, {@code bb} (direct or otherwise), an
2297      * {@code index}, {@code T} and it's corresponding boxed type,
2298      * {@code T_BOX}, as follows:
2299      * <pre>{@code
2300      * int sizeOfT = T_BOX.BYTES;  // size in bytes of T
2301      * ByteBuffer bb = ...
2302      * int misalignedAtIndex = bb.alignmentOffset(index, sizeOfT);
2303      * boolean isMisaligned = misalignedAtIndex != 0;
2304      * }</pre>
2305      * <p>
2306      * If the variable type is {@code float} or {@code double} then atomic
2307      * update access modes compare values using their bitwise representation
2308      * (see {@link Float#floatToRawIntBits} and
2309      * {@link Double#doubleToRawLongBits}, respectively).
2310      * @param viewArrayClass the view array class, with a component type of
2311      * type {@code T}
2312      * @param byteOrder the endianness of the view array elements, as
2313      * stored in the underlying {@code ByteBuffer} (Note this overrides the
2314      * endianness of a {@code ByteBuffer})
2315      * @return a VarHandle giving access to elements of a {@code ByteBuffer}
2316      * viewed as if elements corresponding to the components type of the view
2317      * array class
2318      * @throws NullPointerException if viewArrayClass or byteOrder is null
2319      * @throws IllegalArgumentException if viewArrayClass is not an array type
2320      * @throws UnsupportedOperationException if the component type of
2321      * viewArrayClass is not supported as a variable type
2322      * @since 9
2323      * @hide
2324      */
2325     public static
byteBufferViewVarHandle(Class<?> viewArrayClass, ByteOrder byteOrder)2326     VarHandle byteBufferViewVarHandle(Class<?> viewArrayClass,
2327                                       ByteOrder byteOrder) throws IllegalArgumentException {
2328         checkClassIsArray(viewArrayClass);
2329         checkTypeIsViewable(viewArrayClass.getComponentType());
2330         return ByteBufferViewVarHandle.create(viewArrayClass, byteOrder);
2331     }
2332     // END Android-changed: OpenJDK 9+181 VarHandle API factory methods.
2333 
2334     /// method handle invocation (reflective style)
2335 
2336     /**
2337      * Produces a method handle which will invoke any method handle of the
2338      * given {@code type}, with a given number of trailing arguments replaced by
2339      * a single trailing {@code Object[]} array.
2340      * The resulting invoker will be a method handle with the following
2341      * arguments:
2342      * <ul>
2343      * <li>a single {@code MethodHandle} target
2344      * <li>zero or more leading values (counted by {@code leadingArgCount})
2345      * <li>an {@code Object[]} array containing trailing arguments
2346      * </ul>
2347      * <p>
2348      * The invoker will invoke its target like a call to {@link MethodHandle#invoke invoke} with
2349      * the indicated {@code type}.
2350      * That is, if the target is exactly of the given {@code type}, it will behave
2351      * like {@code invokeExact}; otherwise it behave as if {@link MethodHandle#asType asType}
2352      * is used to convert the target to the required {@code type}.
2353      * <p>
2354      * The type of the returned invoker will not be the given {@code type}, but rather
2355      * will have all parameters except the first {@code leadingArgCount}
2356      * replaced by a single array of type {@code Object[]}, which will be
2357      * the final parameter.
2358      * <p>
2359      * Before invoking its target, the invoker will spread the final array, apply
2360      * reference casts as necessary, and unbox and widen primitive arguments.
2361      * If, when the invoker is called, the supplied array argument does
2362      * not have the correct number of elements, the invoker will throw
2363      * an {@link IllegalArgumentException} instead of invoking the target.
2364      * <p>
2365      * This method is equivalent to the following code (though it may be more efficient):
2366      * <blockquote><pre>{@code
2367 MethodHandle invoker = MethodHandles.invoker(type);
2368 int spreadArgCount = type.parameterCount() - leadingArgCount;
2369 invoker = invoker.asSpreader(Object[].class, spreadArgCount);
2370 return invoker;
2371      * }</pre></blockquote>
2372      * This method throws no reflective or security exceptions.
2373      * @param type the desired target type
2374      * @param leadingArgCount number of fixed arguments, to be passed unchanged to the target
2375      * @return a method handle suitable for invoking any method handle of the given type
2376      * @throws NullPointerException if {@code type} is null
2377      * @throws IllegalArgumentException if {@code leadingArgCount} is not in
2378      *                  the range from 0 to {@code type.parameterCount()} inclusive,
2379      *                  or if the resulting method handle's type would have
2380      *          <a href="MethodHandle.html#maxarity">too many parameters</a>
2381      */
2382     static public
spreadInvoker(MethodType type, int leadingArgCount)2383     MethodHandle spreadInvoker(MethodType type, int leadingArgCount) {
2384         if (leadingArgCount < 0 || leadingArgCount > type.parameterCount())
2385             throw newIllegalArgumentException("bad argument count", leadingArgCount);
2386 
2387         MethodHandle invoker = MethodHandles.invoker(type);
2388         int spreadArgCount = type.parameterCount() - leadingArgCount;
2389         invoker = invoker.asSpreader(Object[].class, spreadArgCount);
2390         return invoker;
2391     }
2392 
2393     /**
2394      * Produces a special <em>invoker method handle</em> which can be used to
2395      * invoke any method handle of the given type, as if by {@link MethodHandle#invokeExact invokeExact}.
2396      * The resulting invoker will have a type which is
2397      * exactly equal to the desired type, except that it will accept
2398      * an additional leading argument of type {@code MethodHandle}.
2399      * <p>
2400      * This method is equivalent to the following code (though it may be more efficient):
2401      * {@code publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)}
2402      *
2403      * <p style="font-size:smaller;">
2404      * <em>Discussion:</em>
2405      * Invoker method handles can be useful when working with variable method handles
2406      * of unknown types.
2407      * For example, to emulate an {@code invokeExact} call to a variable method
2408      * handle {@code M}, extract its type {@code T},
2409      * look up the invoker method {@code X} for {@code T},
2410      * and call the invoker method, as {@code X.invoke(T, A...)}.
2411      * (It would not work to call {@code X.invokeExact}, since the type {@code T}
2412      * is unknown.)
2413      * If spreading, collecting, or other argument transformations are required,
2414      * they can be applied once to the invoker {@code X} and reused on many {@code M}
2415      * method handle values, as long as they are compatible with the type of {@code X}.
2416      * <p style="font-size:smaller;">
2417      * <em>(Note:  The invoker method is not available via the Core Reflection API.
2418      * An attempt to call {@linkplain java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}
2419      * on the declared {@code invokeExact} or {@code invoke} method will raise an
2420      * {@link java.lang.UnsupportedOperationException UnsupportedOperationException}.)</em>
2421      * <p>
2422      * This method throws no reflective or security exceptions.
2423      * @param type the desired target type
2424      * @return a method handle suitable for invoking any method handle of the given type
2425      * @throws IllegalArgumentException if the resulting method handle's type would have
2426      *          <a href="MethodHandle.html#maxarity">too many parameters</a>
2427      */
2428     static public
exactInvoker(MethodType type)2429     MethodHandle exactInvoker(MethodType type) {
2430         return new Transformers.Invoker(type, true /* isExactInvoker */);
2431     }
2432 
2433     /**
2434      * Produces a special <em>invoker method handle</em> which can be used to
2435      * invoke any method handle compatible with the given type, as if by {@link MethodHandle#invoke invoke}.
2436      * The resulting invoker will have a type which is
2437      * exactly equal to the desired type, except that it will accept
2438      * an additional leading argument of type {@code MethodHandle}.
2439      * <p>
2440      * Before invoking its target, if the target differs from the expected type,
2441      * the invoker will apply reference casts as
2442      * necessary and box, unbox, or widen primitive values, as if by {@link MethodHandle#asType asType}.
2443      * Similarly, the return value will be converted as necessary.
2444      * If the target is a {@linkplain MethodHandle#asVarargsCollector variable arity method handle},
2445      * the required arity conversion will be made, again as if by {@link MethodHandle#asType asType}.
2446      * <p>
2447      * This method is equivalent to the following code (though it may be more efficient):
2448      * {@code publicLookup().findVirtual(MethodHandle.class, "invoke", type)}
2449      * <p style="font-size:smaller;">
2450      * <em>Discussion:</em>
2451      * A {@linkplain MethodType#genericMethodType general method type} is one which
2452      * mentions only {@code Object} arguments and return values.
2453      * An invoker for such a type is capable of calling any method handle
2454      * of the same arity as the general type.
2455      * <p style="font-size:smaller;">
2456      * <em>(Note:  The invoker method is not available via the Core Reflection API.
2457      * An attempt to call {@linkplain java.lang.reflect.Method#invoke java.lang.reflect.Method.invoke}
2458      * on the declared {@code invokeExact} or {@code invoke} method will raise an
2459      * {@link java.lang.UnsupportedOperationException UnsupportedOperationException}.)</em>
2460      * <p>
2461      * This method throws no reflective or security exceptions.
2462      * @param type the desired target type
2463      * @return a method handle suitable for invoking any method handle convertible to the given type
2464      * @throws IllegalArgumentException if the resulting method handle's type would have
2465      *          <a href="MethodHandle.html#maxarity">too many parameters</a>
2466      */
2467     static public
invoker(MethodType type)2468     MethodHandle invoker(MethodType type) {
2469         return new Transformers.Invoker(type, false /* isExactInvoker */);
2470     }
2471 
2472     // BEGIN Android-added: resolver for VarHandle accessor methods.
methodHandleForVarHandleAccessor(VarHandle.AccessMode accessMode, MethodType type, boolean isExactInvoker)2473     static private MethodHandle methodHandleForVarHandleAccessor(VarHandle.AccessMode accessMode,
2474                                                                  MethodType type,
2475                                                                  boolean isExactInvoker) {
2476         Class<?> refc = VarHandle.class;
2477         Method method;
2478         try {
2479             method = refc.getDeclaredMethod(accessMode.methodName(), Object[].class);
2480         } catch (NoSuchMethodException e) {
2481             throw new InternalError("No method for AccessMode " + accessMode, e);
2482         }
2483         MethodType methodType = type.insertParameterTypes(0, VarHandle.class);
2484         int kind = isExactInvoker ? MethodHandle.INVOKE_VAR_HANDLE_EXACT
2485                                   : MethodHandle.INVOKE_VAR_HANDLE;
2486         return new MethodHandleImpl(method.getArtMethod(), kind, methodType);
2487     }
2488     // END Android-added: resolver for VarHandle accessor methods.
2489 
2490     /**
2491      * Produces a special <em>invoker method handle</em> which can be used to
2492      * invoke a signature-polymorphic access mode method on any VarHandle whose
2493      * associated access mode type is compatible with the given type.
2494      * The resulting invoker will have a type which is exactly equal to the
2495      * desired given type, except that it will accept an additional leading
2496      * argument of type {@code VarHandle}.
2497      *
2498      * @param accessMode the VarHandle access mode
2499      * @param type the desired target type
2500      * @return a method handle suitable for invoking an access mode method of
2501      *         any VarHandle whose access mode type is of the given type.
2502      * @since 9
2503      * @hide
2504      */
2505     static public
varHandleExactInvoker(VarHandle.AccessMode accessMode, MethodType type)2506     MethodHandle varHandleExactInvoker(VarHandle.AccessMode accessMode, MethodType type) {
2507         return methodHandleForVarHandleAccessor(accessMode, type, true /* isExactInvoker */);
2508     }
2509 
2510     /**
2511      * Produces a special <em>invoker method handle</em> which can be used to
2512      * invoke a signature-polymorphic access mode method on any VarHandle whose
2513      * associated access mode type is compatible with the given type.
2514      * The resulting invoker will have a type which is exactly equal to the
2515      * desired given type, except that it will accept an additional leading
2516      * argument of type {@code VarHandle}.
2517      * <p>
2518      * Before invoking its target, if the access mode type differs from the
2519      * desired given type, the invoker will apply reference casts as necessary
2520      * and box, unbox, or widen primitive values, as if by
2521      * {@link MethodHandle#asType asType}.  Similarly, the return value will be
2522      * converted as necessary.
2523      * <p>
2524      * This method is equivalent to the following code (though it may be more
2525      * efficient): {@code publicLookup().findVirtual(VarHandle.class, accessMode.name(), type)}
2526      *
2527      * @param accessMode the VarHandle access mode
2528      * @param type the desired target type
2529      * @return a method handle suitable for invoking an access mode method of
2530      *         any VarHandle whose access mode type is convertible to the given
2531      *         type.
2532      * @since 9
2533      * @hide
2534      */
2535     static public
varHandleInvoker(VarHandle.AccessMode accessMode, MethodType type)2536     MethodHandle varHandleInvoker(VarHandle.AccessMode accessMode, MethodType type) {
2537         return methodHandleForVarHandleAccessor(accessMode, type, false /* isExactInvoker */);
2538     }
2539 
2540     // Android-changed: Basic invokers are not supported.
2541     //
2542     // static /*non-public*/
2543     // MethodHandle basicInvoker(MethodType type) {
2544     //     return type.invokers().basicInvoker();
2545     // }
2546 
2547      /// method handle modification (creation from other method handles)
2548 
2549     /**
2550      * Produces a method handle which adapts the type of the
2551      * given method handle to a new type by pairwise argument and return type conversion.
2552      * The original type and new type must have the same number of arguments.
2553      * The resulting method handle is guaranteed to report a type
2554      * which is equal to the desired new type.
2555      * <p>
2556      * If the original type and new type are equal, returns target.
2557      * <p>
2558      * The same conversions are allowed as for {@link MethodHandle#asType MethodHandle.asType},
2559      * and some additional conversions are also applied if those conversions fail.
2560      * Given types <em>T0</em>, <em>T1</em>, one of the following conversions is applied
2561      * if possible, before or instead of any conversions done by {@code asType}:
2562      * <ul>
2563      * <li>If <em>T0</em> and <em>T1</em> are references, and <em>T1</em> is an interface type,
2564      *     then the value of type <em>T0</em> is passed as a <em>T1</em> without a cast.
2565      *     (This treatment of interfaces follows the usage of the bytecode verifier.)
2566      * <li>If <em>T0</em> is boolean and <em>T1</em> is another primitive,
2567      *     the boolean is converted to a byte value, 1 for true, 0 for false.
2568      *     (This treatment follows the usage of the bytecode verifier.)
2569      * <li>If <em>T1</em> is boolean and <em>T0</em> is another primitive,
2570      *     <em>T0</em> is converted to byte via Java casting conversion (JLS 5.5),
2571      *     and the low order bit of the result is tested, as if by {@code (x & 1) != 0}.
2572      * <li>If <em>T0</em> and <em>T1</em> are primitives other than boolean,
2573      *     then a Java casting conversion (JLS 5.5) is applied.
2574      *     (Specifically, <em>T0</em> will convert to <em>T1</em> by
2575      *     widening and/or narrowing.)
2576      * <li>If <em>T0</em> is a reference and <em>T1</em> a primitive, an unboxing
2577      *     conversion will be applied at runtime, possibly followed
2578      *     by a Java casting conversion (JLS 5.5) on the primitive value,
2579      *     possibly followed by a conversion from byte to boolean by testing
2580      *     the low-order bit.
2581      * <li>If <em>T0</em> is a reference and <em>T1</em> a primitive,
2582      *     and if the reference is null at runtime, a zero value is introduced.
2583      * </ul>
2584      * @param target the method handle to invoke after arguments are retyped
2585      * @param newType the expected type of the new method handle
2586      * @return a method handle which delegates to the target after performing
2587      *           any necessary argument conversions, and arranges for any
2588      *           necessary return value conversions
2589      * @throws NullPointerException if either argument is null
2590      * @throws WrongMethodTypeException if the conversion cannot be made
2591      * @see MethodHandle#asType
2592      */
2593     public static
explicitCastArguments(MethodHandle target, MethodType newType)2594     MethodHandle explicitCastArguments(MethodHandle target, MethodType newType) {
2595         explicitCastArgumentsChecks(target, newType);
2596         // use the asTypeCache when possible:
2597         MethodType oldType = target.type();
2598         if (oldType == newType) return target;
2599         if (oldType.explicitCastEquivalentToAsType(newType)) {
2600             if (Transformers.Transformer.class.isAssignableFrom(target.getClass())) {
2601                 // The StackFrameReader and StackFrameWriter used to perform transforms on
2602                 // EmulatedStackFrames (in Transformers.java) do not how to perform asType()
2603                 // conversions, but we know here that an explicit cast transform is the same as
2604                 // having called asType() on the method handle.
2605                 return new Transformers.ExplicitCastArguments(target.asFixedArity(), newType);
2606             } else {
2607                 // Runtime will perform asType() conversion during invocation.
2608                 return target.asFixedArity().asType(newType);
2609             }
2610         }
2611         return new Transformers.ExplicitCastArguments(target, newType);
2612     }
2613 
explicitCastArgumentsChecks(MethodHandle target, MethodType newType)2614     private static void explicitCastArgumentsChecks(MethodHandle target, MethodType newType) {
2615         if (target.type().parameterCount() != newType.parameterCount()) {
2616             throw new WrongMethodTypeException("cannot explicitly cast " + target +
2617                                                " to " + newType);
2618         }
2619     }
2620 
2621     /**
2622      * Produces a method handle which adapts the calling sequence of the
2623      * given method handle to a new type, by reordering the arguments.
2624      * The resulting method handle is guaranteed to report a type
2625      * which is equal to the desired new type.
2626      * <p>
2627      * The given array controls the reordering.
2628      * Call {@code #I} the number of incoming parameters (the value
2629      * {@code newType.parameterCount()}, and call {@code #O} the number
2630      * of outgoing parameters (the value {@code target.type().parameterCount()}).
2631      * Then the length of the reordering array must be {@code #O},
2632      * and each element must be a non-negative number less than {@code #I}.
2633      * For every {@code N} less than {@code #O}, the {@code N}-th
2634      * outgoing argument will be taken from the {@code I}-th incoming
2635      * argument, where {@code I} is {@code reorder[N]}.
2636      * <p>
2637      * No argument or return value conversions are applied.
2638      * The type of each incoming argument, as determined by {@code newType},
2639      * must be identical to the type of the corresponding outgoing parameter
2640      * or parameters in the target method handle.
2641      * The return type of {@code newType} must be identical to the return
2642      * type of the original target.
2643      * <p>
2644      * The reordering array need not specify an actual permutation.
2645      * An incoming argument will be duplicated if its index appears
2646      * more than once in the array, and an incoming argument will be dropped
2647      * if its index does not appear in the array.
2648      * As in the case of {@link #dropArguments(MethodHandle,int,List) dropArguments},
2649      * incoming arguments which are not mentioned in the reordering array
2650      * are may be any type, as determined only by {@code newType}.
2651      * <blockquote><pre>{@code
2652 import static java.lang.invoke.MethodHandles.*;
2653 import static java.lang.invoke.MethodType.*;
2654 ...
2655 MethodType intfn1 = methodType(int.class, int.class);
2656 MethodType intfn2 = methodType(int.class, int.class, int.class);
2657 MethodHandle sub = ... (int x, int y) -> (x-y) ...;
2658 assert(sub.type().equals(intfn2));
2659 MethodHandle sub1 = permuteArguments(sub, intfn2, 0, 1);
2660 MethodHandle rsub = permuteArguments(sub, intfn2, 1, 0);
2661 assert((int)rsub.invokeExact(1, 100) == 99);
2662 MethodHandle add = ... (int x, int y) -> (x+y) ...;
2663 assert(add.type().equals(intfn2));
2664 MethodHandle twice = permuteArguments(add, intfn1, 0, 0);
2665 assert(twice.type().equals(intfn1));
2666 assert((int)twice.invokeExact(21) == 42);
2667      * }</pre></blockquote>
2668      * @param target the method handle to invoke after arguments are reordered
2669      * @param newType the expected type of the new method handle
2670      * @param reorder an index array which controls the reordering
2671      * @return a method handle which delegates to the target after it
2672      *           drops unused arguments and moves and/or duplicates the other arguments
2673      * @throws NullPointerException if any argument is null
2674      * @throws IllegalArgumentException if the index array length is not equal to
2675      *                  the arity of the target, or if any index array element
2676      *                  not a valid index for a parameter of {@code newType},
2677      *                  or if two corresponding parameter types in
2678      *                  {@code target.type()} and {@code newType} are not identical,
2679      */
2680     public static
permuteArguments(MethodHandle target, MethodType newType, int... reorder)2681     MethodHandle permuteArguments(MethodHandle target, MethodType newType, int... reorder) {
2682         reorder = reorder.clone();  // get a private copy
2683         MethodType oldType = target.type();
2684         permuteArgumentChecks(reorder, newType, oldType);
2685 
2686         return new Transformers.PermuteArguments(newType, target, reorder);
2687     }
2688 
2689     // Android-changed: findFirstDupOrDrop is unused and removed.
2690     // private static int findFirstDupOrDrop(int[] reorder, int newArity);
2691 
permuteArgumentChecks(int[] reorder, MethodType newType, MethodType oldType)2692     private static boolean permuteArgumentChecks(int[] reorder, MethodType newType, MethodType oldType) {
2693         if (newType.returnType() != oldType.returnType())
2694             throw newIllegalArgumentException("return types do not match",
2695                     oldType, newType);
2696         if (reorder.length == oldType.parameterCount()) {
2697             int limit = newType.parameterCount();
2698             boolean bad = false;
2699             for (int j = 0; j < reorder.length; j++) {
2700                 int i = reorder[j];
2701                 if (i < 0 || i >= limit) {
2702                     bad = true; break;
2703                 }
2704                 Class<?> src = newType.parameterType(i);
2705                 Class<?> dst = oldType.parameterType(j);
2706                 if (src != dst)
2707                     throw newIllegalArgumentException("parameter types do not match after reorder",
2708                             oldType, newType);
2709             }
2710             if (!bad)  return true;
2711         }
2712         throw newIllegalArgumentException("bad reorder array: "+Arrays.toString(reorder));
2713     }
2714 
2715     /**
2716      * Produces a method handle of the requested return type which returns the given
2717      * constant value every time it is invoked.
2718      * <p>
2719      * Before the method handle is returned, the passed-in value is converted to the requested type.
2720      * If the requested type is primitive, widening primitive conversions are attempted,
2721      * else reference conversions are attempted.
2722      * <p>The returned method handle is equivalent to {@code identity(type).bindTo(value)}.
2723      * @param type the return type of the desired method handle
2724      * @param value the value to return
2725      * @return a method handle of the given return type and no arguments, which always returns the given value
2726      * @throws NullPointerException if the {@code type} argument is null
2727      * @throws ClassCastException if the value cannot be converted to the required return type
2728      * @throws IllegalArgumentException if the given type is {@code void.class}
2729      */
2730     public static
constant(Class<?> type, Object value)2731     MethodHandle constant(Class<?> type, Object value) {
2732         if (type.isPrimitive()) {
2733             if (type == void.class)
2734                 throw newIllegalArgumentException("void type");
2735             Wrapper w = Wrapper.forPrimitiveType(type);
2736             value = w.convert(value, type);
2737         }
2738 
2739         return new Transformers.Constant(type, value);
2740     }
2741 
2742     /**
2743      * Produces a method handle which returns its sole argument when invoked.
2744      * @param type the type of the sole parameter and return value of the desired method handle
2745      * @return a unary method handle which accepts and returns the given type
2746      * @throws NullPointerException if the argument is null
2747      * @throws IllegalArgumentException if the given type is {@code void.class}
2748      */
2749     public static
identity(Class<?> type)2750     MethodHandle identity(Class<?> type) {
2751         if (type == null) {
2752             throw new NullPointerException("type == null");
2753         }
2754 
2755         if (type.isPrimitive()) {
2756             try {
2757                 return Lookup.PUBLIC_LOOKUP.findStatic(MethodHandles.class, "identity",
2758                         MethodType.methodType(type, type));
2759             } catch (NoSuchMethodException | IllegalAccessException e) {
2760                 throw new AssertionError(e);
2761             }
2762         }
2763 
2764         return new Transformers.ReferenceIdentity(type);
2765     }
2766 
identity(byte val)2767     /** @hide */ public static byte identity(byte val) { return val; }
identity(boolean val)2768     /** @hide */ public static boolean identity(boolean val) { return val; }
identity(char val)2769     /** @hide */ public static char identity(char val) { return val; }
identity(short val)2770     /** @hide */ public static short identity(short val) { return val; }
identity(int val)2771     /** @hide */ public static int identity(int val) { return val; }
identity(long val)2772     /** @hide */ public static long identity(long val) { return val; }
identity(float val)2773     /** @hide */ public static float identity(float val) { return val; }
identity(double val)2774     /** @hide */ public static double identity(double val) { return val; }
2775 
2776     /**
2777      * Provides a target method handle with one or more <em>bound arguments</em>
2778      * in advance of the method handle's invocation.
2779      * The formal parameters to the target corresponding to the bound
2780      * arguments are called <em>bound parameters</em>.
2781      * Returns a new method handle which saves away the bound arguments.
2782      * When it is invoked, it receives arguments for any non-bound parameters,
2783      * binds the saved arguments to their corresponding parameters,
2784      * and calls the original target.
2785      * <p>
2786      * The type of the new method handle will drop the types for the bound
2787      * parameters from the original target type, since the new method handle
2788      * will no longer require those arguments to be supplied by its callers.
2789      * <p>
2790      * Each given argument object must match the corresponding bound parameter type.
2791      * If a bound parameter type is a primitive, the argument object
2792      * must be a wrapper, and will be unboxed to produce the primitive value.
2793      * <p>
2794      * The {@code pos} argument selects which parameters are to be bound.
2795      * It may range between zero and <i>N-L</i> (inclusively),
2796      * where <i>N</i> is the arity of the target method handle
2797      * and <i>L</i> is the length of the values array.
2798      * @param target the method handle to invoke after the argument is inserted
2799      * @param pos where to insert the argument (zero for the first)
2800      * @param values the series of arguments to insert
2801      * @return a method handle which inserts an additional argument,
2802      *         before calling the original method handle
2803      * @throws NullPointerException if the target or the {@code values} array is null
2804      * @see MethodHandle#bindTo
2805      */
2806     public static
insertArguments(MethodHandle target, int pos, Object... values)2807     MethodHandle insertArguments(MethodHandle target, int pos, Object... values) {
2808         int insCount = values.length;
2809         Class<?>[] ptypes = insertArgumentsChecks(target, insCount, pos);
2810         if (insCount == 0)  {
2811             return target;
2812         }
2813 
2814         // Throw ClassCastExceptions early if we can't cast any of the provided values
2815         // to the required type.
2816         for (int i = 0; i < insCount; i++) {
2817             final Class<?> ptype = ptypes[pos + i];
2818             if (!ptype.isPrimitive()) {
2819                 ptypes[pos + i].cast(values[i]);
2820             } else {
2821                 // Will throw a ClassCastException if something terrible happens.
2822                 values[i] = Wrapper.forPrimitiveType(ptype).convert(values[i], ptype);
2823             }
2824         }
2825 
2826         return new Transformers.InsertArguments(target, pos, values);
2827     }
2828 
2829     // Android-changed: insertArgumentPrimitive is unused.
2830     //
2831     // private static BoundMethodHandle insertArgumentPrimitive(BoundMethodHandle result, int pos,
2832     //                                                          Class<?> ptype, Object value) {
2833     //     Wrapper w = Wrapper.forPrimitiveType(ptype);
2834     //     // perform unboxing and/or primitive conversion
2835     //     value = w.convert(value, ptype);
2836     //     switch (w) {
2837     //     case INT:     return result.bindArgumentI(pos, (int)value);
2838     //     case LONG:    return result.bindArgumentJ(pos, (long)value);
2839     //     case FLOAT:   return result.bindArgumentF(pos, (float)value);
2840     //     case DOUBLE:  return result.bindArgumentD(pos, (double)value);
2841     //     default:      return result.bindArgumentI(pos, ValueConversions.widenSubword(value));
2842     //     }
2843     // }
2844 
insertArgumentsChecks(MethodHandle target, int insCount, int pos)2845     private static Class<?>[] insertArgumentsChecks(MethodHandle target, int insCount, int pos) throws RuntimeException {
2846         MethodType oldType = target.type();
2847         int outargs = oldType.parameterCount();
2848         int inargs  = outargs - insCount;
2849         if (inargs < 0)
2850             throw newIllegalArgumentException("too many values to insert");
2851         if (pos < 0 || pos > inargs)
2852             throw newIllegalArgumentException("no argument type to append");
2853         return oldType.ptypes();
2854     }
2855 
2856     /**
2857      * Produces a method handle which will discard some dummy arguments
2858      * before calling some other specified <i>target</i> method handle.
2859      * The type of the new method handle will be the same as the target's type,
2860      * except it will also include the dummy argument types,
2861      * at some given position.
2862      * <p>
2863      * The {@code pos} argument may range between zero and <i>N</i>,
2864      * where <i>N</i> is the arity of the target.
2865      * If {@code pos} is zero, the dummy arguments will precede
2866      * the target's real arguments; if {@code pos} is <i>N</i>
2867      * they will come after.
2868      * <p>
2869      * <b>Example:</b>
2870      * <blockquote><pre>{@code
2871 import static java.lang.invoke.MethodHandles.*;
2872 import static java.lang.invoke.MethodType.*;
2873 ...
2874 MethodHandle cat = lookup().findVirtual(String.class,
2875   "concat", methodType(String.class, String.class));
2876 assertEquals("xy", (String) cat.invokeExact("x", "y"));
2877 MethodType bigType = cat.type().insertParameterTypes(0, int.class, String.class);
2878 MethodHandle d0 = dropArguments(cat, 0, bigType.parameterList().subList(0,2));
2879 assertEquals(bigType, d0.type());
2880 assertEquals("yz", (String) d0.invokeExact(123, "x", "y", "z"));
2881      * }</pre></blockquote>
2882      * <p>
2883      * This method is also equivalent to the following code:
2884      * <blockquote><pre>
2885      * {@link #dropArguments(MethodHandle,int,Class...) dropArguments}{@code (target, pos, valueTypes.toArray(new Class[0]))}
2886      * </pre></blockquote>
2887      * @param target the method handle to invoke after the arguments are dropped
2888      * @param valueTypes the type(s) of the argument(s) to drop
2889      * @param pos position of first argument to drop (zero for the leftmost)
2890      * @return a method handle which drops arguments of the given types,
2891      *         before calling the original method handle
2892      * @throws NullPointerException if the target is null,
2893      *                              or if the {@code valueTypes} list or any of its elements is null
2894      * @throws IllegalArgumentException if any element of {@code valueTypes} is {@code void.class},
2895      *                  or if {@code pos} is negative or greater than the arity of the target,
2896      *                  or if the new method handle's type would have too many parameters
2897      */
2898     public static
dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes)2899     MethodHandle dropArguments(MethodHandle target, int pos, List<Class<?>> valueTypes) {
2900         valueTypes = copyTypes(valueTypes);
2901         MethodType oldType = target.type();  // get NPE
2902         int dropped = dropArgumentChecks(oldType, pos, valueTypes);
2903 
2904         MethodType newType = oldType.insertParameterTypes(pos, valueTypes);
2905         if (dropped == 0) {
2906             return target;
2907         }
2908 
2909         return new Transformers.DropArguments(newType, target, pos, valueTypes.size());
2910     }
2911 
copyTypes(List<Class<?>> types)2912     private static List<Class<?>> copyTypes(List<Class<?>> types) {
2913         Object[] a = types.toArray();
2914         return Arrays.asList(Arrays.copyOf(a, a.length, Class[].class));
2915     }
2916 
dropArgumentChecks(MethodType oldType, int pos, List<Class<?>> valueTypes)2917     private static int dropArgumentChecks(MethodType oldType, int pos, List<Class<?>> valueTypes) {
2918         int dropped = valueTypes.size();
2919         MethodType.checkSlotCount(dropped);
2920         int outargs = oldType.parameterCount();
2921         int inargs  = outargs + dropped;
2922         if (pos < 0 || pos > outargs)
2923             throw newIllegalArgumentException("no argument type to remove"
2924                     + Arrays.asList(oldType, pos, valueTypes, inargs, outargs)
2925                     );
2926         return dropped;
2927     }
2928 
2929     /**
2930      * Produces a method handle which will discard some dummy arguments
2931      * before calling some other specified <i>target</i> method handle.
2932      * The type of the new method handle will be the same as the target's type,
2933      * except it will also include the dummy argument types,
2934      * at some given position.
2935      * <p>
2936      * The {@code pos} argument may range between zero and <i>N</i>,
2937      * where <i>N</i> is the arity of the target.
2938      * If {@code pos} is zero, the dummy arguments will precede
2939      * the target's real arguments; if {@code pos} is <i>N</i>
2940      * they will come after.
2941      * <p>
2942      * <b>Example:</b>
2943      * <blockquote><pre>{@code
2944 import static java.lang.invoke.MethodHandles.*;
2945 import static java.lang.invoke.MethodType.*;
2946 ...
2947 MethodHandle cat = lookup().findVirtual(String.class,
2948   "concat", methodType(String.class, String.class));
2949 assertEquals("xy", (String) cat.invokeExact("x", "y"));
2950 MethodHandle d0 = dropArguments(cat, 0, String.class);
2951 assertEquals("yz", (String) d0.invokeExact("x", "y", "z"));
2952 MethodHandle d1 = dropArguments(cat, 1, String.class);
2953 assertEquals("xz", (String) d1.invokeExact("x", "y", "z"));
2954 MethodHandle d2 = dropArguments(cat, 2, String.class);
2955 assertEquals("xy", (String) d2.invokeExact("x", "y", "z"));
2956 MethodHandle d12 = dropArguments(cat, 1, int.class, boolean.class);
2957 assertEquals("xz", (String) d12.invokeExact("x", 12, true, "z"));
2958      * }</pre></blockquote>
2959      * <p>
2960      * This method is also equivalent to the following code:
2961      * <blockquote><pre>
2962      * {@link #dropArguments(MethodHandle,int,List) dropArguments}{@code (target, pos, Arrays.asList(valueTypes))}
2963      * </pre></blockquote>
2964      * @param target the method handle to invoke after the arguments are dropped
2965      * @param valueTypes the type(s) of the argument(s) to drop
2966      * @param pos position of first argument to drop (zero for the leftmost)
2967      * @return a method handle which drops arguments of the given types,
2968      *         before calling the original method handle
2969      * @throws NullPointerException if the target is null,
2970      *                              or if the {@code valueTypes} array or any of its elements is null
2971      * @throws IllegalArgumentException if any element of {@code valueTypes} is {@code void.class},
2972      *                  or if {@code pos} is negative or greater than the arity of the target,
2973      *                  or if the new method handle's type would have
2974      *                  <a href="MethodHandle.html#maxarity">too many parameters</a>
2975      */
2976     public static
dropArguments(MethodHandle target, int pos, Class<?>... valueTypes)2977     MethodHandle dropArguments(MethodHandle target, int pos, Class<?>... valueTypes) {
2978         return dropArguments(target, pos, Arrays.asList(valueTypes));
2979     }
2980 
2981     /**
2982      * Adapts a target method handle by pre-processing
2983      * one or more of its arguments, each with its own unary filter function,
2984      * and then calling the target with each pre-processed argument
2985      * replaced by the result of its corresponding filter function.
2986      * <p>
2987      * The pre-processing is performed by one or more method handles,
2988      * specified in the elements of the {@code filters} array.
2989      * The first element of the filter array corresponds to the {@code pos}
2990      * argument of the target, and so on in sequence.
2991      * <p>
2992      * Null arguments in the array are treated as identity functions,
2993      * and the corresponding arguments left unchanged.
2994      * (If there are no non-null elements in the array, the original target is returned.)
2995      * Each filter is applied to the corresponding argument of the adapter.
2996      * <p>
2997      * If a filter {@code F} applies to the {@code N}th argument of
2998      * the target, then {@code F} must be a method handle which
2999      * takes exactly one argument.  The type of {@code F}'s sole argument
3000      * replaces the corresponding argument type of the target
3001      * in the resulting adapted method handle.
3002      * The return type of {@code F} must be identical to the corresponding
3003      * parameter type of the target.
3004      * <p>
3005      * It is an error if there are elements of {@code filters}
3006      * (null or not)
3007      * which do not correspond to argument positions in the target.
3008      * <p><b>Example:</b>
3009      * <blockquote><pre>{@code
3010 import static java.lang.invoke.MethodHandles.*;
3011 import static java.lang.invoke.MethodType.*;
3012 ...
3013 MethodHandle cat = lookup().findVirtual(String.class,
3014   "concat", methodType(String.class, String.class));
3015 MethodHandle upcase = lookup().findVirtual(String.class,
3016   "toUpperCase", methodType(String.class));
3017 assertEquals("xy", (String) cat.invokeExact("x", "y"));
3018 MethodHandle f0 = filterArguments(cat, 0, upcase);
3019 assertEquals("Xy", (String) f0.invokeExact("x", "y")); // Xy
3020 MethodHandle f1 = filterArguments(cat, 1, upcase);
3021 assertEquals("xY", (String) f1.invokeExact("x", "y")); // xY
3022 MethodHandle f2 = filterArguments(cat, 0, upcase, upcase);
3023 assertEquals("XY", (String) f2.invokeExact("x", "y")); // XY
3024      * }</pre></blockquote>
3025      * <p> Here is pseudocode for the resulting adapter:
3026      * <blockquote><pre>{@code
3027      * V target(P... p, A[i]... a[i], B... b);
3028      * A[i] filter[i](V[i]);
3029      * T adapter(P... p, V[i]... v[i], B... b) {
3030      *   return target(p..., f[i](v[i])..., b...);
3031      * }
3032      * }</pre></blockquote>
3033      *
3034      * @param target the method handle to invoke after arguments are filtered
3035      * @param pos the position of the first argument to filter
3036      * @param filters method handles to call initially on filtered arguments
3037      * @return method handle which incorporates the specified argument filtering logic
3038      * @throws NullPointerException if the target is null
3039      *                              or if the {@code filters} array is null
3040      * @throws IllegalArgumentException if a non-null element of {@code filters}
3041      *          does not match a corresponding argument type of target as described above,
3042      *          or if the {@code pos+filters.length} is greater than {@code target.type().parameterCount()},
3043      *          or if the resulting method handle's type would have
3044      *          <a href="MethodHandle.html#maxarity">too many parameters</a>
3045      */
3046     public static
filterArguments(MethodHandle target, int pos, MethodHandle... filters)3047     MethodHandle filterArguments(MethodHandle target, int pos, MethodHandle... filters) {
3048         filterArgumentsCheckArity(target, pos, filters);
3049 
3050         for (int i = 0; i < filters.length; ++i) {
3051             filterArgumentChecks(target, i + pos, filters[i]);
3052         }
3053 
3054         return new Transformers.FilterArguments(target, pos, filters);
3055     }
3056 
filterArgumentsCheckArity(MethodHandle target, int pos, MethodHandle[] filters)3057     private static void filterArgumentsCheckArity(MethodHandle target, int pos, MethodHandle[] filters) {
3058         MethodType targetType = target.type();
3059         int maxPos = targetType.parameterCount();
3060         if (pos + filters.length > maxPos)
3061             throw newIllegalArgumentException("too many filters");
3062     }
3063 
filterArgumentChecks(MethodHandle target, int pos, MethodHandle filter)3064     private static void filterArgumentChecks(MethodHandle target, int pos, MethodHandle filter) throws RuntimeException {
3065         MethodType targetType = target.type();
3066         MethodType filterType = filter.type();
3067         if (filterType.parameterCount() != 1
3068             || filterType.returnType() != targetType.parameterType(pos))
3069             throw newIllegalArgumentException("target and filter types do not match", targetType, filterType);
3070     }
3071 
3072     /**
3073      * Adapts a target method handle by pre-processing
3074      * a sub-sequence of its arguments with a filter (another method handle).
3075      * The pre-processed arguments are replaced by the result (if any) of the
3076      * filter function.
3077      * The target is then called on the modified (usually shortened) argument list.
3078      * <p>
3079      * If the filter returns a value, the target must accept that value as
3080      * its argument in position {@code pos}, preceded and/or followed by
3081      * any arguments not passed to the filter.
3082      * If the filter returns void, the target must accept all arguments
3083      * not passed to the filter.
3084      * No arguments are reordered, and a result returned from the filter
3085      * replaces (in order) the whole subsequence of arguments originally
3086      * passed to the adapter.
3087      * <p>
3088      * The argument types (if any) of the filter
3089      * replace zero or one argument types of the target, at position {@code pos},
3090      * in the resulting adapted method handle.
3091      * The return type of the filter (if any) must be identical to the
3092      * argument type of the target at position {@code pos}, and that target argument
3093      * is supplied by the return value of the filter.
3094      * <p>
3095      * In all cases, {@code pos} must be greater than or equal to zero, and
3096      * {@code pos} must also be less than or equal to the target's arity.
3097      * <p><b>Example:</b>
3098      * <blockquote><pre>{@code
3099 import static java.lang.invoke.MethodHandles.*;
3100 import static java.lang.invoke.MethodType.*;
3101 ...
3102 MethodHandle deepToString = publicLookup()
3103   .findStatic(Arrays.class, "deepToString", methodType(String.class, Object[].class));
3104 
3105 MethodHandle ts1 = deepToString.asCollector(String[].class, 1);
3106 assertEquals("[strange]", (String) ts1.invokeExact("strange"));
3107 
3108 MethodHandle ts2 = deepToString.asCollector(String[].class, 2);
3109 assertEquals("[up, down]", (String) ts2.invokeExact("up", "down"));
3110 
3111 MethodHandle ts3 = deepToString.asCollector(String[].class, 3);
3112 MethodHandle ts3_ts2 = collectArguments(ts3, 1, ts2);
3113 assertEquals("[top, [up, down], strange]",
3114              (String) ts3_ts2.invokeExact("top", "up", "down", "strange"));
3115 
3116 MethodHandle ts3_ts2_ts1 = collectArguments(ts3_ts2, 3, ts1);
3117 assertEquals("[top, [up, down], [strange]]",
3118              (String) ts3_ts2_ts1.invokeExact("top", "up", "down", "strange"));
3119 
3120 MethodHandle ts3_ts2_ts3 = collectArguments(ts3_ts2, 1, ts3);
3121 assertEquals("[top, [[up, down, strange], charm], bottom]",
3122              (String) ts3_ts2_ts3.invokeExact("top", "up", "down", "strange", "charm", "bottom"));
3123      * }</pre></blockquote>
3124      * <p> Here is pseudocode for the resulting adapter:
3125      * <blockquote><pre>{@code
3126      * T target(A...,V,C...);
3127      * V filter(B...);
3128      * T adapter(A... a,B... b,C... c) {
3129      *   V v = filter(b...);
3130      *   return target(a...,v,c...);
3131      * }
3132      * // and if the filter has no arguments:
3133      * T target2(A...,V,C...);
3134      * V filter2();
3135      * T adapter2(A... a,C... c) {
3136      *   V v = filter2();
3137      *   return target2(a...,v,c...);
3138      * }
3139      * // and if the filter has a void return:
3140      * T target3(A...,C...);
3141      * void filter3(B...);
3142      * void adapter3(A... a,B... b,C... c) {
3143      *   filter3(b...);
3144      *   return target3(a...,c...);
3145      * }
3146      * }</pre></blockquote>
3147      * <p>
3148      * A collection adapter {@code collectArguments(mh, 0, coll)} is equivalent to
3149      * one which first "folds" the affected arguments, and then drops them, in separate
3150      * steps as follows:
3151      * <blockquote><pre>{@code
3152      * mh = MethodHandles.dropArguments(mh, 1, coll.type().parameterList()); //step 2
3153      * mh = MethodHandles.foldArguments(mh, coll); //step 1
3154      * }</pre></blockquote>
3155      * If the target method handle consumes no arguments besides than the result
3156      * (if any) of the filter {@code coll}, then {@code collectArguments(mh, 0, coll)}
3157      * is equivalent to {@code filterReturnValue(coll, mh)}.
3158      * If the filter method handle {@code coll} consumes one argument and produces
3159      * a non-void result, then {@code collectArguments(mh, N, coll)}
3160      * is equivalent to {@code filterArguments(mh, N, coll)}.
3161      * Other equivalences are possible but would require argument permutation.
3162      *
3163      * @param target the method handle to invoke after filtering the subsequence of arguments
3164      * @param pos the position of the first adapter argument to pass to the filter,
3165      *            and/or the target argument which receives the result of the filter
3166      * @param filter method handle to call on the subsequence of arguments
3167      * @return method handle which incorporates the specified argument subsequence filtering logic
3168      * @throws NullPointerException if either argument is null
3169      * @throws IllegalArgumentException if the return type of {@code filter}
3170      *          is non-void and is not the same as the {@code pos} argument of the target,
3171      *          or if {@code pos} is not between 0 and the target's arity, inclusive,
3172      *          or if the resulting method handle's type would have
3173      *          <a href="MethodHandle.html#maxarity">too many parameters</a>
3174      * @see MethodHandles#foldArguments
3175      * @see MethodHandles#filterArguments
3176      * @see MethodHandles#filterReturnValue
3177      */
3178     public static
collectArguments(MethodHandle target, int pos, MethodHandle filter)3179     MethodHandle collectArguments(MethodHandle target, int pos, MethodHandle filter) {
3180         MethodType newType = collectArgumentsChecks(target, pos, filter);
3181         return new Transformers.CollectArguments(target, filter, pos, newType);
3182     }
3183 
collectArgumentsChecks(MethodHandle target, int pos, MethodHandle filter)3184     private static MethodType collectArgumentsChecks(MethodHandle target, int pos, MethodHandle filter) throws RuntimeException {
3185         MethodType targetType = target.type();
3186         MethodType filterType = filter.type();
3187         Class<?> rtype = filterType.returnType();
3188         List<Class<?>> filterArgs = filterType.parameterList();
3189         if (rtype == void.class) {
3190             return targetType.insertParameterTypes(pos, filterArgs);
3191         }
3192         if (rtype != targetType.parameterType(pos)) {
3193             throw newIllegalArgumentException("target and filter types do not match", targetType, filterType);
3194         }
3195         return targetType.dropParameterTypes(pos, pos+1).insertParameterTypes(pos, filterArgs);
3196     }
3197 
3198     /**
3199      * Adapts a target method handle by post-processing
3200      * its return value (if any) with a filter (another method handle).
3201      * The result of the filter is returned from the adapter.
3202      * <p>
3203      * If the target returns a value, the filter must accept that value as
3204      * its only argument.
3205      * If the target returns void, the filter must accept no arguments.
3206      * <p>
3207      * The return type of the filter
3208      * replaces the return type of the target
3209      * in the resulting adapted method handle.
3210      * The argument type of the filter (if any) must be identical to the
3211      * return type of the target.
3212      * <p><b>Example:</b>
3213      * <blockquote><pre>{@code
3214 import static java.lang.invoke.MethodHandles.*;
3215 import static java.lang.invoke.MethodType.*;
3216 ...
3217 MethodHandle cat = lookup().findVirtual(String.class,
3218   "concat", methodType(String.class, String.class));
3219 MethodHandle length = lookup().findVirtual(String.class,
3220   "length", methodType(int.class));
3221 System.out.println((String) cat.invokeExact("x", "y")); // xy
3222 MethodHandle f0 = filterReturnValue(cat, length);
3223 System.out.println((int) f0.invokeExact("x", "y")); // 2
3224      * }</pre></blockquote>
3225      * <p> Here is pseudocode for the resulting adapter:
3226      * <blockquote><pre>{@code
3227      * V target(A...);
3228      * T filter(V);
3229      * T adapter(A... a) {
3230      *   V v = target(a...);
3231      *   return filter(v);
3232      * }
3233      * // and if the target has a void return:
3234      * void target2(A...);
3235      * T filter2();
3236      * T adapter2(A... a) {
3237      *   target2(a...);
3238      *   return filter2();
3239      * }
3240      * // and if the filter has a void return:
3241      * V target3(A...);
3242      * void filter3(V);
3243      * void adapter3(A... a) {
3244      *   V v = target3(a...);
3245      *   filter3(v);
3246      * }
3247      * }</pre></blockquote>
3248      * @param target the method handle to invoke before filtering the return value
3249      * @param filter method handle to call on the return value
3250      * @return method handle which incorporates the specified return value filtering logic
3251      * @throws NullPointerException if either argument is null
3252      * @throws IllegalArgumentException if the argument list of {@code filter}
3253      *          does not match the return type of target as described above
3254      */
3255     public static
filterReturnValue(MethodHandle target, MethodHandle filter)3256     MethodHandle filterReturnValue(MethodHandle target, MethodHandle filter) {
3257         MethodType targetType = target.type();
3258         MethodType filterType = filter.type();
3259         filterReturnValueChecks(targetType, filterType);
3260 
3261         return new Transformers.FilterReturnValue(target, filter);
3262     }
3263 
filterReturnValueChecks(MethodType targetType, MethodType filterType)3264     private static void filterReturnValueChecks(MethodType targetType, MethodType filterType) throws RuntimeException {
3265         Class<?> rtype = targetType.returnType();
3266         int filterValues = filterType.parameterCount();
3267         if (filterValues == 0
3268                 ? (rtype != void.class)
3269                 : (rtype != filterType.parameterType(0) || filterValues != 1))
3270             throw newIllegalArgumentException("target and filter types do not match", targetType, filterType);
3271     }
3272 
3273     /**
3274      * Adapts a target method handle by pre-processing
3275      * some of its arguments, and then calling the target with
3276      * the result of the pre-processing, inserted into the original
3277      * sequence of arguments.
3278      * <p>
3279      * The pre-processing is performed by {@code combiner}, a second method handle.
3280      * Of the arguments passed to the adapter, the first {@code N} arguments
3281      * are copied to the combiner, which is then called.
3282      * (Here, {@code N} is defined as the parameter count of the combiner.)
3283      * After this, control passes to the target, with any result
3284      * from the combiner inserted before the original {@code N} incoming
3285      * arguments.
3286      * <p>
3287      * If the combiner returns a value, the first parameter type of the target
3288      * must be identical with the return type of the combiner, and the next
3289      * {@code N} parameter types of the target must exactly match the parameters
3290      * of the combiner.
3291      * <p>
3292      * If the combiner has a void return, no result will be inserted,
3293      * and the first {@code N} parameter types of the target
3294      * must exactly match the parameters of the combiner.
3295      * <p>
3296      * The resulting adapter is the same type as the target, except that the
3297      * first parameter type is dropped,
3298      * if it corresponds to the result of the combiner.
3299      * <p>
3300      * (Note that {@link #dropArguments(MethodHandle,int,List) dropArguments} can be used to remove any arguments
3301      * that either the combiner or the target does not wish to receive.
3302      * If some of the incoming arguments are destined only for the combiner,
3303      * consider using {@link MethodHandle#asCollector asCollector} instead, since those
3304      * arguments will not need to be live on the stack on entry to the
3305      * target.)
3306      * <p><b>Example:</b>
3307      * <blockquote><pre>{@code
3308 import static java.lang.invoke.MethodHandles.*;
3309 import static java.lang.invoke.MethodType.*;
3310 ...
3311 MethodHandle trace = publicLookup().findVirtual(java.io.PrintStream.class,
3312   "println", methodType(void.class, String.class))
3313     .bindTo(System.out);
3314 MethodHandle cat = lookup().findVirtual(String.class,
3315   "concat", methodType(String.class, String.class));
3316 assertEquals("boojum", (String) cat.invokeExact("boo", "jum"));
3317 MethodHandle catTrace = foldArguments(cat, trace);
3318 // also prints "boo":
3319 assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
3320      * }</pre></blockquote>
3321      * <p> Here is pseudocode for the resulting adapter:
3322      * <blockquote><pre>{@code
3323      * // there are N arguments in A...
3324      * T target(V, A[N]..., B...);
3325      * V combiner(A...);
3326      * T adapter(A... a, B... b) {
3327      *   V v = combiner(a...);
3328      *   return target(v, a..., b...);
3329      * }
3330      * // and if the combiner has a void return:
3331      * T target2(A[N]..., B...);
3332      * void combiner2(A...);
3333      * T adapter2(A... a, B... b) {
3334      *   combiner2(a...);
3335      *   return target2(a..., b...);
3336      * }
3337      * }</pre></blockquote>
3338      * @param target the method handle to invoke after arguments are combined
3339      * @param combiner method handle to call initially on the incoming arguments
3340      * @return method handle which incorporates the specified argument folding logic
3341      * @throws NullPointerException if either argument is null
3342      * @throws IllegalArgumentException if {@code combiner}'s return type
3343      *          is non-void and not the same as the first argument type of
3344      *          the target, or if the initial {@code N} argument types
3345      *          of the target
3346      *          (skipping one matching the {@code combiner}'s return type)
3347      *          are not identical with the argument types of {@code combiner}
3348      */
3349     public static
foldArguments(MethodHandle target, MethodHandle combiner)3350     MethodHandle foldArguments(MethodHandle target, MethodHandle combiner) {
3351         int foldPos = 0;
3352         MethodType targetType = target.type();
3353         MethodType combinerType = combiner.type();
3354         Class<?> rtype = foldArgumentChecks(foldPos, targetType, combinerType);
3355 
3356         return new Transformers.FoldArguments(target, combiner);
3357     }
3358 
foldArgumentChecks(int foldPos, MethodType targetType, MethodType combinerType)3359     private static Class<?> foldArgumentChecks(int foldPos, MethodType targetType, MethodType combinerType) {
3360         int foldArgs   = combinerType.parameterCount();
3361         Class<?> rtype = combinerType.returnType();
3362         int foldVals = rtype == void.class ? 0 : 1;
3363         int afterInsertPos = foldPos + foldVals;
3364         boolean ok = (targetType.parameterCount() >= afterInsertPos + foldArgs);
3365         if (ok && !(combinerType.parameterList()
3366                     .equals(targetType.parameterList().subList(afterInsertPos,
3367                                                                afterInsertPos + foldArgs))))
3368             ok = false;
3369         if (ok && foldVals != 0 && combinerType.returnType() != targetType.parameterType(0))
3370             ok = false;
3371         if (!ok)
3372             throw misMatchedTypes("target and combiner types", targetType, combinerType);
3373         return rtype;
3374     }
3375 
3376     /**
3377      * Makes a method handle which adapts a target method handle,
3378      * by guarding it with a test, a boolean-valued method handle.
3379      * If the guard fails, a fallback handle is called instead.
3380      * All three method handles must have the same corresponding
3381      * argument and return types, except that the return type
3382      * of the test must be boolean, and the test is allowed
3383      * to have fewer arguments than the other two method handles.
3384      * <p> Here is pseudocode for the resulting adapter:
3385      * <blockquote><pre>{@code
3386      * boolean test(A...);
3387      * T target(A...,B...);
3388      * T fallback(A...,B...);
3389      * T adapter(A... a,B... b) {
3390      *   if (test(a...))
3391      *     return target(a..., b...);
3392      *   else
3393      *     return fallback(a..., b...);
3394      * }
3395      * }</pre></blockquote>
3396      * Note that the test arguments ({@code a...} in the pseudocode) cannot
3397      * be modified by execution of the test, and so are passed unchanged
3398      * from the caller to the target or fallback as appropriate.
3399      * @param test method handle used for test, must return boolean
3400      * @param target method handle to call if test passes
3401      * @param fallback method handle to call if test fails
3402      * @return method handle which incorporates the specified if/then/else logic
3403      * @throws NullPointerException if any argument is null
3404      * @throws IllegalArgumentException if {@code test} does not return boolean,
3405      *          or if all three method types do not match (with the return
3406      *          type of {@code test} changed to match that of the target).
3407      */
3408     public static
guardWithTest(MethodHandle test, MethodHandle target, MethodHandle fallback)3409     MethodHandle guardWithTest(MethodHandle test,
3410                                MethodHandle target,
3411                                MethodHandle fallback) {
3412         MethodType gtype = test.type();
3413         MethodType ttype = target.type();
3414         MethodType ftype = fallback.type();
3415         if (!ttype.equals(ftype))
3416             throw misMatchedTypes("target and fallback types", ttype, ftype);
3417         if (gtype.returnType() != boolean.class)
3418             throw newIllegalArgumentException("guard type is not a predicate "+gtype);
3419         List<Class<?>> targs = ttype.parameterList();
3420         List<Class<?>> gargs = gtype.parameterList();
3421         if (!targs.equals(gargs)) {
3422             int gpc = gargs.size(), tpc = targs.size();
3423             if (gpc >= tpc || !targs.subList(0, gpc).equals(gargs))
3424                 throw misMatchedTypes("target and test types", ttype, gtype);
3425             test = dropArguments(test, gpc, targs.subList(gpc, tpc));
3426             gtype = test.type();
3427         }
3428 
3429         return new Transformers.GuardWithTest(test, target, fallback);
3430     }
3431 
misMatchedTypes(String what, MethodType t1, MethodType t2)3432     static RuntimeException misMatchedTypes(String what, MethodType t1, MethodType t2) {
3433         return newIllegalArgumentException(what + " must match: " + t1 + " != " + t2);
3434     }
3435 
3436     /**
3437      * Makes a method handle which adapts a target method handle,
3438      * by running it inside an exception handler.
3439      * If the target returns normally, the adapter returns that value.
3440      * If an exception matching the specified type is thrown, the fallback
3441      * handle is called instead on the exception, plus the original arguments.
3442      * <p>
3443      * The target and handler must have the same corresponding
3444      * argument and return types, except that handler may omit trailing arguments
3445      * (similarly to the predicate in {@link #guardWithTest guardWithTest}).
3446      * Also, the handler must have an extra leading parameter of {@code exType} or a supertype.
3447      * <p> Here is pseudocode for the resulting adapter:
3448      * <blockquote><pre>{@code
3449      * T target(A..., B...);
3450      * T handler(ExType, A...);
3451      * T adapter(A... a, B... b) {
3452      *   try {
3453      *     return target(a..., b...);
3454      *   } catch (ExType ex) {
3455      *     return handler(ex, a...);
3456      *   }
3457      * }
3458      * }</pre></blockquote>
3459      * Note that the saved arguments ({@code a...} in the pseudocode) cannot
3460      * be modified by execution of the target, and so are passed unchanged
3461      * from the caller to the handler, if the handler is invoked.
3462      * <p>
3463      * The target and handler must return the same type, even if the handler
3464      * always throws.  (This might happen, for instance, because the handler
3465      * is simulating a {@code finally} clause).
3466      * To create such a throwing handler, compose the handler creation logic
3467      * with {@link #throwException throwException},
3468      * in order to create a method handle of the correct return type.
3469      * @param target method handle to call
3470      * @param exType the type of exception which the handler will catch
3471      * @param handler method handle to call if a matching exception is thrown
3472      * @return method handle which incorporates the specified try/catch logic
3473      * @throws NullPointerException if any argument is null
3474      * @throws IllegalArgumentException if {@code handler} does not accept
3475      *          the given exception type, or if the method handle types do
3476      *          not match in their return types and their
3477      *          corresponding parameters
3478      */
3479     public static
catchException(MethodHandle target, Class<? extends Throwable> exType, MethodHandle handler)3480     MethodHandle catchException(MethodHandle target,
3481                                 Class<? extends Throwable> exType,
3482                                 MethodHandle handler) {
3483         MethodType ttype = target.type();
3484         MethodType htype = handler.type();
3485         if (htype.parameterCount() < 1 ||
3486             !htype.parameterType(0).isAssignableFrom(exType))
3487             throw newIllegalArgumentException("handler does not accept exception type "+exType);
3488         if (htype.returnType() != ttype.returnType())
3489             throw misMatchedTypes("target and handler return types", ttype, htype);
3490         List<Class<?>> targs = ttype.parameterList();
3491         List<Class<?>> hargs = htype.parameterList();
3492         hargs = hargs.subList(1, hargs.size());  // omit leading parameter from handler
3493         if (!targs.equals(hargs)) {
3494             int hpc = hargs.size(), tpc = targs.size();
3495             if (hpc >= tpc || !targs.subList(0, hpc).equals(hargs))
3496                 throw misMatchedTypes("target and handler types", ttype, htype);
3497         }
3498 
3499         return new Transformers.CatchException(target, handler, exType);
3500     }
3501 
3502     /**
3503      * Produces a method handle which will throw exceptions of the given {@code exType}.
3504      * The method handle will accept a single argument of {@code exType},
3505      * and immediately throw it as an exception.
3506      * The method type will nominally specify a return of {@code returnType}.
3507      * The return type may be anything convenient:  It doesn't matter to the
3508      * method handle's behavior, since it will never return normally.
3509      * @param returnType the return type of the desired method handle
3510      * @param exType the parameter type of the desired method handle
3511      * @return method handle which can throw the given exceptions
3512      * @throws NullPointerException if either argument is null
3513      */
3514     public static
throwException(Class<?> returnType, Class<? extends Throwable> exType)3515     MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType) {
3516         if (!Throwable.class.isAssignableFrom(exType))
3517             throw new ClassCastException(exType.getName());
3518 
3519         return new Transformers.AlwaysThrow(returnType, exType);
3520     }
3521 }
3522