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