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.util.BitSet;
30 import java.util.List;
31 import java.util.Arrays;
32 import java.util.Objects;
33
34 import sun.invoke.util.ValueConversions;
35 import sun.invoke.util.VerifyAccess;
36 import sun.invoke.util.Wrapper;
37 import sun.reflect.CallerSensitive;
38 import sun.reflect.Reflection;
39 import sun.reflect.misc.ReflectUtil;
40 import sun.security.util.SecurityConstants;
41 import java.lang.invoke.LambdaForm.BasicType;
42 import static java.lang.invoke.LambdaForm.BasicType.*;
43 import static java.lang.invoke.MethodHandleStatics.*;
44 import static java.lang.invoke.MethodHandleImpl.Intrinsic;
45 import static java.lang.invoke.MethodHandleNatives.Constants.*;
46 import java.util.concurrent.ConcurrentHashMap;
47
48 /**
49 * This class consists exclusively of static methods that operate on or return
50 * method handles. They fall into several categories:
51 * <ul>
52 * <li>Lookup methods which help create method handles for methods and fields.
53 * <li>Combinator methods, which combine or transform pre-existing method handles into new ones.
54 * <li>Other factory methods to create method handles that emulate other common JVM operations or control flow patterns.
55 * </ul>
56 *
57 * @author John Rose, JSR 292 EG
58 * @since 1.7
59 */
60 public class MethodHandles {
61
62 private MethodHandles() { } // do not instantiate
63
64 private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
65 static { MethodHandleImpl.initStatics(); }
66 // See IMPL_LOOKUP below.
159 * restrictions must be enforced when a method handle is created.
160 * The caller class against which those restrictions are enforced
161 * is known as the {@linkplain #lookupClass lookup class}.
162 * <p>
163 * A lookup class which needs to create method handles will call
164 * {@link MethodHandles#lookup MethodHandles.lookup} to create a factory for itself.
165 * When the {@code Lookup} factory object is created, the identity of the lookup class is
166 * determined, and securely stored in the {@code Lookup} object.
167 * The lookup class (or its delegates) may then use factory methods
168 * on the {@code Lookup} object to create method handles for access-checked members.
169 * This includes all methods, constructors, and fields which are allowed to the lookup class,
170 * even private ones.
171 *
172 * <h1><a name="lookups"></a>Lookup Factory Methods</h1>
173 * The factory methods on a {@code Lookup} object correspond to all major
174 * use cases for methods, constructors, and fields.
175 * Each method handle created by a factory method is the functional
176 * equivalent of a particular <em>bytecode behavior</em>.
177 * (Bytecode behaviors are described in section 5.4.3.5 of the Java Virtual Machine Specification.)
178 * Here is a summary of the correspondence between these factory methods and
179 * the behavior the resulting method handles:
180 * <table border=1 cellpadding=5 summary="lookup method behaviors">
181 * <tr>
182 * <th><a name="equiv"></a>lookup expression</th>
183 * <th>member</th>
184 * <th>bytecode behavior</th>
185 * </tr>
186 * <tr>
187 * <td>{@link java.lang.invoke.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}</td>
188 * <td>{@code FT f;}</td><td>{@code (T) this.f;}</td>
189 * </tr>
190 * <tr>
191 * <td>{@link java.lang.invoke.MethodHandles.Lookup#findStaticGetter lookup.findStaticGetter(C.class,"f",FT.class)}</td>
192 * <td>{@code static}<br>{@code FT f;}</td><td>{@code (T) C.f;}</td>
193 * </tr>
194 * <tr>
195 * <td>{@link java.lang.invoke.MethodHandles.Lookup#findSetter lookup.findSetter(C.class,"f",FT.class)}</td>
196 * <td>{@code FT f;}</td><td>{@code this.f = x;}</td>
197 * </tr>
198 * <tr>
199 * <td>{@link java.lang.invoke.MethodHandles.Lookup#findStaticSetter lookup.findStaticSetter(C.class,"f",FT.class)}</td>
218 * <tr>
219 * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectGetter lookup.unreflectGetter(aField)}</td>
220 * <td>({@code static})?<br>{@code FT f;}</td><td>{@code (FT) aField.get(thisOrNull);}</td>
221 * </tr>
222 * <tr>
223 * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectSetter lookup.unreflectSetter(aField)}</td>
224 * <td>({@code static})?<br>{@code FT f;}</td><td>{@code aField.set(thisOrNull, arg);}</td>
225 * </tr>
226 * <tr>
227 * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
228 * <td>({@code static})?<br>{@code T m(A*);}</td><td>{@code (T) aMethod.invoke(thisOrNull, arg*);}</td>
229 * </tr>
230 * <tr>
231 * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor lookup.unreflectConstructor(aConstructor)}</td>
232 * <td>{@code C(A*);}</td><td>{@code (C) aConstructor.newInstance(arg*);}</td>
233 * </tr>
234 * <tr>
235 * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
236 * <td>({@code static})?<br>{@code T m(A*);}</td><td>{@code (T) aMethod.invoke(thisOrNull, arg*);}</td>
237 * </tr>
238 * </table>
239 *
240 * Here, the type {@code C} is the class or interface being searched for a member,
241 * documented as a parameter named {@code refc} in the lookup methods.
242 * The method type {@code MT} is composed from the return type {@code T}
243 * and the sequence of argument types {@code A*}.
244 * The constructor also has a sequence of argument types {@code A*} and
245 * is deemed to return the newly-created object of type {@code C}.
246 * Both {@code MT} and the field type {@code FT} are documented as a parameter named {@code type}.
247 * The formal parameter {@code this} stands for the self-reference of type {@code C};
248 * if it is present, it is always the leading argument to the method handle invocation.
249 * (In the case of some {@code protected} members, {@code this} may be
250 * restricted in type to the lookup class; see below.)
251 * The name {@code arg} stands for all the other method handle arguments.
252 * In the code examples for the Core Reflection API, the name {@code thisOrNull}
253 * stands for a null reference if the accessed method or field is static,
254 * and {@code this} otherwise.
255 * The names {@code aMethod}, {@code aField}, and {@code aConstructor} stand
256 * for reflective objects corresponding to the given members.
257 * <p>
258 * In cases where the given member is of variable arity (i.e., a method or constructor)
259 * the returned method handle will also be of {@linkplain MethodHandle#asVarargsCollector variable arity}.
260 * In all other cases, the returned method handle will be of fixed arity.
261 * <p style="font-size:smaller;">
262 * <em>Discussion:</em>
263 * The equivalence between looked-up method handles and underlying
264 * class members and bytecode behaviors
265 * can break down in a few ways:
266 * <ul style="font-size:smaller;">
267 * <li>If {@code C} is not symbolically accessible from the lookup class's loader,
268 * the lookup can still succeed, even when there is no equivalent
269 * Java expression or bytecoded constant.
270 * <li>Likewise, if {@code T} or {@code MT}
271 * is not symbolically accessible from the lookup class's loader,
272 * the lookup can still succeed.
273 * For example, lookups for {@code MethodHandle.invokeExact} and
274 * {@code MethodHandle.invoke} will always succeed, regardless of requested type.
275 * <li>If there is a security manager installed, it can forbid the lookup
276 * on various grounds (<a href="MethodHandles.Lookup.html#secmgr">see below</a>).
277 * By contrast, the {@code ldc} instruction on a {@code CONSTANT_MethodHandle}
406 * </ul>
407 * <p style="font-size:smaller;">
408 * Each of these permissions is a consequence of the fact that a lookup object
409 * with private access can be securely traced back to an originating class,
410 * whose <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> and Java language access permissions
411 * can be reliably determined and emulated by method handles.
412 *
413 * <h1><a name="secmgr"></a>Security manager interactions</h1>
414 * Although bytecode instructions can only refer to classes in
415 * a related class loader, this API can search for methods in any
416 * class, as long as a reference to its {@code Class} object is
417 * available. Such cross-loader references are also possible with the
418 * Core Reflection API, and are impossible to bytecode instructions
419 * such as {@code invokestatic} or {@code getfield}.
420 * There is a {@linkplain java.lang.SecurityManager security manager API}
421 * to allow applications to check such cross-loader references.
422 * These checks apply to both the {@code MethodHandles.Lookup} API
423 * and the Core Reflection API
424 * (as found on {@link java.lang.Class Class}).
425 * <p>
426 * If a security manager is present, member lookups are subject to
427 * additional checks.
428 * From one to three calls are made to the security manager.
429 * Any of these calls can refuse access by throwing a
430 * {@link java.lang.SecurityException SecurityException}.
431 * Define {@code smgr} as the security manager,
432 * {@code lookc} as the lookup class of the current lookup object,
433 * {@code refc} as the containing class in which the member
434 * is being sought, and {@code defc} as the class in which the
435 * member is actually defined.
436 * The value {@code lookc} is defined as <em>not present</em>
437 * if the current lookup object does not have
438 * <a href="MethodHandles.Lookup.html#privacc">private access</a>.
439 * The calls are made according to the following rules:
440 * <ul>
441 * <li><b>Step 1:</b>
442 * If {@code lookc} is not present, or if its class loader is not
443 * the same as or an ancestor of the class loader of {@code refc},
444 * then {@link SecurityManager#checkPackageAccess
445 * smgr.checkPackageAccess(refcPkg)} is called,
446 * where {@code refcPkg} is the package of {@code refc}.
447 * <li><b>Step 2:</b>
448 * If the retrieved member is not public and
449 * {@code lookc} is not present, then
450 * {@link SecurityManager#checkPermission smgr.checkPermission}
451 * with {@code RuntimePermission("accessDeclaredMembers")} is called.
452 * <li><b>Step 3:</b>
453 * If the retrieved member is not public,
454 * and if {@code lookc} is not present,
455 * and if {@code defc} and {@code refc} are different,
456 * then {@link SecurityManager#checkPackageAccess
457 * smgr.checkPackageAccess(defcPkg)} is called,
458 * where {@code defcPkg} is the package of {@code defc}.
459 * </ul>
460 * Security checks are performed after other access checks have passed.
461 * Therefore, the above rules presuppose a member that is public,
462 * or else that is being accessed from a lookup class that has
463 * rights to access the member.
464 *
465 * <h1><a name="callsens"></a>Caller sensitive methods</h1>
466 * A small number of Java methods have a special property called caller sensitivity.
467 * A <em>caller-sensitive</em> method can behave differently depending on the
468 * identity of its immediate caller.
469 * <p>
470 * If a method handle for a caller-sensitive method is requested,
471 * the general rules for <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> apply,
472 * but they take account of the lookup class in a special way.
473 * The resulting method handle behaves as if it were called
474 * from an instruction contained in the lookup class,
475 * so that the caller-sensitive method detects the lookup class.
476 * (By contrast, the invoker of the method handle is disregarded.)
477 * Thus, in the case of caller-sensitive methods,
478 * different lookup classes may give rise to
479 * differently behaving method handles.
480 * <p>
481 * In cases where the lookup object is
482 * {@link MethodHandles#publicLookup() publicLookup()},
483 * or some other lookup object without
905 assertEquals("[x, y, z]", pb.command().toString());
906 * }</pre></blockquote>
907 * @param refc the class or interface from which the method is accessed
908 * @param type the type of the method, with the receiver argument omitted, and a void return type
909 * @return the desired method handle
910 * @throws NoSuchMethodException if the constructor does not exist
911 * @throws IllegalAccessException if access checking fails
912 * or if the method's variable arity modifier bit
913 * is set and {@code asVarargsCollector} fails
914 * @exception SecurityException if a security manager is present and it
915 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
916 * @throws NullPointerException if any argument is null
917 */
918 public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
919 String name = "<init>";
920 MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
921 return getDirectConstructor(refc, ctor);
922 }
923
924 /**
925 * Produces an early-bound method handle for a virtual method.
926 * It will bypass checks for overriding methods on the receiver,
927 * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial}
928 * instruction from within the explicitly specified {@code specialCaller}.
929 * The type of the method handle will be that of the method,
930 * with a suitably restricted receiver type prepended.
931 * (The receiver type will be {@code specialCaller} or a subtype.)
932 * The method and all its argument types must be accessible
933 * to the lookup object.
934 * <p>
935 * Before method resolution,
936 * if the explicitly specified caller class is not identical with the
937 * lookup class, or if this lookup object does not have
938 * <a href="MethodHandles.Lookup.html#privacc">private access</a>
939 * privileges, the access fails.
940 * <p>
941 * The returned method handle will have
942 * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
943 * the method's variable arity modifier bit ({@code 0x0080}) is set.
944 * <p style="font-size:smaller;">
978 } catch (IllegalAccessException ex) { } // OK
979 Listie subl = new Listie() { public String toString() { return "[subclass]"; } };
980 assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method
981 * }</pre></blockquote>
982 *
983 * @param refc the class or interface from which the method is accessed
984 * @param name the name of the method (which must not be "<init>")
985 * @param type the type of the method, with the receiver argument omitted
986 * @param specialCaller the proposed calling class to perform the {@code invokespecial}
987 * @return the desired method handle
988 * @throws NoSuchMethodException if the method does not exist
989 * @throws IllegalAccessException if access checking fails
990 * or if the method's variable arity modifier bit
991 * is set and {@code asVarargsCollector} fails
992 * @exception SecurityException if a security manager is present and it
993 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
994 * @throws NullPointerException if any argument is null
995 */
996 public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
997 Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
998 checkSpecialCaller(specialCaller);
999 Lookup specialLookup = this.in(specialCaller);
1000 MemberName method = specialLookup.resolveOrFail(REF_invokeSpecial, refc, name, type);
1001 return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method, findBoundCallerClass(method));
1002 }
1003
1004 /**
1005 * Produces a method handle giving read access to a non-static field.
1006 * The type of the method handle will have a return type of the field's
1007 * value type.
1008 * The method handle's single argument will be the instance containing
1009 * the field.
1010 * Access checking is performed immediately on behalf of the lookup class.
1011 * @param refc the class or interface from which the method is accessed
1012 * @param name the field's name
1013 * @param type the field's type
1014 * @return a method handle which can load values from the field
1015 * @throws NoSuchFieldException if the field does not exist
1016 * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
1017 * @exception SecurityException if a security manager is present and it
1018 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1207 * as if {@code invokespecial} instruction were being linked.
1208 * <p>
1209 * Before method resolution,
1210 * if the explicitly specified caller class is not identical with the
1211 * lookup class, or if this lookup object does not have
1212 * <a href="MethodHandles.Lookup.html#privacc">private access</a>
1213 * privileges, the access fails.
1214 * <p>
1215 * The returned method handle will have
1216 * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1217 * the method's variable arity modifier bit ({@code 0x0080}) is set.
1218 * @param m the reflected method
1219 * @param specialCaller the class nominally calling the method
1220 * @return a method handle which can invoke the reflected method
1221 * @throws IllegalAccessException if access checking fails
1222 * or if the method's variable arity modifier bit
1223 * is set and {@code asVarargsCollector} fails
1224 * @throws NullPointerException if any argument is null
1225 */
1226 public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException {
1227 checkSpecialCaller(specialCaller);
1228 Lookup specialLookup = this.in(specialCaller);
1229 MemberName method = new MemberName(m, true);
1230 assert(method.isMethod());
1231 // ignore m.isAccessible: this is a new kind of access
1232 return specialLookup.getDirectMethodNoSecurityManager(REF_invokeSpecial, method.getDeclaringClass(), method, findBoundCallerClass(method));
1233 }
1234
1235 /**
1236 * Produces a method handle for a reflected constructor.
1237 * The type of the method handle will be that of the constructor,
1238 * with the return type changed to the declaring class.
1239 * The method handle will perform a {@code newInstance} operation,
1240 * creating a new instance of the constructor's class on the
1241 * arguments passed to the method handle.
1242 * <p>
1243 * If the constructor's {@code accessible} flag is not set,
1244 * access checking is performed immediately on behalf of the lookup class.
1245 * <p>
1246 * The returned method handle will have
1247 * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1427 return (allowedModes & PRIVATE) != 0;
1428 }
1429
1430 /**
1431 * Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
1432 * Determines a trustable caller class to compare with refc, the symbolic reference class.
1433 * If this lookup object has private access, then the caller class is the lookupClass.
1434 */
1435 void checkSecurityManager(Class<?> refc, MemberName m) {
1436 SecurityManager smgr = System.getSecurityManager();
1437 if (smgr == null) return;
1438 if (allowedModes == TRUSTED) return;
1439
1440 // Step 1:
1441 boolean fullPowerLookup = hasPrivateAccess();
1442 if (!fullPowerLookup ||
1443 !VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
1444 ReflectUtil.checkPackageAccess(refc);
1445 }
1446
1447 // Step 2:
1448 if (m.isPublic()) return;
1449 if (!fullPowerLookup) {
1450 smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
1451 }
1452
1453 // Step 3:
1454 Class<?> defc = m.getDeclaringClass();
1455 if (!fullPowerLookup && defc != refc) {
1456 ReflectUtil.checkPackageAccess(defc);
1457 }
1458 }
1459
1460 void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
1461 boolean wantStatic = (refKind == REF_invokeStatic);
1462 String message;
1463 if (m.isConstructor())
1464 message = "expected a method, not a constructor";
1465 else if (!m.isMethod())
1466 message = "expected a method";
1467 else if (wantStatic != m.isStatic())
1540 (defc == refc ||
1541 Modifier.isPublic(refc.getModifiers())));
1542 if (!classOK && (allowedModes & PACKAGE) != 0) {
1543 classOK = (VerifyAccess.isClassAccessible(defc, lookupClass(), ALL_MODES) &&
1544 (defc == refc ||
1545 VerifyAccess.isClassAccessible(refc, lookupClass(), ALL_MODES)));
1546 }
1547 if (!classOK)
1548 return "class is not public";
1549 if (Modifier.isPublic(mods))
1550 return "access to public member failed"; // (how?)
1551 if (Modifier.isPrivate(mods))
1552 return "member is private";
1553 if (Modifier.isProtected(mods))
1554 return "member is protected";
1555 return "member is private to package";
1556 }
1557
1558 private static final boolean ALLOW_NESTMATE_ACCESS = false;
1559
1560 private void checkSpecialCaller(Class<?> specialCaller) throws IllegalAccessException {
1561 int allowedModes = this.allowedModes;
1562 if (allowedModes == TRUSTED) return;
1563 if (!hasPrivateAccess()
1564 || (specialCaller != lookupClass()
1565 && !(ALLOW_NESTMATE_ACCESS &&
1566 VerifyAccess.isSamePackageMember(specialCaller, lookupClass()))))
1567 throw new MemberName(specialCaller).
1568 makeAccessException("no private access for invokespecial", this);
1569 }
1570
1571 private boolean restrictProtectedReceiver(MemberName method) {
1572 // The accessing class only has the right to use a protected member
1573 // on itself or a subclass. Enforce that restriction, from JVMS 5.4.4, etc.
1574 if (!method.isProtected() || method.isStatic()
1575 || allowedModes == TRUSTED
1576 || method.getDeclaringClass() == lookupClass()
1577 || VerifyAccess.isSamePackage(method.getDeclaringClass(), lookupClass())
1578 || (ALLOW_NESTMATE_ACCESS &&
1579 VerifyAccess.isSamePackageMember(method.getDeclaringClass(), lookupClass())))
1580 return false;
1581 return true;
1582 }
1583 private MethodHandle restrictReceiver(MemberName method, DirectMethodHandle mh, Class<?> caller) throws IllegalAccessException {
1584 assert(!method.isStatic());
1871 * <blockquote><pre>{@code
1872 MethodHandle invoker = MethodHandles.invoker(type);
1873 int spreadArgCount = type.parameterCount() - leadingArgCount;
1874 invoker = invoker.asSpreader(Object[].class, spreadArgCount);
1875 return invoker;
1876 * }</pre></blockquote>
1877 * This method throws no reflective or security exceptions.
1878 * @param type the desired target type
1879 * @param leadingArgCount number of fixed arguments, to be passed unchanged to the target
1880 * @return a method handle suitable for invoking any method handle of the given type
1881 * @throws NullPointerException if {@code type} is null
1882 * @throws IllegalArgumentException if {@code leadingArgCount} is not in
1883 * the range from 0 to {@code type.parameterCount()} inclusive,
1884 * or if the resulting method handle's type would have
1885 * <a href="MethodHandle.html#maxarity">too many parameters</a>
1886 */
1887 public static
1888 MethodHandle spreadInvoker(MethodType type, int leadingArgCount) {
1889 if (leadingArgCount < 0 || leadingArgCount > type.parameterCount())
1890 throw newIllegalArgumentException("bad argument count", leadingArgCount);
1891 type = type.asSpreaderType(Object[].class, type.parameterCount() - leadingArgCount);
1892 return type.invokers().spreadInvoker(leadingArgCount);
1893 }
1894
1895 /**
1896 * Produces a special <em>invoker method handle</em> which can be used to
1897 * invoke any method handle of the given type, as if by {@link MethodHandle#invokeExact invokeExact}.
1898 * The resulting invoker will have a type which is
1899 * exactly equal to the desired type, except that it will accept
1900 * an additional leading argument of type {@code MethodHandle}.
1901 * <p>
1902 * This method is equivalent to the following code (though it may be more efficient):
1903 * {@code publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)}
1904 *
1905 * <p style="font-size:smaller;">
1906 * <em>Discussion:</em>
1907 * Invoker method handles can be useful when working with variable method handles
1908 * of unknown types.
1909 * For example, to emulate an {@code invokeExact} call to a variable method
1910 * handle {@code M}, extract its type {@code T},
1911 * look up the invoker method {@code X} for {@code T},
2907 * T target2(A[N]..., B...);
2908 * void combiner2(A...);
2909 * T adapter2(A... a, B... b) {
2910 * combiner2(a...);
2911 * return target2(a..., b...);
2912 * }
2913 * }</pre></blockquote>
2914 * @param target the method handle to invoke after arguments are combined
2915 * @param combiner method handle to call initially on the incoming arguments
2916 * @return method handle which incorporates the specified argument folding logic
2917 * @throws NullPointerException if either argument is null
2918 * @throws IllegalArgumentException if {@code combiner}'s return type
2919 * is non-void and not the same as the first argument type of
2920 * the target, or if the initial {@code N} argument types
2921 * of the target
2922 * (skipping one matching the {@code combiner}'s return type)
2923 * are not identical with the argument types of {@code combiner}
2924 */
2925 public static
2926 MethodHandle foldArguments(MethodHandle target, MethodHandle combiner) {
2927 int foldPos = 0;
2928 MethodType targetType = target.type();
2929 MethodType combinerType = combiner.type();
2930 Class<?> rtype = foldArgumentChecks(foldPos, targetType, combinerType);
2931 BoundMethodHandle result = target.rebind();
2932 boolean dropResult = (rtype == void.class);
2933 // Note: This may cache too many distinct LFs. Consider backing off to varargs code.
2934 LambdaForm lform = result.editor().foldArgumentsForm(1 + foldPos, dropResult, combinerType.basicType());
2935 MethodType newType = targetType;
2936 if (!dropResult)
2937 newType = newType.dropParameterTypes(foldPos, foldPos + 1);
2938 result = result.copyWithExtendL(newType, lform, combiner);
2939 return result;
2940 }
2941
2942 private static Class<?> foldArgumentChecks(int foldPos, MethodType targetType, MethodType combinerType) {
2943 int foldArgs = combinerType.parameterCount();
2944 Class<?> rtype = combinerType.returnType();
2945 int foldVals = rtype == void.class ? 0 : 1;
2946 int afterInsertPos = foldPos + foldVals;
2947 boolean ok = (targetType.parameterCount() >= afterInsertPos + foldArgs);
2948 if (ok && !(combinerType.parameterList()
2949 .equals(targetType.parameterList().subList(afterInsertPos,
2950 afterInsertPos + foldArgs))))
2951 ok = false;
2952 if (ok && foldVals != 0 && combinerType.returnType() != targetType.parameterType(0))
2953 ok = false;
2954 if (!ok)
2955 throw misMatchedTypes("target and combiner types", targetType, combinerType);
2956 return rtype;
2957 }
2958
2959 /**
2960 * Makes a method handle which adapts a target method handle,
2961 * by guarding it with a test, a boolean-valued method handle.
2962 * If the guard fails, a fallback handle is called instead.
2963 * All three method handles must have the same corresponding
2964 * argument and return types, except that the return type
2965 * of the test must be boolean, and the test is allowed
2966 * to have fewer arguments than the other two method handles.
2967 * <p> Here is pseudocode for the resulting adapter:
2968 * <blockquote><pre>{@code
2969 * boolean test(A...);
2970 * T target(A...,B...);
2971 * T fallback(A...,B...);
2972 * T adapter(A... a,B... b) {
2994 MethodHandle fallback) {
2995 MethodType gtype = test.type();
2996 MethodType ttype = target.type();
2997 MethodType ftype = fallback.type();
2998 if (!ttype.equals(ftype))
2999 throw misMatchedTypes("target and fallback types", ttype, ftype);
3000 if (gtype.returnType() != boolean.class)
3001 throw newIllegalArgumentException("guard type is not a predicate "+gtype);
3002 List<Class<?>> targs = ttype.parameterList();
3003 List<Class<?>> gargs = gtype.parameterList();
3004 if (!targs.equals(gargs)) {
3005 int gpc = gargs.size(), tpc = targs.size();
3006 if (gpc >= tpc || !targs.subList(0, gpc).equals(gargs))
3007 throw misMatchedTypes("target and test types", ttype, gtype);
3008 test = dropArguments(test, gpc, targs.subList(gpc, tpc));
3009 gtype = test.type();
3010 }
3011 return MethodHandleImpl.makeGuardWithTest(test, target, fallback);
3012 }
3013
3014 static RuntimeException misMatchedTypes(String what, MethodType t1, MethodType t2) {
3015 return newIllegalArgumentException(what + " must match: " + t1 + " != " + t2);
3016 }
3017
3018 /**
3019 * Makes a method handle which adapts a target method handle,
3020 * by running it inside an exception handler.
3021 * If the target returns normally, the adapter returns that value.
3022 * If an exception matching the specified type is thrown, the fallback
3023 * handle is called instead on the exception, plus the original arguments.
3024 * <p>
3025 * The target and handler must have the same corresponding
3026 * argument and return types, except that handler may omit trailing arguments
3027 * (similarly to the predicate in {@link #guardWithTest guardWithTest}).
3028 * Also, the handler must have an extra leading parameter of {@code exType} or a supertype.
3029 * <p> Here is pseudocode for the resulting adapter:
3030 * <blockquote><pre>{@code
3031 * T target(A..., B...);
3032 * T handler(ExType, A...);
3033 * T adapter(A... a, B... b) {
3034 * try {
3040 * }</pre></blockquote>
3041 * Note that the saved arguments ({@code a...} in the pseudocode) cannot
3042 * be modified by execution of the target, and so are passed unchanged
3043 * from the caller to the handler, if the handler is invoked.
3044 * <p>
3045 * The target and handler must return the same type, even if the handler
3046 * always throws. (This might happen, for instance, because the handler
3047 * is simulating a {@code finally} clause).
3048 * To create such a throwing handler, compose the handler creation logic
3049 * with {@link #throwException throwException},
3050 * in order to create a method handle of the correct return type.
3051 * @param target method handle to call
3052 * @param exType the type of exception which the handler will catch
3053 * @param handler method handle to call if a matching exception is thrown
3054 * @return method handle which incorporates the specified try/catch logic
3055 * @throws NullPointerException if any argument is null
3056 * @throws IllegalArgumentException if {@code handler} does not accept
3057 * the given exception type, or if the method handle types do
3058 * not match in their return types and their
3059 * corresponding parameters
3060 */
3061 public static
3062 MethodHandle catchException(MethodHandle target,
3063 Class<? extends Throwable> exType,
3064 MethodHandle handler) {
3065 MethodType ttype = target.type();
3066 MethodType htype = handler.type();
3067 if (htype.parameterCount() < 1 ||
3068 !htype.parameterType(0).isAssignableFrom(exType))
3069 throw newIllegalArgumentException("handler does not accept exception type "+exType);
3070 if (htype.returnType() != ttype.returnType())
3071 throw misMatchedTypes("target and handler return types", ttype, htype);
3072 List<Class<?>> targs = ttype.parameterList();
3073 List<Class<?>> hargs = htype.parameterList();
3074 hargs = hargs.subList(1, hargs.size()); // omit leading parameter from handler
3075 if (!targs.equals(hargs)) {
3076 int hpc = hargs.size(), tpc = targs.size();
3077 if (hpc >= tpc || !targs.subList(0, hpc).equals(hargs))
3078 throw misMatchedTypes("target and handler types", ttype, htype);
3079 handler = dropArguments(handler, 1+hpc, targs.subList(hpc, tpc));
3083 }
3084
3085 /**
3086 * Produces a method handle which will throw exceptions of the given {@code exType}.
3087 * The method handle will accept a single argument of {@code exType},
3088 * and immediately throw it as an exception.
3089 * The method type will nominally specify a return of {@code returnType}.
3090 * The return type may be anything convenient: It doesn't matter to the
3091 * method handle's behavior, since it will never return normally.
3092 * @param returnType the return type of the desired method handle
3093 * @param exType the parameter type of the desired method handle
3094 * @return method handle which can throw the given exceptions
3095 * @throws NullPointerException if either argument is null
3096 */
3097 public static
3098 MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType) {
3099 if (!Throwable.class.isAssignableFrom(exType))
3100 throw new ClassCastException(exType.getName());
3101 return MethodHandleImpl.throwException(MethodType.methodType(returnType, exType));
3102 }
3103 }
|
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.util.*;
30
31 import sun.invoke.util.ValueConversions;
32 import sun.invoke.util.VerifyAccess;
33 import sun.invoke.util.Wrapper;
34 import sun.reflect.CallerSensitive;
35 import sun.reflect.Reflection;
36 import sun.reflect.misc.ReflectUtil;
37 import sun.security.util.SecurityConstants;
38 import java.lang.invoke.LambdaForm.BasicType;
39
40 import static java.lang.invoke.MethodHandleStatics.*;
41 import static java.lang.invoke.MethodHandleImpl.Intrinsic;
42 import static java.lang.invoke.MethodHandleNatives.Constants.*;
43 import java.util.concurrent.ConcurrentHashMap;
44 import java.util.stream.Collectors;
45 import java.util.stream.Stream;
46
47 /**
48 * This class consists exclusively of static methods that operate on or return
49 * method handles. They fall into several categories:
50 * <ul>
51 * <li>Lookup methods which help create method handles for methods and fields.
52 * <li>Combinator methods, which combine or transform pre-existing method handles into new ones.
53 * <li>Other factory methods to create method handles that emulate other common JVM operations or control flow patterns.
54 * </ul>
55 *
56 * @author John Rose, JSR 292 EG
57 * @since 1.7
58 */
59 public class MethodHandles {
60
61 private MethodHandles() { } // do not instantiate
62
63 private static final MemberName.Factory IMPL_NAMES = MemberName.getFactory();
64 static { MethodHandleImpl.initStatics(); }
65 // See IMPL_LOOKUP below.
158 * restrictions must be enforced when a method handle is created.
159 * The caller class against which those restrictions are enforced
160 * is known as the {@linkplain #lookupClass lookup class}.
161 * <p>
162 * A lookup class which needs to create method handles will call
163 * {@link MethodHandles#lookup MethodHandles.lookup} to create a factory for itself.
164 * When the {@code Lookup} factory object is created, the identity of the lookup class is
165 * determined, and securely stored in the {@code Lookup} object.
166 * The lookup class (or its delegates) may then use factory methods
167 * on the {@code Lookup} object to create method handles for access-checked members.
168 * This includes all methods, constructors, and fields which are allowed to the lookup class,
169 * even private ones.
170 *
171 * <h1><a name="lookups"></a>Lookup Factory Methods</h1>
172 * The factory methods on a {@code Lookup} object correspond to all major
173 * use cases for methods, constructors, and fields.
174 * Each method handle created by a factory method is the functional
175 * equivalent of a particular <em>bytecode behavior</em>.
176 * (Bytecode behaviors are described in section 5.4.3.5 of the Java Virtual Machine Specification.)
177 * Here is a summary of the correspondence between these factory methods and
178 * the behavior of the resulting method handles:
179 * <table border=1 cellpadding=5 summary="lookup method behaviors">
180 * <tr>
181 * <th><a name="equiv"></a>lookup expression</th>
182 * <th>member</th>
183 * <th>bytecode behavior</th>
184 * </tr>
185 * <tr>
186 * <td>{@link java.lang.invoke.MethodHandles.Lookup#findGetter lookup.findGetter(C.class,"f",FT.class)}</td>
187 * <td>{@code FT f;}</td><td>{@code (T) this.f;}</td>
188 * </tr>
189 * <tr>
190 * <td>{@link java.lang.invoke.MethodHandles.Lookup#findStaticGetter lookup.findStaticGetter(C.class,"f",FT.class)}</td>
191 * <td>{@code static}<br>{@code FT f;}</td><td>{@code (T) C.f;}</td>
192 * </tr>
193 * <tr>
194 * <td>{@link java.lang.invoke.MethodHandles.Lookup#findSetter lookup.findSetter(C.class,"f",FT.class)}</td>
195 * <td>{@code FT f;}</td><td>{@code this.f = x;}</td>
196 * </tr>
197 * <tr>
198 * <td>{@link java.lang.invoke.MethodHandles.Lookup#findStaticSetter lookup.findStaticSetter(C.class,"f",FT.class)}</td>
217 * <tr>
218 * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectGetter lookup.unreflectGetter(aField)}</td>
219 * <td>({@code static})?<br>{@code FT f;}</td><td>{@code (FT) aField.get(thisOrNull);}</td>
220 * </tr>
221 * <tr>
222 * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectSetter lookup.unreflectSetter(aField)}</td>
223 * <td>({@code static})?<br>{@code FT f;}</td><td>{@code aField.set(thisOrNull, arg);}</td>
224 * </tr>
225 * <tr>
226 * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
227 * <td>({@code static})?<br>{@code T m(A*);}</td><td>{@code (T) aMethod.invoke(thisOrNull, arg*);}</td>
228 * </tr>
229 * <tr>
230 * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflectConstructor lookup.unreflectConstructor(aConstructor)}</td>
231 * <td>{@code C(A*);}</td><td>{@code (C) aConstructor.newInstance(arg*);}</td>
232 * </tr>
233 * <tr>
234 * <td>{@link java.lang.invoke.MethodHandles.Lookup#unreflect lookup.unreflect(aMethod)}</td>
235 * <td>({@code static})?<br>{@code T m(A*);}</td><td>{@code (T) aMethod.invoke(thisOrNull, arg*);}</td>
236 * </tr>
237 * <tr>
238 * <td>{@link java.lang.invoke.MethodHandles.Lookup#findClass lookup.findClass("C")}</td>
239 * <td>{@code class C { ... }}</td><td>{@code C.class;}</td>
240 * </tr>
241 * </table>
242 *
243 * Here, the type {@code C} is the class or interface being searched for a member,
244 * documented as a parameter named {@code refc} in the lookup methods.
245 * The method type {@code MT} is composed from the return type {@code T}
246 * and the sequence of argument types {@code A*}.
247 * The constructor also has a sequence of argument types {@code A*} and
248 * is deemed to return the newly-created object of type {@code C}.
249 * Both {@code MT} and the field type {@code FT} are documented as a parameter named {@code type}.
250 * The formal parameter {@code this} stands for the self-reference of type {@code C};
251 * if it is present, it is always the leading argument to the method handle invocation.
252 * (In the case of some {@code protected} members, {@code this} may be
253 * restricted in type to the lookup class; see below.)
254 * The name {@code arg} stands for all the other method handle arguments.
255 * In the code examples for the Core Reflection API, the name {@code thisOrNull}
256 * stands for a null reference if the accessed method or field is static,
257 * and {@code this} otherwise.
258 * The names {@code aMethod}, {@code aField}, and {@code aConstructor} stand
259 * for reflective objects corresponding to the given members.
260 * <p>
261 * The bytecode behavior for a {@code findClass} operation is a load of a constant class,
262 * as if by {@code ldc CONSTANT_Class}.
263 * The behavior is represented, not as a method handle, but directly as a {@code Class} constant.
264 * <p>
265 * In cases where the given member is of variable arity (i.e., a method or constructor)
266 * the returned method handle will also be of {@linkplain MethodHandle#asVarargsCollector variable arity}.
267 * In all other cases, the returned method handle will be of fixed arity.
268 * <p style="font-size:smaller;">
269 * <em>Discussion:</em>
270 * The equivalence between looked-up method handles and underlying
271 * class members and bytecode behaviors
272 * can break down in a few ways:
273 * <ul style="font-size:smaller;">
274 * <li>If {@code C} is not symbolically accessible from the lookup class's loader,
275 * the lookup can still succeed, even when there is no equivalent
276 * Java expression or bytecoded constant.
277 * <li>Likewise, if {@code T} or {@code MT}
278 * is not symbolically accessible from the lookup class's loader,
279 * the lookup can still succeed.
280 * For example, lookups for {@code MethodHandle.invokeExact} and
281 * {@code MethodHandle.invoke} will always succeed, regardless of requested type.
282 * <li>If there is a security manager installed, it can forbid the lookup
283 * on various grounds (<a href="MethodHandles.Lookup.html#secmgr">see below</a>).
284 * By contrast, the {@code ldc} instruction on a {@code CONSTANT_MethodHandle}
413 * </ul>
414 * <p style="font-size:smaller;">
415 * Each of these permissions is a consequence of the fact that a lookup object
416 * with private access can be securely traced back to an originating class,
417 * whose <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> and Java language access permissions
418 * can be reliably determined and emulated by method handles.
419 *
420 * <h1><a name="secmgr"></a>Security manager interactions</h1>
421 * Although bytecode instructions can only refer to classes in
422 * a related class loader, this API can search for methods in any
423 * class, as long as a reference to its {@code Class} object is
424 * available. Such cross-loader references are also possible with the
425 * Core Reflection API, and are impossible to bytecode instructions
426 * such as {@code invokestatic} or {@code getfield}.
427 * There is a {@linkplain java.lang.SecurityManager security manager API}
428 * to allow applications to check such cross-loader references.
429 * These checks apply to both the {@code MethodHandles.Lookup} API
430 * and the Core Reflection API
431 * (as found on {@link java.lang.Class Class}).
432 * <p>
433 * If a security manager is present, member and class lookups are subject to
434 * additional checks.
435 * From one to three calls are made to the security manager.
436 * Any of these calls can refuse access by throwing a
437 * {@link java.lang.SecurityException SecurityException}.
438 * Define {@code smgr} as the security manager,
439 * {@code lookc} as the lookup class of the current lookup object,
440 * {@code refc} as the containing class in which the member
441 * is being sought, and {@code defc} as the class in which the
442 * member is actually defined.
443 * (If a class or other type is being accessed,
444 * the {@code refc} and {@code defc} values are the class itself.)
445 * The value {@code lookc} is defined as <em>not present</em>
446 * if the current lookup object does not have
447 * <a href="MethodHandles.Lookup.html#privacc">private access</a>.
448 * The calls are made according to the following rules:
449 * <ul>
450 * <li><b>Step 1:</b>
451 * If {@code lookc} is not present, or if its class loader is not
452 * the same as or an ancestor of the class loader of {@code refc},
453 * then {@link SecurityManager#checkPackageAccess
454 * smgr.checkPackageAccess(refcPkg)} is called,
455 * where {@code refcPkg} is the package of {@code refc}.
456 * <li><b>Step 2a:</b>
457 * If the retrieved member is not public and
458 * {@code lookc} is not present, then
459 * {@link SecurityManager#checkPermission smgr.checkPermission}
460 * with {@code RuntimePermission("accessDeclaredMembers")} is called.
461 * <li><b>Step 2b:</b>
462 * If the retrieved class has a {@code null} class loader,
463 * and {@code lookc} is not present, then
464 * {@link SecurityManager#checkPermission smgr.checkPermission}
465 * with {@code RuntimePermission("getClassLoader")} is called.
466 * <li><b>Step 3:</b>
467 * If the retrieved member is not public,
468 * and if {@code lookc} is not present,
469 * and if {@code defc} and {@code refc} are different,
470 * then {@link SecurityManager#checkPackageAccess
471 * smgr.checkPackageAccess(defcPkg)} is called,
472 * where {@code defcPkg} is the package of {@code defc}.
473 * </ul>
474 * Security checks are performed after other access checks have passed.
475 * Therefore, the above rules presuppose a member or class that is public,
476 * or else that is being accessed from a lookup class that has
477 * rights to access the member or class.
478 *
479 * <h1><a name="callsens"></a>Caller sensitive methods</h1>
480 * A small number of Java methods have a special property called caller sensitivity.
481 * A <em>caller-sensitive</em> method can behave differently depending on the
482 * identity of its immediate caller.
483 * <p>
484 * If a method handle for a caller-sensitive method is requested,
485 * the general rules for <a href="MethodHandles.Lookup.html#equiv">bytecode behaviors</a> apply,
486 * but they take account of the lookup class in a special way.
487 * The resulting method handle behaves as if it were called
488 * from an instruction contained in the lookup class,
489 * so that the caller-sensitive method detects the lookup class.
490 * (By contrast, the invoker of the method handle is disregarded.)
491 * Thus, in the case of caller-sensitive methods,
492 * different lookup classes may give rise to
493 * differently behaving method handles.
494 * <p>
495 * In cases where the lookup object is
496 * {@link MethodHandles#publicLookup() publicLookup()},
497 * or some other lookup object without
919 assertEquals("[x, y, z]", pb.command().toString());
920 * }</pre></blockquote>
921 * @param refc the class or interface from which the method is accessed
922 * @param type the type of the method, with the receiver argument omitted, and a void return type
923 * @return the desired method handle
924 * @throws NoSuchMethodException if the constructor does not exist
925 * @throws IllegalAccessException if access checking fails
926 * or if the method's variable arity modifier bit
927 * is set and {@code asVarargsCollector} fails
928 * @exception SecurityException if a security manager is present and it
929 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
930 * @throws NullPointerException if any argument is null
931 */
932 public MethodHandle findConstructor(Class<?> refc, MethodType type) throws NoSuchMethodException, IllegalAccessException {
933 String name = "<init>";
934 MemberName ctor = resolveOrFail(REF_newInvokeSpecial, refc, name, type);
935 return getDirectConstructor(refc, ctor);
936 }
937
938 /**
939 * Looks up a class by name from the lookup context defined by this {@code Lookup} object. The static
940 * initializer of the class is not run.
941 *
942 * @param targetName the fully qualified name of the class to be looked up.
943 * @return the requested class.
944 * @exception SecurityException if a security manager is present and it
945 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
946 * @throws LinkageError if the linkage fails
947 * @throws ClassNotFoundException if the class does not exist.
948 * @throws IllegalAccessException if the class is not accessible, using the allowed access
949 * modes.
950 * @exception SecurityException if a security manager is present and it
951 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
952 * @since 9
953 */
954 public Class<?> findClass(String targetName) throws ClassNotFoundException, IllegalAccessException {
955 Class<?> targetClass = Class.forName(targetName, false, lookupClass.getClassLoader());
956 return accessClass(targetClass);
957 }
958
959 /**
960 * Determines if a class can be accessed from the lookup context defined by this {@code Lookup} object. The
961 * static initializer of the class is not run.
962 *
963 * @param targetClass the class to be access-checked
964 *
965 * @return the class that has been access-checked
966 *
967 * @throws IllegalAccessException if the class is not accessible from the lookup class, using the allowed access
968 * modes.
969 * @exception SecurityException if a security manager is present and it
970 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
971 * @since 9
972 */
973 public Class<?> accessClass(Class<?> targetClass) throws IllegalAccessException {
974 if (!VerifyAccess.isClassAccessible(targetClass, lookupClass, allowedModes)) {
975 throw new MemberName(targetClass).makeAccessException("access violation", this);
976 }
977 checkSecurityManager(targetClass, null);
978 return targetClass;
979 }
980
981 /**
982 * Produces an early-bound method handle for a virtual method.
983 * It will bypass checks for overriding methods on the receiver,
984 * <a href="MethodHandles.Lookup.html#equiv">as if called</a> from an {@code invokespecial}
985 * instruction from within the explicitly specified {@code specialCaller}.
986 * The type of the method handle will be that of the method,
987 * with a suitably restricted receiver type prepended.
988 * (The receiver type will be {@code specialCaller} or a subtype.)
989 * The method and all its argument types must be accessible
990 * to the lookup object.
991 * <p>
992 * Before method resolution,
993 * if the explicitly specified caller class is not identical with the
994 * lookup class, or if this lookup object does not have
995 * <a href="MethodHandles.Lookup.html#privacc">private access</a>
996 * privileges, the access fails.
997 * <p>
998 * The returned method handle will have
999 * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1000 * the method's variable arity modifier bit ({@code 0x0080}) is set.
1001 * <p style="font-size:smaller;">
1035 } catch (IllegalAccessException ex) { } // OK
1036 Listie subl = new Listie() { public String toString() { return "[subclass]"; } };
1037 assertEquals(""+l, (String) MH_this.invokeExact(subl)); // Listie method
1038 * }</pre></blockquote>
1039 *
1040 * @param refc the class or interface from which the method is accessed
1041 * @param name the name of the method (which must not be "<init>")
1042 * @param type the type of the method, with the receiver argument omitted
1043 * @param specialCaller the proposed calling class to perform the {@code invokespecial}
1044 * @return the desired method handle
1045 * @throws NoSuchMethodException if the method does not exist
1046 * @throws IllegalAccessException if access checking fails
1047 * or if the method's variable arity modifier bit
1048 * is set and {@code asVarargsCollector} fails
1049 * @exception SecurityException if a security manager is present and it
1050 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1051 * @throws NullPointerException if any argument is null
1052 */
1053 public MethodHandle findSpecial(Class<?> refc, String name, MethodType type,
1054 Class<?> specialCaller) throws NoSuchMethodException, IllegalAccessException {
1055 checkSpecialCaller(specialCaller, refc);
1056 Lookup specialLookup = this.in(specialCaller);
1057 MemberName method = specialLookup.resolveOrFail(REF_invokeSpecial, refc, name, type);
1058 return specialLookup.getDirectMethod(REF_invokeSpecial, refc, method, findBoundCallerClass(method));
1059 }
1060
1061 /**
1062 * Produces a method handle giving read access to a non-static field.
1063 * The type of the method handle will have a return type of the field's
1064 * value type.
1065 * The method handle's single argument will be the instance containing
1066 * the field.
1067 * Access checking is performed immediately on behalf of the lookup class.
1068 * @param refc the class or interface from which the method is accessed
1069 * @param name the field's name
1070 * @param type the field's type
1071 * @return a method handle which can load values from the field
1072 * @throws NoSuchFieldException if the field does not exist
1073 * @throws IllegalAccessException if access checking fails, or if the field is {@code static}
1074 * @exception SecurityException if a security manager is present and it
1075 * <a href="MethodHandles.Lookup.html#secmgr">refuses access</a>
1264 * as if {@code invokespecial} instruction were being linked.
1265 * <p>
1266 * Before method resolution,
1267 * if the explicitly specified caller class is not identical with the
1268 * lookup class, or if this lookup object does not have
1269 * <a href="MethodHandles.Lookup.html#privacc">private access</a>
1270 * privileges, the access fails.
1271 * <p>
1272 * The returned method handle will have
1273 * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1274 * the method's variable arity modifier bit ({@code 0x0080}) is set.
1275 * @param m the reflected method
1276 * @param specialCaller the class nominally calling the method
1277 * @return a method handle which can invoke the reflected method
1278 * @throws IllegalAccessException if access checking fails
1279 * or if the method's variable arity modifier bit
1280 * is set and {@code asVarargsCollector} fails
1281 * @throws NullPointerException if any argument is null
1282 */
1283 public MethodHandle unreflectSpecial(Method m, Class<?> specialCaller) throws IllegalAccessException {
1284 checkSpecialCaller(specialCaller, null);
1285 Lookup specialLookup = this.in(specialCaller);
1286 MemberName method = new MemberName(m, true);
1287 assert(method.isMethod());
1288 // ignore m.isAccessible: this is a new kind of access
1289 return specialLookup.getDirectMethodNoSecurityManager(REF_invokeSpecial, method.getDeclaringClass(), method, findBoundCallerClass(method));
1290 }
1291
1292 /**
1293 * Produces a method handle for a reflected constructor.
1294 * The type of the method handle will be that of the constructor,
1295 * with the return type changed to the declaring class.
1296 * The method handle will perform a {@code newInstance} operation,
1297 * creating a new instance of the constructor's class on the
1298 * arguments passed to the method handle.
1299 * <p>
1300 * If the constructor's {@code accessible} flag is not set,
1301 * access checking is performed immediately on behalf of the lookup class.
1302 * <p>
1303 * The returned method handle will have
1304 * {@linkplain MethodHandle#asVarargsCollector variable arity} if and only if
1484 return (allowedModes & PRIVATE) != 0;
1485 }
1486
1487 /**
1488 * Perform necessary <a href="MethodHandles.Lookup.html#secmgr">access checks</a>.
1489 * Determines a trustable caller class to compare with refc, the symbolic reference class.
1490 * If this lookup object has private access, then the caller class is the lookupClass.
1491 */
1492 void checkSecurityManager(Class<?> refc, MemberName m) {
1493 SecurityManager smgr = System.getSecurityManager();
1494 if (smgr == null) return;
1495 if (allowedModes == TRUSTED) return;
1496
1497 // Step 1:
1498 boolean fullPowerLookup = hasPrivateAccess();
1499 if (!fullPowerLookup ||
1500 !VerifyAccess.classLoaderIsAncestor(lookupClass, refc)) {
1501 ReflectUtil.checkPackageAccess(refc);
1502 }
1503
1504 if (m == null) { // findClass or accessClass
1505 // Step 2b:
1506 if (!fullPowerLookup) {
1507 smgr.checkPermission(SecurityConstants.GET_CLASSLOADER_PERMISSION);
1508 }
1509 return;
1510 }
1511
1512 // Step 2a:
1513 if (m.isPublic()) return;
1514 if (!fullPowerLookup) {
1515 smgr.checkPermission(SecurityConstants.CHECK_MEMBER_ACCESS_PERMISSION);
1516 }
1517
1518 // Step 3:
1519 Class<?> defc = m.getDeclaringClass();
1520 if (!fullPowerLookup && defc != refc) {
1521 ReflectUtil.checkPackageAccess(defc);
1522 }
1523 }
1524
1525 void checkMethod(byte refKind, Class<?> refc, MemberName m) throws IllegalAccessException {
1526 boolean wantStatic = (refKind == REF_invokeStatic);
1527 String message;
1528 if (m.isConstructor())
1529 message = "expected a method, not a constructor";
1530 else if (!m.isMethod())
1531 message = "expected a method";
1532 else if (wantStatic != m.isStatic())
1605 (defc == refc ||
1606 Modifier.isPublic(refc.getModifiers())));
1607 if (!classOK && (allowedModes & PACKAGE) != 0) {
1608 classOK = (VerifyAccess.isClassAccessible(defc, lookupClass(), ALL_MODES) &&
1609 (defc == refc ||
1610 VerifyAccess.isClassAccessible(refc, lookupClass(), ALL_MODES)));
1611 }
1612 if (!classOK)
1613 return "class is not public";
1614 if (Modifier.isPublic(mods))
1615 return "access to public member failed"; // (how?)
1616 if (Modifier.isPrivate(mods))
1617 return "member is private";
1618 if (Modifier.isProtected(mods))
1619 return "member is protected";
1620 return "member is private to package";
1621 }
1622
1623 private static final boolean ALLOW_NESTMATE_ACCESS = false;
1624
1625 private void checkSpecialCaller(Class<?> specialCaller, Class<?> refc) throws IllegalAccessException {
1626 int allowedModes = this.allowedModes;
1627 if (allowedModes == TRUSTED) return;
1628 if (!hasPrivateAccess()
1629 || (specialCaller != lookupClass()
1630 // ensure non-abstract methods in superinterfaces can be special-invoked
1631 && !(refc != null && refc.isInterface() && refc.isAssignableFrom(specialCaller))
1632 && !(ALLOW_NESTMATE_ACCESS &&
1633 VerifyAccess.isSamePackageMember(specialCaller, lookupClass()))))
1634 throw new MemberName(specialCaller).
1635 makeAccessException("no private access for invokespecial", this);
1636 }
1637
1638 private boolean restrictProtectedReceiver(MemberName method) {
1639 // The accessing class only has the right to use a protected member
1640 // on itself or a subclass. Enforce that restriction, from JVMS 5.4.4, etc.
1641 if (!method.isProtected() || method.isStatic()
1642 || allowedModes == TRUSTED
1643 || method.getDeclaringClass() == lookupClass()
1644 || VerifyAccess.isSamePackage(method.getDeclaringClass(), lookupClass())
1645 || (ALLOW_NESTMATE_ACCESS &&
1646 VerifyAccess.isSamePackageMember(method.getDeclaringClass(), lookupClass())))
1647 return false;
1648 return true;
1649 }
1650 private MethodHandle restrictReceiver(MemberName method, DirectMethodHandle mh, Class<?> caller) throws IllegalAccessException {
1651 assert(!method.isStatic());
1938 * <blockquote><pre>{@code
1939 MethodHandle invoker = MethodHandles.invoker(type);
1940 int spreadArgCount = type.parameterCount() - leadingArgCount;
1941 invoker = invoker.asSpreader(Object[].class, spreadArgCount);
1942 return invoker;
1943 * }</pre></blockquote>
1944 * This method throws no reflective or security exceptions.
1945 * @param type the desired target type
1946 * @param leadingArgCount number of fixed arguments, to be passed unchanged to the target
1947 * @return a method handle suitable for invoking any method handle of the given type
1948 * @throws NullPointerException if {@code type} is null
1949 * @throws IllegalArgumentException if {@code leadingArgCount} is not in
1950 * the range from 0 to {@code type.parameterCount()} inclusive,
1951 * or if the resulting method handle's type would have
1952 * <a href="MethodHandle.html#maxarity">too many parameters</a>
1953 */
1954 public static
1955 MethodHandle spreadInvoker(MethodType type, int leadingArgCount) {
1956 if (leadingArgCount < 0 || leadingArgCount > type.parameterCount())
1957 throw newIllegalArgumentException("bad argument count", leadingArgCount);
1958 type = type.asSpreaderType(Object[].class, leadingArgCount, type.parameterCount() - leadingArgCount);
1959 return type.invokers().spreadInvoker(leadingArgCount);
1960 }
1961
1962 /**
1963 * Produces a special <em>invoker method handle</em> which can be used to
1964 * invoke any method handle of the given type, as if by {@link MethodHandle#invokeExact invokeExact}.
1965 * The resulting invoker will have a type which is
1966 * exactly equal to the desired type, except that it will accept
1967 * an additional leading argument of type {@code MethodHandle}.
1968 * <p>
1969 * This method is equivalent to the following code (though it may be more efficient):
1970 * {@code publicLookup().findVirtual(MethodHandle.class, "invokeExact", type)}
1971 *
1972 * <p style="font-size:smaller;">
1973 * <em>Discussion:</em>
1974 * Invoker method handles can be useful when working with variable method handles
1975 * of unknown types.
1976 * For example, to emulate an {@code invokeExact} call to a variable method
1977 * handle {@code M}, extract its type {@code T},
1978 * look up the invoker method {@code X} for {@code T},
2974 * T target2(A[N]..., B...);
2975 * void combiner2(A...);
2976 * T adapter2(A... a, B... b) {
2977 * combiner2(a...);
2978 * return target2(a..., b...);
2979 * }
2980 * }</pre></blockquote>
2981 * @param target the method handle to invoke after arguments are combined
2982 * @param combiner method handle to call initially on the incoming arguments
2983 * @return method handle which incorporates the specified argument folding logic
2984 * @throws NullPointerException if either argument is null
2985 * @throws IllegalArgumentException if {@code combiner}'s return type
2986 * is non-void and not the same as the first argument type of
2987 * the target, or if the initial {@code N} argument types
2988 * of the target
2989 * (skipping one matching the {@code combiner}'s return type)
2990 * are not identical with the argument types of {@code combiner}
2991 */
2992 public static
2993 MethodHandle foldArguments(MethodHandle target, MethodHandle combiner) {
2994 return foldArguments(target, 0, combiner);
2995 }
2996
2997 private static Class<?> foldArgumentChecks(int foldPos, MethodType targetType, MethodType combinerType) {
2998 int foldArgs = combinerType.parameterCount();
2999 Class<?> rtype = combinerType.returnType();
3000 int foldVals = rtype == void.class ? 0 : 1;
3001 int afterInsertPos = foldPos + foldVals;
3002 boolean ok = (targetType.parameterCount() >= afterInsertPos + foldArgs);
3003 if (ok && !(combinerType.parameterList()
3004 .equals(targetType.parameterList().subList(afterInsertPos,
3005 afterInsertPos + foldArgs))))
3006 ok = false;
3007 if (ok && foldVals != 0 && combinerType.returnType() != targetType.parameterType(foldPos))
3008 ok = false;
3009 if (!ok)
3010 throw misMatchedTypes("target and combiner types", targetType, combinerType);
3011 return rtype;
3012 }
3013
3014 /**
3015 * Makes a method handle which adapts a target method handle,
3016 * by guarding it with a test, a boolean-valued method handle.
3017 * If the guard fails, a fallback handle is called instead.
3018 * All three method handles must have the same corresponding
3019 * argument and return types, except that the return type
3020 * of the test must be boolean, and the test is allowed
3021 * to have fewer arguments than the other two method handles.
3022 * <p> Here is pseudocode for the resulting adapter:
3023 * <blockquote><pre>{@code
3024 * boolean test(A...);
3025 * T target(A...,B...);
3026 * T fallback(A...,B...);
3027 * T adapter(A... a,B... b) {
3049 MethodHandle fallback) {
3050 MethodType gtype = test.type();
3051 MethodType ttype = target.type();
3052 MethodType ftype = fallback.type();
3053 if (!ttype.equals(ftype))
3054 throw misMatchedTypes("target and fallback types", ttype, ftype);
3055 if (gtype.returnType() != boolean.class)
3056 throw newIllegalArgumentException("guard type is not a predicate "+gtype);
3057 List<Class<?>> targs = ttype.parameterList();
3058 List<Class<?>> gargs = gtype.parameterList();
3059 if (!targs.equals(gargs)) {
3060 int gpc = gargs.size(), tpc = targs.size();
3061 if (gpc >= tpc || !targs.subList(0, gpc).equals(gargs))
3062 throw misMatchedTypes("target and test types", ttype, gtype);
3063 test = dropArguments(test, gpc, targs.subList(gpc, tpc));
3064 gtype = test.type();
3065 }
3066 return MethodHandleImpl.makeGuardWithTest(test, target, fallback);
3067 }
3068
3069 static <T> RuntimeException misMatchedTypes(String what, T t1, T t2) {
3070 return newIllegalArgumentException(what + " must match: " + t1 + " != " + t2);
3071 }
3072
3073 /**
3074 * Makes a method handle which adapts a target method handle,
3075 * by running it inside an exception handler.
3076 * If the target returns normally, the adapter returns that value.
3077 * If an exception matching the specified type is thrown, the fallback
3078 * handle is called instead on the exception, plus the original arguments.
3079 * <p>
3080 * The target and handler must have the same corresponding
3081 * argument and return types, except that handler may omit trailing arguments
3082 * (similarly to the predicate in {@link #guardWithTest guardWithTest}).
3083 * Also, the handler must have an extra leading parameter of {@code exType} or a supertype.
3084 * <p> Here is pseudocode for the resulting adapter:
3085 * <blockquote><pre>{@code
3086 * T target(A..., B...);
3087 * T handler(ExType, A...);
3088 * T adapter(A... a, B... b) {
3089 * try {
3095 * }</pre></blockquote>
3096 * Note that the saved arguments ({@code a...} in the pseudocode) cannot
3097 * be modified by execution of the target, and so are passed unchanged
3098 * from the caller to the handler, if the handler is invoked.
3099 * <p>
3100 * The target and handler must return the same type, even if the handler
3101 * always throws. (This might happen, for instance, because the handler
3102 * is simulating a {@code finally} clause).
3103 * To create such a throwing handler, compose the handler creation logic
3104 * with {@link #throwException throwException},
3105 * in order to create a method handle of the correct return type.
3106 * @param target method handle to call
3107 * @param exType the type of exception which the handler will catch
3108 * @param handler method handle to call if a matching exception is thrown
3109 * @return method handle which incorporates the specified try/catch logic
3110 * @throws NullPointerException if any argument is null
3111 * @throws IllegalArgumentException if {@code handler} does not accept
3112 * the given exception type, or if the method handle types do
3113 * not match in their return types and their
3114 * corresponding parameters
3115 * @see MethodHandles#tryFinally(MethodHandle, MethodHandle)
3116 */
3117 public static
3118 MethodHandle catchException(MethodHandle target,
3119 Class<? extends Throwable> exType,
3120 MethodHandle handler) {
3121 MethodType ttype = target.type();
3122 MethodType htype = handler.type();
3123 if (htype.parameterCount() < 1 ||
3124 !htype.parameterType(0).isAssignableFrom(exType))
3125 throw newIllegalArgumentException("handler does not accept exception type "+exType);
3126 if (htype.returnType() != ttype.returnType())
3127 throw misMatchedTypes("target and handler return types", ttype, htype);
3128 List<Class<?>> targs = ttype.parameterList();
3129 List<Class<?>> hargs = htype.parameterList();
3130 hargs = hargs.subList(1, hargs.size()); // omit leading parameter from handler
3131 if (!targs.equals(hargs)) {
3132 int hpc = hargs.size(), tpc = targs.size();
3133 if (hpc >= tpc || !targs.subList(0, hpc).equals(hargs))
3134 throw misMatchedTypes("target and handler types", ttype, htype);
3135 handler = dropArguments(handler, 1+hpc, targs.subList(hpc, tpc));
3139 }
3140
3141 /**
3142 * Produces a method handle which will throw exceptions of the given {@code exType}.
3143 * The method handle will accept a single argument of {@code exType},
3144 * and immediately throw it as an exception.
3145 * The method type will nominally specify a return of {@code returnType}.
3146 * The return type may be anything convenient: It doesn't matter to the
3147 * method handle's behavior, since it will never return normally.
3148 * @param returnType the return type of the desired method handle
3149 * @param exType the parameter type of the desired method handle
3150 * @return method handle which can throw the given exceptions
3151 * @throws NullPointerException if either argument is null
3152 */
3153 public static
3154 MethodHandle throwException(Class<?> returnType, Class<? extends Throwable> exType) {
3155 if (!Throwable.class.isAssignableFrom(exType))
3156 throw new ClassCastException(exType.getName());
3157 return MethodHandleImpl.throwException(MethodType.methodType(returnType, exType));
3158 }
3159
3160 /**
3161 * Constructs a method handle representing a loop with several loop variables that are updated and checked upon each
3162 * iteration. Upon termination of the loop due to one of the predicates, a corresponding finalizer is run and
3163 * delivers the loop's result, which is the return value of the resulting handle.
3164 * <p>
3165 * Intuitively, every loop is formed by one or more "clauses", each specifying a local iteration value and/or a loop
3166 * exit. Each iteration of the loop executes each clause in order. A clause can optionally update its iteration
3167 * variable; it can also optionally perform a test and conditional loop exit. In order to express this logic in
3168 * terms of method handles, each clause will determine four actions:<ul>
3169 * <li>Before the loop executes, the initialization of an iteration variable or loop invariant local.
3170 * <li>When a clause executes, an update step for the iteration variable.
3171 * <li>When a clause executes, a predicate execution to test for loop exit.
3172 * <li>If a clause causes a loop exit, a finalizer execution to compute the loop's return value.
3173 * </ul>
3174 * <p>
3175 * Some of these clause parts may be omitted according to certain rules, and useful default behavior is provided in
3176 * this case. See below for a detailed description.
3177 * <p>
3178 * Each clause function, with the exception of clause initializers, is able to observe the entire loop state,
3179 * because it will be passed <em>all</em> current iteration variable values, as well as all incoming loop
3180 * parameters. Most clause functions will not need all of this information, but they will be formally connected as
3181 * if by {@link #dropArguments}.
3182 * <p>
3183 * Given a set of clauses, there is a number of checks and adjustments performed to connect all the parts of the
3184 * loop. They are spelled out in detail in the steps below. In these steps, every occurrence of the word "must"
3185 * corresponds to a place where {@link IllegalArgumentException} may be thrown if the required constraint is not met
3186 * by the inputs to the loop combinator. The term "effectively identical", applied to parameter type lists, means
3187 * that they must be identical, or else one list must be a proper prefix of the other.
3188 * <p>
3189 * <em>Step 0: Determine clause structure.</em><ol type="a">
3190 * <li>The clause array (of type {@code MethodHandle[][]} must be non-{@code null} and contain at least one element.
3191 * <li>The clause array may not contain {@code null}s or sub-arrays longer than four elements.
3192 * <li>Clauses shorter than four elements are treated as if they were padded by {@code null} elements to length
3193 * four. Padding takes place by appending elements to the array.
3194 * <li>Clauses with all {@code null}s are disregarded.
3195 * <li>Each clause is treated as a four-tuple of functions, called "init", "step", "pred", and "fini".
3196 * </ol>
3197 * <p>
3198 * <em>Step 1A: Determine iteration variables.</em><ol type="a">
3199 * <li>Examine init and step function return types, pairwise, to determine each clause's iteration variable type.
3200 * <li>If both functions are omitted, use {@code void}; else if one is omitted, use the other's return type; else
3201 * use the common return type (they must be identical).
3202 * <li>Form the list of return types (in clause order), omitting all occurrences of {@code void}.
3203 * <li>This list of types is called the "common prefix".
3204 * </ol>
3205 * <p>
3206 * <em>Step 1B: Determine loop parameters.</em><ol type="a">
3207 * <li>Examine init function parameter lists.
3208 * <li>Omitted init functions are deemed to have {@code null} parameter lists.
3209 * <li>All init function parameter lists must be effectively identical.
3210 * <li>The longest parameter list (which is necessarily unique) is called the "common suffix".
3211 * </ol>
3212 * <p>
3213 * <em>Step 1C: Determine loop return type.</em><ol type="a">
3214 * <li>Examine fini function return types, disregarding omitted fini functions.
3215 * <li>If there are no fini functions, use {@code void} as the loop return type.
3216 * <li>Otherwise, use the common return type of the fini functions; they must all be identical.
3217 * </ol>
3218 * <p>
3219 * <em>Step 1D: Check other types.</em><ol type="a">
3220 * <li>There must be at least one non-omitted pred function.
3221 * <li>Every non-omitted pred function must have a {@code boolean} return type.
3222 * </ol>
3223 * <p>
3224 * (Implementation Note: Steps 1A, 1B, 1C, 1D are logically independent of each other, and may be performed in any
3225 * order.)
3226 * <p>
3227 * <em>Step 2: Determine parameter lists.</em><ol type="a">
3228 * <li>The parameter list for the resulting loop handle will be the "common suffix".
3229 * <li>The parameter list for init functions will be adjusted to the "common suffix". (Note that their parameter
3230 * lists are already effectively identical to the common suffix.)
3231 * <li>The parameter list for non-init (step, pred, and fini) functions will be adjusted to the common prefix
3232 * followed by the common suffix, called the "common parameter sequence".
3233 * <li>Every non-init, non-omitted function parameter list must be effectively identical to the common parameter
3234 * sequence.
3235 * </ol>
3236 * <p>
3237 * <em>Step 3: Fill in omitted functions.</em><ol type="a">
3238 * <li>If an init function is omitted, use a {@linkplain #constant constant function} of the appropriate
3239 * {@code null}/zero/{@code false}/{@code void} type. (For this purpose, a constant {@code void} is simply a
3240 * function which does nothing and returns {@code void}; it can be obtained from another constant function by
3241 * {@linkplain MethodHandle#asType type conversion}.)
3242 * <li>If a step function is omitted, use an {@linkplain #identity identity function} of the clause's iteration
3243 * variable type; insert dropped argument parameters before the identity function parameter for the non-{@code void}
3244 * iteration variables of preceding clauses. (This will turn the loop variable into a local loop invariant.)
3245 * <li>If a pred function is omitted, the corresponding fini function must also be omitted.
3246 * <li>If a pred function is omitted, use a constant {@code true} function. (This will keep the loop going, as far
3247 * as this clause is concerned.)
3248 * <li>If a fini function is omitted, use a constant {@code null}/zero/{@code false}/{@code void} function of the
3249 * loop return type.
3250 * </ol>
3251 * <p>
3252 * <em>Step 4: Fill in missing parameter types.</em><ol type="a">
3253 * <li>At this point, every init function parameter list is effectively identical to the common suffix, but some
3254 * lists may be shorter. For every init function with a short parameter list, pad out the end of the list by
3255 * {@linkplain #dropArguments dropping arguments}.
3256 * <li>At this point, every non-init function parameter list is effectively identical to the common parameter
3257 * sequence, but some lists may be shorter. For every non-init function with a short parameter list, pad out the end
3258 * of the list by {@linkplain #dropArguments dropping arguments}.
3259 * </ol>
3260 * <p>
3261 * <em>Final observations.</em><ol type="a">
3262 * <li>After these steps, all clauses have been adjusted by supplying omitted functions and arguments.
3263 * <li>All init functions have a common parameter type list, which the final loop handle will also have.
3264 * <li>All fini functions have a common return type, which the final loop handle will also have.
3265 * <li>All non-init functions have a common parameter type list, which is the common parameter sequence, of
3266 * (non-{@code void}) iteration variables followed by loop parameters.
3267 * <li>Each pair of init and step functions agrees in their return types.
3268 * <li>Each non-init function will be able to observe the current values of all iteration variables, by means of the
3269 * common prefix.
3270 * </ol>
3271 * <p>
3272 * <em>Loop execution.</em><ol type="a">
3273 * <li>When the loop is called, the loop input values are saved in locals, to be passed (as the common suffix) to
3274 * every clause function. These locals are loop invariant.
3275 * <li>Each init function is executed in clause order (passing the common suffix) and the non-{@code void} values
3276 * are saved (as the common prefix) into locals. These locals are loop varying (unless their steps are identity
3277 * functions, as noted above).
3278 * <li>All function executions (except init functions) will be passed the common parameter sequence, consisting of
3279 * the non-{@code void} iteration values (in clause order) and then the loop inputs (in argument order).
3280 * <li>The step and pred functions are then executed, in clause order (step before pred), until a pred function
3281 * returns {@code false}.
3282 * <li>The non-{@code void} result from a step function call is used to update the corresponding loop variable. The
3283 * updated value is immediately visible to all subsequent function calls.
3284 * <li>If a pred function returns {@code false}, the corresponding fini function is called, and the resulting value
3285 * is returned from the loop as a whole.
3286 * </ol>
3287 * <p>
3288 * Here is pseudocode for the resulting loop handle:
3289 * <blockquote><pre>{@code
3290 * V... init...(A...);
3291 * boolean pred...(V..., A...);
3292 * V... step...(V..., A...);
3293 * R fini...(V..., A...);
3294 * R loop(A... a) {
3295 * V... v... = init...(a...);
3296 * for (;;) {
3297 * for ((v, p, s, f) in (v..., pred..., step..., fini...)) {
3298 * v = s(v..., a...);
3299 * if (!p(v..., a...)) {
3300 * return f(v..., a...);
3301 * }
3302 * }
3303 * }
3304 * }
3305 * }</pre></blockquote>
3306 * <p>
3307 * @apiNote Example:
3308 * <blockquote><pre>{@code
3309 * // iterative implementation of the factorial function as a loop handle
3310 * static int one(int k) { return 1; }
3311 * int inc(int i, int acc, int k) { return i + 1; }
3312 * int mult(int i, int acc, int k) { return i * acc; }
3313 * boolean pred(int i, int acc, int k) { return i < k; }
3314 * int fin(int i, int acc, int k) { return acc; }
3315 * // assume MH_one, MH_inc, MH_mult, MH_pred, and MH_fin are handles to the above methods
3316 * // null initializer for counter, should initialize to 0
3317 * MethodHandle[] counterClause = new MethodHandle[]{null, MH_inc};
3318 * MethodHandle[] accumulatorClause = new MethodHandle[]{MH_one, MH_mult, MH_pred, MH_fin};
3319 * MethodHandle loop = MethodHandles.loop(counterClause, accumulatorClause);
3320 * assertEquals(120, loop.invoke(5));
3321 * }</pre></blockquote>
3322 *
3323 * @param clauses an array of arrays (4-tuples) of {@link MethodHandle}s adhering to the rules described above.
3324 *
3325 * @return a method handle embodying the looping behavior as defined by the arguments.
3326 *
3327 * @throws IllegalArgumentException in case any of the constraints described above is violated.
3328 *
3329 * @see MethodHandles#whileLoop(MethodHandle, MethodHandle, MethodHandle)
3330 * @see MethodHandles#doWhileLoop(MethodHandle, MethodHandle, MethodHandle)
3331 * @see MethodHandles#countedLoop(MethodHandle, MethodHandle, MethodHandle)
3332 * @see MethodHandles#iteratedLoop(MethodHandle, MethodHandle, MethodHandle)
3333 * @since 9
3334 */
3335 public static MethodHandle loop(MethodHandle[]... clauses) {
3336 // Step 0: determine clause structure.
3337 checkLoop0(clauses);
3338
3339 List<MethodHandle> init = new ArrayList<>();
3340 List<MethodHandle> step = new ArrayList<>();
3341 List<MethodHandle> pred = new ArrayList<>();
3342 List<MethodHandle> fini = new ArrayList<>();
3343
3344 Stream.of(clauses).filter(c -> Stream.of(c).anyMatch(Objects::nonNull)).forEach(clause -> {
3345 init.add(clause[0]); // all clauses have at least length 1
3346 step.add(clause.length <= 1 ? null : clause[1]);
3347 pred.add(clause.length <= 2 ? null : clause[2]);
3348 fini.add(clause.length <= 3 ? null : clause[3]);
3349 });
3350
3351 assert Stream.of(init, step, pred, fini).map(List::size).distinct().count() == 1;
3352 final int nclauses = init.size();
3353
3354 // Step 1A: determine iteration variables.
3355 final List<Class<?>> iterationVariableTypes = new ArrayList<>();
3356 for (int i = 0; i < nclauses; ++i) {
3357 MethodHandle in = init.get(i);
3358 MethodHandle st = step.get(i);
3359 if (in == null && st == null) {
3360 iterationVariableTypes.add(void.class);
3361 } else if (in != null && st != null) {
3362 checkLoop1a(i, in, st);
3363 iterationVariableTypes.add(in.type().returnType());
3364 } else {
3365 iterationVariableTypes.add(in == null ? st.type().returnType() : in.type().returnType());
3366 }
3367 }
3368 final List<Class<?>> commonPrefix = iterationVariableTypes.stream().filter(t -> t != void.class).
3369 collect(Collectors.toList());
3370
3371 // Step 1B: determine loop parameters.
3372 final List<Class<?>> empty = new ArrayList<>();
3373 final List<Class<?>> commonSuffix = init.stream().filter(Objects::nonNull).map(MethodHandle::type).
3374 map(MethodType::parameterList).reduce((p, q) -> p.size() >= q.size() ? p : q).orElse(empty);
3375 checkLoop1b(init, commonSuffix);
3376
3377 // Step 1C: determine loop return type.
3378 // Step 1D: check other types.
3379 final Class<?> loopReturnType = fini.stream().filter(Objects::nonNull).map(MethodHandle::type).
3380 map(MethodType::returnType).findFirst().orElse(void.class);
3381 checkLoop1cd(pred, fini, loopReturnType);
3382
3383 // Step 2: determine parameter lists.
3384 final List<Class<?>> commonParameterSequence = new ArrayList<>(commonPrefix);
3385 commonParameterSequence.addAll(commonSuffix);
3386 checkLoop2(step, pred, fini, commonParameterSequence);
3387
3388 // Step 3: fill in omitted functions.
3389 for (int i = 0; i < nclauses; ++i) {
3390 Class<?> t = iterationVariableTypes.get(i);
3391 if (init.get(i) == null) {
3392 init.set(i, zeroHandle(t));
3393 }
3394 if (step.get(i) == null) {
3395 step.set(i, dropArguments(t == void.class ? zeroHandle(t) : identity(t), 0, commonPrefix.subList(0, i)));
3396 }
3397 if (pred.get(i) == null) {
3398 pred.set(i, constant(boolean.class, true));
3399 }
3400 if (fini.get(i) == null) {
3401 fini.set(i, zeroHandle(t));
3402 }
3403 }
3404
3405 // Step 4: fill in missing parameter types.
3406 List<MethodHandle> finit = fillParameterTypes(init, commonSuffix);
3407 List<MethodHandle> fstep = fillParameterTypes(step, commonParameterSequence);
3408 List<MethodHandle> fpred = fillParameterTypes(pred, commonParameterSequence);
3409 List<MethodHandle> ffini = fillParameterTypes(fini, commonParameterSequence);
3410
3411 assert finit.stream().map(MethodHandle::type).map(MethodType::parameterList).
3412 allMatch(pl -> pl.equals(commonSuffix));
3413 assert Stream.of(fstep, fpred, ffini).flatMap(List::stream).map(MethodHandle::type).map(MethodType::parameterList).
3414 allMatch(pl -> pl.equals(commonParameterSequence));
3415
3416 return MethodHandleImpl.makeLoop(loopReturnType, commonSuffix, commonPrefix, finit, fstep, fpred, ffini);
3417 }
3418
3419 private static List<MethodHandle> fillParameterTypes(List<MethodHandle> hs, final List<Class<?>> targetParams) {
3420 return hs.stream().map(h -> {
3421 int pc = h.type().parameterCount();
3422 int tpsize = targetParams.size();
3423 return pc < tpsize ? dropArguments(h, pc, targetParams.subList(pc, tpsize)) : h;
3424 }).collect(Collectors.toList());
3425 }
3426
3427 /**
3428 * Constructs a {@code while} loop from an initializer, a body, and a predicate. This is a convenience wrapper for
3429 * the {@linkplain #loop(MethodHandle[][]) generic loop combinator}.
3430 * <p>
3431 * The loop handle's result type is the same as the sole loop variable's, i.e., the result type of {@code init}.
3432 * The parameter type list of {@code init} also determines that of the resulting handle. The {@code pred} handle
3433 * must have an additional leading parameter of the same type as {@code init}'s result, and so must the {@code
3434 * body}. These constraints follow directly from those described for the {@linkplain MethodHandles#loop(MethodHandle[][])
3435 * generic loop combinator}.
3436 * <p>
3437 * Here is pseudocode for the resulting loop handle:
3438 * <blockquote><pre>{@code
3439 * V init(A);
3440 * boolean pred(V, A);
3441 * V body(V, A);
3442 * V whileLoop(A a) {
3443 * V v = init(a);
3444 * while (pred(v, a)) {
3445 * v = body(v, a);
3446 * }
3447 * return v;
3448 * }
3449 * }</pre></blockquote>
3450 * <p>
3451 * @apiNote Example:
3452 * <blockquote><pre>{@code
3453 * // implement the zip function for lists as a loop handle
3454 * List<String> initZip(Iterator<String> a, Iterator<String> b) { return new ArrayList<>(); }
3455 * boolean zipPred(List<String> zip, Iterator<String> a, Iterator<String> b) { return a.hasNext() && b.hasNext(); }
3456 * List<String> zipStep(List<String> zip, Iterator<String> a, Iterator<String> b) {
3457 * zip.add(a.next());
3458 * zip.add(b.next());
3459 * return zip;
3460 * }
3461 * // assume MH_initZip, MH_zipPred, and MH_zipStep are handles to the above methods
3462 * MethodHandle loop = MethodHandles.doWhileLoop(MH_initZip, MH_zipPred, MH_zipStep);
3463 * List<String> a = Arrays.asList("a", "b", "c", "d");
3464 * List<String> b = Arrays.asList("e", "f", "g", "h");
3465 * List<String> zipped = Arrays.asList("a", "e", "b", "f", "c", "g", "d", "h");
3466 * assertEquals(zipped, (List<String>) loop.invoke(a.iterator(), b.iterator()));
3467 * }</pre></blockquote>
3468 *
3469 * <p>
3470 * The implementation of this method is equivalent to:
3471 * <blockquote><pre>{@code
3472 * MethodHandle whileLoop(MethodHandle init, MethodHandle pred, MethodHandle body) {
3473 * MethodHandle[]
3474 * checkExit = {null, null, pred, identity(init.type().returnType())},
3475 * varBody = {init, body};
3476 * return loop(checkExit, varBody);
3477 * }
3478 * }</pre></blockquote>
3479 *
3480 * @param init initializer: it should provide the initial value of the loop variable. This controls the loop's
3481 * result type. Passing {@code null} or a {@code void} init function will make the loop's result type
3482 * {@code void}.
3483 * @param pred condition for the loop, which may not be {@code null}.
3484 * @param body body of the loop, which may not be {@code null}.
3485 *
3486 * @return the value of the loop variable as the loop terminates.
3487 * @throws IllegalArgumentException if any argument has a type inconsistent with the loop structure
3488 *
3489 * @see MethodHandles#loop(MethodHandle[][])
3490 * @since 9
3491 */
3492 public static MethodHandle whileLoop(MethodHandle init, MethodHandle pred, MethodHandle body) {
3493 MethodHandle fin = init == null ? zeroHandle(void.class) : identity(init.type().returnType());
3494 MethodHandle[] checkExit = {null, null, pred, fin};
3495 MethodHandle[] varBody = {init, body};
3496 return loop(checkExit, varBody);
3497 }
3498
3499 /**
3500 * Constructs a {@code do-while} loop from an initializer, a body, and a predicate. This is a convenience wrapper
3501 * for the {@linkplain MethodHandles#loop(MethodHandle[][]) generic loop combinator}.
3502 * <p>
3503 * The loop handle's result type is the same as the sole loop variable's, i.e., the result type of {@code init}.
3504 * The parameter type list of {@code init} also determines that of the resulting handle. The {@code pred} handle
3505 * must have an additional leading parameter of the same type as {@code init}'s result, and so must the {@code
3506 * body}. These constraints follow directly from those described for the {@linkplain MethodHandles#loop(MethodHandle[][])
3507 * generic loop combinator}.
3508 * <p>
3509 * Here is pseudocode for the resulting loop handle:
3510 * <blockquote><pre>{@code
3511 * V init(A);
3512 * boolean pred(V, A);
3513 * V body(V, A);
3514 * V doWhileLoop(A a) {
3515 * V v = init(a);
3516 * do {
3517 * v = body(v, a);
3518 * } while (pred(v, a));
3519 * return v;
3520 * }
3521 * }</pre></blockquote>
3522 * <p>
3523 * @apiNote Example:
3524 * <blockquote><pre>{@code
3525 * // int i = 0; while (i < limit) { ++i; } return i; => limit
3526 * int zero(int limit) { return 0; }
3527 * int step(int i, int limit) { return i + 1; }
3528 * boolean pred(int i, int limit) { return i < limit; }
3529 * // assume MH_zero, MH_step, and MH_pred are handles to the above methods
3530 * MethodHandle loop = MethodHandles.doWhileLoop(MH_zero, MH_step, MH_pred);
3531 * assertEquals(23, loop.invoke(23));
3532 * }</pre></blockquote>
3533 *
3534 * * <p>
3535 * The implementation of this method is equivalent to:
3536 * <blockquote><pre>{@code
3537 * MethodHandle doWhileLoop(MethodHandle init, MethodHandle body, MethodHandle pred) {
3538 * MethodHandle[] clause = { init, body, pred, identity(init.type().returnType()) };
3539 * return loop(clause);
3540 * }
3541 * }</pre></blockquote>
3542 *
3543 *
3544 * @param init initializer: it should provide the initial value of the loop variable. This controls the loop's
3545 * result type. Passing {@code null} or a {@code void} init function will make the loop's result type
3546 * {@code void}.
3547 * @param pred condition for the loop, which may not be {@code null}.
3548 * @param body body of the loop, which may not be {@code null}.
3549 *
3550 * @return the value of the loop variable as the loop terminates.
3551 * @throws IllegalArgumentException if any argument has a type inconsistent with the loop structure
3552 *
3553 * @see MethodHandles#loop(MethodHandle[][])
3554 * @since 9
3555 */
3556 public static MethodHandle doWhileLoop(MethodHandle init, MethodHandle body, MethodHandle pred) {
3557 MethodHandle fin = init == null ? zeroHandle(void.class) : identity(init.type().returnType());
3558 MethodHandle[] clause = {init, body, pred, fin};
3559 return loop(clause);
3560 }
3561
3562 /**
3563 * Constructs a loop that runs a given number of iterations. The loop counter is an {@code int} initialized from the
3564 * {@code iterations} handle evaluation result. The counter is passed to the {@code body} function, so that must
3565 * accept an initial {@code int} argument. The result of the loop execution is the final value of the additional
3566 * local state. This is a convenience wrapper for the {@linkplain MethodHandles#loop(MethodHandle[][]) generic loop combinator}.
3567 * <p>
3568 * The result type and parameter type list of {@code init} determine those of the resulting handle. The {@code
3569 * iterations} handle must accept the same parameter types as {@code init} but return an {@code int}. The {@code
3570 * body} handle must accept the same parameter types as well, preceded by an {@code int} parameter for the counter,
3571 * and a parameter of the same type as {@code init}'s result. These constraints follow directly from those described
3572 * for the {@linkplain MethodHandles#loop(MethodHandle[][]) generic loop combinator}.
3573 * <p>
3574 * Here is pseudocode for the resulting loop handle:
3575 * <blockquote><pre>{@code
3576 * int iterations(A);
3577 * V init(A);
3578 * V body(int, V, A);
3579 * V countedLoop(A a) {
3580 * int end = iterations(a);
3581 * V v = init(a);
3582 * for (int i = 0; i < end; ++i) {
3583 * v = body(i, v, a);
3584 * }
3585 * return v;
3586 * }
3587 * }</pre></blockquote>
3588 * <p>
3589 * @apiNote Example:
3590 * <blockquote><pre>{@code
3591 * // String s = "Lambdaman!"; for (int i = 0; i < 13; ++i) { s = "na " + s; } return s;
3592 * // => a variation on a well known theme
3593 * String start(String arg) { return arg; }
3594 * String step(int counter, String v, String arg) { return "na " + v; }
3595 * // assume MH_start and MH_step are handles to the two methods above
3596 * MethodHandle loop = MethodHandles.countedLoop(13, MH_start, MH_step);
3597 * assertEquals("na na na na na na na na na na na na na Lambdaman!", loop.invoke("Lambdaman!"));
3598 * }</pre></blockquote>
3599 *
3600 * <p>
3601 * The implementation of this method is equivalent to:
3602 * <blockquote><pre>{@code
3603 * MethodHandle countedLoop(MethodHandle iterations, MethodHandle init, MethodHandle body) {
3604 * return countedLoop(null, iterations, init, body); // null => constant zero
3605 * }
3606 * }</pre></blockquote>
3607 *
3608 * @param iterations a handle to return the number of iterations this loop should run.
3609 * @param init initializer for additional loop state. This determines the loop's result type.
3610 * Passing {@code null} or a {@code void} init function will make the loop's result type
3611 * {@code void}.
3612 * @param body the body of the loop, which must not be {@code null}.
3613 * It must accept an initial {@code int} parameter (for the counter), and then any
3614 * additional loop-local variable plus loop parameters.
3615 *
3616 * @return a method handle representing the loop.
3617 * @throws IllegalArgumentException if any argument has a type inconsistent with the loop structure
3618 *
3619 * @since 9
3620 */
3621 public static MethodHandle countedLoop(MethodHandle iterations, MethodHandle init, MethodHandle body) {
3622 return countedLoop(null, iterations, init, body);
3623 }
3624
3625 /**
3626 * Constructs a loop that counts over a range of numbers. The loop counter is an {@code int} that will be
3627 * initialized to the {@code int} value returned from the evaluation of the {@code start} handle and run to the
3628 * value returned from {@code end} (exclusively) with a step width of 1. The counter value is passed to the {@code
3629 * body} function in each iteration; it has to accept an initial {@code int} parameter
3630 * for that. The result of the loop execution is the final value of the additional local state
3631 * obtained by running {@code init}.
3632 * This is a
3633 * convenience wrapper for the {@linkplain MethodHandles#loop(MethodHandle[][]) generic loop combinator}.
3634 * <p>
3635 * The constraints for the {@code init} and {@code body} handles are the same as for {@link
3636 * #countedLoop(MethodHandle, MethodHandle, MethodHandle)}. Additionally, the {@code start} and {@code end} handles
3637 * must return an {@code int} and accept the same parameters as {@code init}.
3638 * <p>
3639 * Here is pseudocode for the resulting loop handle:
3640 * <blockquote><pre>{@code
3641 * int start(A);
3642 * int end(A);
3643 * V init(A);
3644 * V body(int, V, A);
3645 * V countedLoop(A a) {
3646 * int s = start(a);
3647 * int e = end(a);
3648 * V v = init(a);
3649 * for (int i = s; i < e; ++i) {
3650 * v = body(i, v, a);
3651 * }
3652 * return v;
3653 * }
3654 * }</pre></blockquote>
3655 *
3656 * <p>
3657 * The implementation of this method is equivalent to:
3658 * <blockquote><pre>{@code
3659 * MethodHandle countedLoop(MethodHandle start, MethodHandle end, MethodHandle init, MethodHandle body) {
3660 * MethodHandle returnVar = dropArguments(identity(init.type().returnType()), 0, int.class, int.class);
3661 * // assume MH_increment and MH_lessThan are handles to x+1 and x<y of type int
3662 * MethodHandle[]
3663 * indexVar = {start, MH_increment}, // i = start; i = i+1
3664 * loopLimit = {end, null, MH_lessThan, returnVar }, // i<end
3665 * bodyClause = {init, dropArguments(body, 1, int.class)}; // v = body(i, v);
3666 * return loop(indexVar, loopLimit, bodyClause);
3667 * }
3668 * }</pre></blockquote>
3669 *
3670 * @param start a handle to return the start value of the loop counter.
3671 * If it is {@code null}, a constant zero is assumed.
3672 * @param end a non-{@code null} handle to return the end value of the loop counter (the loop will run to {@code end-1}).
3673 * @param init initializer for additional loop state. This determines the loop's result type.
3674 * Passing {@code null} or a {@code void} init function will make the loop's result type
3675 * {@code void}.
3676 * @param body the body of the loop, which must not be {@code null}.
3677 * It must accept an initial {@code int} parameter (for the counter), and then any
3678 * additional loop-local variable plus loop parameters.
3679 *
3680 * @return a method handle representing the loop.
3681 * @throws IllegalArgumentException if any argument has a type inconsistent with the loop structure
3682 *
3683 * @since 9
3684 */
3685 public static MethodHandle countedLoop(MethodHandle start, MethodHandle end, MethodHandle init, MethodHandle body) {
3686 MethodHandle returnVar = dropArguments(init == null ? zeroHandle(void.class) : identity(init.type().returnType()),
3687 0, int.class, int.class);
3688 MethodHandle[] indexVar = {start, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopStep)};
3689 MethodHandle[] loopLimit = {end, null, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_countedLoopPred), returnVar};
3690 MethodHandle[] bodyClause = {init, dropArguments(body, 1, int.class)};
3691 return loop(indexVar, loopLimit, bodyClause);
3692 }
3693
3694 /**
3695 * Constructs a loop that ranges over the elements produced by an {@code Iterator<T>}.
3696 * The iterator will be produced by the evaluation of the {@code iterator} handle.
3697 * If this handle is passed as {@code null} the method {@link Iterable#iterator} will be used instead,
3698 * and will be applied to a leading argument of the loop handle.
3699 * Each value produced by the iterator is passed to the {@code body}, which must accept an initial {@code T} parameter.
3700 * The result of the loop execution is the final value of the additional local state
3701 * obtained by running {@code init}.
3702 * <p>
3703 * This is a convenience wrapper for the
3704 * {@linkplain MethodHandles#loop(MethodHandle[][]) generic loop combinator}, and the constraints imposed on the {@code body}
3705 * handle follow directly from those described for the latter.
3706 * <p>
3707 * Here is pseudocode for the resulting loop handle:
3708 * <blockquote><pre>{@code
3709 * Iterator<T> iterator(A); // defaults to Iterable::iterator
3710 * V init(A);
3711 * V body(T,V,A);
3712 * V iteratedLoop(A a) {
3713 * Iterator<T> it = iterator(a);
3714 * V v = init(a);
3715 * for (T t : it) {
3716 * v = body(t, v, a);
3717 * }
3718 * return v;
3719 * }
3720 * }</pre></blockquote>
3721 * <p>
3722 * The type {@code T} may be either a primitive or reference.
3723 * Since type {@code Iterator<T>} is erased in the method handle representation to the raw type
3724 * {@code Iterator}, the {@code iteratedLoop} combinator adjusts the leading argument type for {@code body}
3725 * to {@code Object} as if by the {@link MethodHandle#asType asType} conversion method.
3726 * Therefore, if an iterator of the wrong type appears as the loop is executed,
3727 * runtime exceptions may occur as the result of dynamic conversions performed by {@code asType}.
3728 * <p>
3729 * @apiNote Example:
3730 * <blockquote><pre>{@code
3731 * // reverse a list
3732 * List<String> reverseStep(String e, List<String> r) {
3733 * r.add(0, e);
3734 * return r;
3735 * }
3736 * List<String> newArrayList() { return new ArrayList<>(); }
3737 * // assume MH_reverseStep, MH_newArrayList are handles to the above methods
3738 * MethodHandle loop = MethodHandles.iteratedLoop(null, MH_newArrayList, MH_reverseStep);
3739 * List<String> list = Arrays.asList("a", "b", "c", "d", "e");
3740 * List<String> reversedList = Arrays.asList("e", "d", "c", "b", "a");
3741 * assertEquals(reversedList, (List<String>) loop.invoke(list));
3742 * }</pre></blockquote>
3743 * <p>
3744 * The implementation of this method is equivalent to:
3745 * <blockquote><pre>{@code
3746 * MethodHandle iteratedLoop(MethodHandle iterator, MethodHandle init, MethodHandle body) {
3747 * // assume MH_next and MH_hasNext are handles to methods of Iterator
3748 * Class<?> itype = iterator.type().returnType();
3749 * Class<?> ttype = body.type().parameterType(0);
3750 * MethodHandle returnVar = dropArguments(identity(init.type().returnType()), 0, itype);
3751 * MethodHandle nextVal = MH_next.asType(MH_next.type().changeReturnType(ttype));
3752 * MethodHandle[]
3753 * iterVar = {iterator, null, MH_hasNext, returnVar}, // it = iterator(); while (it.hasNext)
3754 * bodyClause = {init, filterArgument(body, 0, nextVal)}; // v = body(t, v, a);
3755 * return loop(iterVar, bodyClause);
3756 * }
3757 * }</pre></blockquote>
3758 *
3759 * @param iterator a handle to return the iterator to start the loop.
3760 * Passing {@code null} will make the loop call {@link Iterable#iterator()} on the first
3761 * incoming value.
3762 * @param init initializer for additional loop state. This determines the loop's result type.
3763 * Passing {@code null} or a {@code void} init function will make the loop's result type
3764 * {@code void}.
3765 * @param body the body of the loop, which must not be {@code null}.
3766 * It must accept an initial {@code T} parameter (for the iterated values), and then any
3767 * additional loop-local variable plus loop parameters.
3768 *
3769 * @return a method handle embodying the iteration loop functionality.
3770 * @throws IllegalArgumentException if any argument has a type inconsistent with the loop structure
3771 *
3772 * @since 9
3773 */
3774 public static MethodHandle iteratedLoop(MethodHandle iterator, MethodHandle init, MethodHandle body) {
3775 checkIteratedLoop(body);
3776
3777 MethodHandle initit = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_initIterator);
3778 MethodHandle initIterator = iterator == null ?
3779 initit.asType(initit.type().changeParameterType(0, body.type().parameterType(init == null ? 1 : 2))) :
3780 iterator;
3781 Class<?> itype = initIterator.type().returnType();
3782 Class<?> ttype = body.type().parameterType(0);
3783
3784 MethodHandle returnVar =
3785 dropArguments(init == null ? zeroHandle(void.class) : identity(init.type().returnType()), 0, itype);
3786 MethodHandle initnx = MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_iterateNext);
3787 MethodHandle nextVal = initnx.asType(initnx.type().changeReturnType(ttype));
3788
3789 MethodHandle[] iterVar = {initIterator, null, MethodHandleImpl.getConstantHandle(MethodHandleImpl.MH_iteratePred), returnVar};
3790 MethodHandle[] bodyClause = {init, filterArgument(body, 0, nextVal)};
3791
3792 return loop(iterVar, bodyClause);
3793 }
3794
3795 /**
3796 * Makes a method handle that adapts a {@code target} method handle by wrapping it in a {@code try-finally} block.
3797 * Another method handle, {@code cleanup}, represents the functionality of the {@code finally} block. Any exception
3798 * thrown during the execution of the {@code target} handle will be passed to the {@code cleanup} handle. The
3799 * exception will be rethrown, unless {@code cleanup} handle throws an exception first. The
3800 * value returned from the {@code cleanup} handle's execution will be the result of the execution of the
3801 * {@code try-finally} handle.
3802 * <p>
3803 * The {@code cleanup} handle will be passed one or two additional leading arguments.
3804 * The first is the exception thrown during the
3805 * execution of the {@code target} handle, or {@code null} if no exception was thrown.
3806 * The second is the result of the execution of the {@code target} handle, or, if it throws an exception,
3807 * a {@code null}, zero, or {@code false} value of the required type is supplied as a placeholder.
3808 * The second argument is not present if the {@code target} handle has a {@code void} return type.
3809 * (Note that, except for argument type conversions, combinators represent {@code void} values in parameter lists
3810 * by omitting the corresponding paradoxical arguments, not by inserting {@code null} or zero values.)
3811 * <p>
3812 * The {@code target} and {@code cleanup} handles' return types must be the same. Their parameter type lists also
3813 * must be the same, but the {@code cleanup} handle must accept one or two more leading parameters:<ul>
3814 * <li>a {@code Throwable}, which will carry the exception thrown by the {@code target} handle (if any); and
3815 * <li>a parameter of the same type as the return type of both {@code target} and {@code cleanup}, which will carry
3816 * the result from the execution of the {@code target} handle.
3817 * This parameter is not present if the {@code target} returns {@code void}.
3818 * </ul>
3819 * <p>
3820 * The pseudocode for the resulting adapter looks like this:
3821 * <blockquote><pre>{@code
3822 * T target(A..., B...);
3823 * T cleanup(Throwable, T, A...);
3824 * T adapter(A... a, B... b) {
3825 * T result = (zero value for T);
3826 * Throwable throwable = null;
3827 * try {
3828 * result = target(a..., b...);
3829 * } catch (Throwable t) {
3830 * throwable = t;
3831 * throw t;
3832 * } finally {
3833 * result = cleanup(throwable, result, a...);
3834 * }
3835 * return result;
3836 * }
3837 * }</pre></blockquote>
3838 * <p>
3839 * Note that the saved arguments ({@code a...} in the pseudocode) cannot
3840 * be modified by execution of the target, and so are passed unchanged
3841 * from the caller to the cleanup, if it is invoked.
3842 * <p>
3843 * The target and cleanup must return the same type, even if the cleanup
3844 * always throws.
3845 * To create such a throwing cleanup, compose the cleanup logic
3846 * with {@link #throwException throwException},
3847 * in order to create a method handle of the correct return type.
3848 * <p>
3849 * Note that {@code tryFinally} never converts exceptions into normal returns.
3850 * In rare cases where exceptions must be converted in that way, first wrap
3851 * the target with {@link #catchException(MethodHandle, Class, MethodHandle)}
3852 * to capture an outgoing exception, and then wrap with {@code tryFinally}.
3853 *
3854 * @param target the handle whose execution is to be wrapped in a {@code try} block.
3855 * @param cleanup the handle that is invoked in the finally block.
3856 *
3857 * @return a method handle embodying the {@code try-finally} block composed of the two arguments.
3858 * @throws NullPointerException if any argument is null
3859 * @throws IllegalArgumentException if {@code cleanup} does not accept
3860 * the required leading arguments, or if the method handle types do
3861 * not match in their return types and their
3862 * corresponding trailing parameters
3863 *
3864 * @see MethodHandles#catchException(MethodHandle, Class, MethodHandle)
3865 * @since 9
3866 */
3867 public static MethodHandle tryFinally(MethodHandle target, MethodHandle cleanup) {
3868 List<Class<?>> targetParamTypes = target.type().parameterList();
3869 List<Class<?>> cleanupParamTypes = cleanup.type().parameterList();
3870 Class<?> rtype = target.type().returnType();
3871
3872 checkTryFinally(target, cleanup);
3873
3874 // Match parameter lists: if the cleanup has a shorter parameter list than the target, add ignored arguments.
3875 int tpSize = targetParamTypes.size();
3876 int cpPrefixLength = rtype == void.class ? 1 : 2;
3877 int cpSize = cleanupParamTypes.size();
3878 MethodHandle aCleanup = cpSize - cpPrefixLength < tpSize ?
3879 dropArguments(cleanup, cpSize, targetParamTypes.subList(tpSize - (cpSize - cpPrefixLength), tpSize)) :
3880 cleanup;
3881
3882 MethodHandle aTarget = target.asSpreader(Object[].class, target.type().parameterCount());
3883 aCleanup = aCleanup.asSpreader(Object[].class, tpSize);
3884
3885 return MethodHandleImpl.makeTryFinally(aTarget, aCleanup, rtype, targetParamTypes);
3886 }
3887
3888 /**
3889 * Adapts a target method handle by pre-processing some of its arguments, starting at a given position, and then
3890 * calling the target with the result of the pre-processing, inserted into the original sequence of arguments just
3891 * before the folded arguments.
3892 * <p>
3893 * This method is closely related to {@link #foldArguments(MethodHandle, MethodHandle)}, but allows to control the
3894 * position in the parameter list at which folding takes place. The argument controlling this, {@code pos}, is a
3895 * zero-based index. The aforementioned method {@link #foldArguments(MethodHandle, MethodHandle)} assumes position
3896 * 0.
3897 * <p>
3898 * @apiNote Example:
3899 * <blockquote><pre>{@code
3900 import static java.lang.invoke.MethodHandles.*;
3901 import static java.lang.invoke.MethodType.*;
3902 ...
3903 MethodHandle trace = publicLookup().findVirtual(java.io.PrintStream.class,
3904 "println", methodType(void.class, String.class))
3905 .bindTo(System.out);
3906 MethodHandle cat = lookup().findVirtual(String.class,
3907 "concat", methodType(String.class, String.class));
3908 assertEquals("boojum", (String) cat.invokeExact("boo", "jum"));
3909 MethodHandle catTrace = foldArguments(cat, 1, trace);
3910 // also prints "jum":
3911 assertEquals("boojum", (String) catTrace.invokeExact("boo", "jum"));
3912 * }</pre></blockquote>
3913 * <p> Here is pseudocode for the resulting adapter:
3914 * <blockquote><pre>{@code
3915 * // there are N arguments in A...
3916 * T target(Z..., V, A[N]..., B...);
3917 * V combiner(A...);
3918 * T adapter(Z... z, A... a, B... b) {
3919 * V v = combiner(a...);
3920 * return target(z..., v, a..., b...);
3921 * }
3922 * // and if the combiner has a void return:
3923 * T target2(Z..., A[N]..., B...);
3924 * void combiner2(A...);
3925 * T adapter2(Z... z, A... a, B... b) {
3926 * combiner2(a...);
3927 * return target2(z..., a..., b...);
3928 * }
3929 * }</pre></blockquote>
3930 *
3931 * @param target the method handle to invoke after arguments are combined
3932 * @param pos the position at which to start folding and at which to insert the folding result; if this is {@code
3933 * 0}, the effect is the same as for {@link #foldArguments(MethodHandle, MethodHandle)}.
3934 * @param combiner method handle to call initially on the incoming arguments
3935 * @return method handle which incorporates the specified argument folding logic
3936 * @throws NullPointerException if either argument is null
3937 * @throws IllegalArgumentException if {@code combiner}'s return type
3938 * is non-void and not the same as the argument type at position {@code pos} of
3939 * the target signature, or if the {@code N} argument types at position {@code pos}
3940 * of the target signature
3941 * (skipping one matching the {@code combiner}'s return type)
3942 * are not identical with the argument types of {@code combiner}
3943 *
3944 * @see #foldArguments(MethodHandle, MethodHandle)
3945 * @since 9
3946 */
3947 public static MethodHandle foldArguments(MethodHandle target, int pos, MethodHandle combiner) {
3948 MethodType targetType = target.type();
3949 MethodType combinerType = combiner.type();
3950 Class<?> rtype = foldArgumentChecks(pos, targetType, combinerType);
3951 BoundMethodHandle result = target.rebind();
3952 boolean dropResult = rtype == void.class;
3953 LambdaForm lform = result.editor().foldArgumentsForm(1 + pos, dropResult, combinerType.basicType());
3954 MethodType newType = targetType;
3955 if (!dropResult) {
3956 newType = newType.dropParameterTypes(pos, pos + 1);
3957 }
3958 result = result.copyWithExtendL(newType, lform, combiner);
3959 return result;
3960 }
3961
3962 /**
3963 * Wrap creation of a proper zero handle for a given type.
3964 *
3965 * @param type the type.
3966 *
3967 * @return a zero value for the given type.
3968 */
3969 static MethodHandle zeroHandle(Class<?> type) {
3970 return type.isPrimitive() ? zero(Wrapper.forPrimitiveType(type), type) : zero(Wrapper.OBJECT, type);
3971 }
3972
3973 private static void checkLoop0(MethodHandle[][] clauses) {
3974 if (clauses == null || clauses.length == 0) {
3975 throw newIllegalArgumentException("null or no clauses passed");
3976 }
3977 if (Stream.of(clauses).anyMatch(Objects::isNull)) {
3978 throw newIllegalArgumentException("null clauses are not allowed");
3979 }
3980 if (Stream.of(clauses).anyMatch(c -> c.length > 4)) {
3981 throw newIllegalArgumentException("All loop clauses must be represented as MethodHandle arrays with at most 4 elements.");
3982 }
3983 }
3984
3985 private static void checkLoop1a(int i, MethodHandle in, MethodHandle st) {
3986 if (in.type().returnType() != st.type().returnType()) {
3987 throw misMatchedTypes("clause " + i + ": init and step return types", in.type().returnType(),
3988 st.type().returnType());
3989 }
3990 }
3991
3992 private static void checkLoop1b(List<MethodHandle> init, List<Class<?>> commonSuffix) {
3993 if (init.stream().filter(Objects::nonNull).map(MethodHandle::type).map(MethodType::parameterList).
3994 anyMatch(pl -> !pl.equals(commonSuffix.subList(0, pl.size())))) {
3995 throw newIllegalArgumentException("found non-effectively identical init parameter type lists: " + init +
3996 " (common suffix: " + commonSuffix + ")");
3997 }
3998 }
3999
4000 private static void checkLoop1cd(List<MethodHandle> pred, List<MethodHandle> fini, Class<?> loopReturnType) {
4001 if (fini.stream().filter(Objects::nonNull).map(MethodHandle::type).map(MethodType::returnType).
4002 anyMatch(t -> t != loopReturnType)) {
4003 throw newIllegalArgumentException("found non-identical finalizer return types: " + fini + " (return type: " +
4004 loopReturnType + ")");
4005 }
4006
4007 if (!pred.stream().filter(Objects::nonNull).findFirst().isPresent()) {
4008 throw newIllegalArgumentException("no predicate found", pred);
4009 }
4010 if (pred.stream().filter(Objects::nonNull).map(MethodHandle::type).map(MethodType::returnType).
4011 anyMatch(t -> t != boolean.class)) {
4012 throw newIllegalArgumentException("predicates must have boolean return type", pred);
4013 }
4014 }
4015
4016 private static void checkLoop2(List<MethodHandle> step, List<MethodHandle> pred, List<MethodHandle> fini, List<Class<?>> commonParameterSequence) {
4017 if (Stream.of(step, pred, fini).flatMap(List::stream).filter(Objects::nonNull).map(MethodHandle::type).
4018 map(MethodType::parameterList).anyMatch(pl -> !pl.equals(commonParameterSequence.subList(0, pl.size())))) {
4019 throw newIllegalArgumentException("found non-effectively identical parameter type lists:\nstep: " + step +
4020 "\npred: " + pred + "\nfini: " + fini + " (common parameter sequence: " + commonParameterSequence + ")");
4021 }
4022 }
4023
4024 private static void checkIteratedLoop(MethodHandle body) {
4025 if (null == body) {
4026 throw newIllegalArgumentException("iterated loop body must not be null");
4027 }
4028 }
4029
4030 private static void checkTryFinally(MethodHandle target, MethodHandle cleanup) {
4031 Class<?> rtype = target.type().returnType();
4032 if (rtype != cleanup.type().returnType()) {
4033 throw misMatchedTypes("target and return types", cleanup.type().returnType(), rtype);
4034 }
4035 List<Class<?>> cleanupParamTypes = cleanup.type().parameterList();
4036 if (!Throwable.class.isAssignableFrom(cleanupParamTypes.get(0))) {
4037 throw misMatchedTypes("cleanup first argument and Throwable", cleanup.type(), Throwable.class);
4038 }
4039 if (rtype != void.class && cleanupParamTypes.get(1) != rtype) {
4040 throw misMatchedTypes("cleanup second argument and target return type", cleanup.type(), rtype);
4041 }
4042 // The cleanup parameter list (minus the leading Throwable and result parameters) must be a sublist of the
4043 // target parameter list.
4044 int cleanupArgIndex = rtype == void.class ? 1 : 2;
4045 if (!cleanupParamTypes.subList(cleanupArgIndex, cleanupParamTypes.size()).
4046 equals(target.type().parameterList().subList(0, cleanupParamTypes.size() - cleanupArgIndex))) {
4047 throw misMatchedTypes("cleanup parameters after (Throwable,result) and target parameter list prefix",
4048 cleanup.type(), target.type());
4049 }
4050 }
4051
4052 }
|