378 */ 379 public GuardedInvocation asTypeSafeReturn(final LinkerServices linkerServices, final MethodType newType) { 380 return replaceMethodsOrThis(linkerServices.asTypeLosslessReturn(invocation, newType), guard == null ? null : 381 Guards.asType(linkerServices, guard, newType)); 382 } 383 384 /** 385 * Changes the type of the invocation, as if 386 * {@link MethodHandle#asType(MethodType)} was applied to its invocation 387 * and its guard, if it has one (with return type changed to boolean for 388 * guard). If the invocation already is of the required type, returns this 389 * object. 390 * @param desc a call descriptor whose method type is adapted. 391 * @return a guarded invocation with the new type applied to it. 392 */ 393 public GuardedInvocation asType(final CallSiteDescriptor desc) { 394 return asType(desc.getMethodType()); 395 } 396 397 /** 398 * Applies argument filters to both the invocation and the guard (if there 399 * is one) with {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)}. 400 * @param pos the position of the first argument being filtered 401 * @param filters the argument filters 402 * @return a filtered invocation 403 */ 404 public GuardedInvocation filterArguments(final int pos, final MethodHandle... filters) { 405 return replaceMethods(MethodHandles.filterArguments(invocation, pos, filters), guard == null ? null : 406 MethodHandles.filterArguments(guard, pos, filters)); 407 } 408 409 /** 410 * Makes an invocation that drops arguments in both the invocation and the 411 * guard (if there is one) with {@link MethodHandles#dropArguments(MethodHandle, int, List)}. 412 * @param pos the position of the first argument being dropped 413 * @param valueTypes the types of the values being dropped 414 * @return an invocation that drops arguments 415 */ 416 public GuardedInvocation dropArguments(final int pos, final List<Class<?>> valueTypes) { 417 return replaceMethods(MethodHandles.dropArguments(invocation, pos, valueTypes), guard == null ? null : 418 MethodHandles.dropArguments(guard, pos, valueTypes)); 419 } 420 421 /** 422 * Makes an invocation that drops arguments in both the invocation and the 423 * guard (if there is one) with {@link MethodHandles#dropArguments(MethodHandle, int, Class...)}. 424 * @param pos the position of the first argument being dropped 425 * @param valueTypes the types of the values being dropped 426 * @return an invocation that drops arguments 427 */ 428 public GuardedInvocation dropArguments(final int pos, final Class<?>... valueTypes) { 429 return replaceMethods(MethodHandles.dropArguments(invocation, pos, valueTypes), guard == null ? null : 430 MethodHandles.dropArguments(guard, pos, valueTypes)); 431 } 432 433 434 /** 435 * Composes the invocation, guard, switch points, and the exception into a 436 * composite method handle that knows how to fall back when the guard fails 437 * or the invocation is invalidated. 438 * @param fallback the fallback method handle for when a switch point is 439 * invalidated, a guard returns false, or invalidating exception is thrown. 440 * @return a composite method handle. 441 */ 442 public MethodHandle compose(final MethodHandle fallback) { 443 return compose(fallback, fallback, fallback); 444 } 445 446 /** 447 * Composes the invocation, guard, switch points, and the exception into a 448 * composite method handle that knows how to fall back when the guard fails 449 * or the invocation is invalidated. 450 * @param switchpointFallback the fallback method handle in case a switch | 378 */ 379 public GuardedInvocation asTypeSafeReturn(final LinkerServices linkerServices, final MethodType newType) { 380 return replaceMethodsOrThis(linkerServices.asTypeLosslessReturn(invocation, newType), guard == null ? null : 381 Guards.asType(linkerServices, guard, newType)); 382 } 383 384 /** 385 * Changes the type of the invocation, as if 386 * {@link MethodHandle#asType(MethodType)} was applied to its invocation 387 * and its guard, if it has one (with return type changed to boolean for 388 * guard). If the invocation already is of the required type, returns this 389 * object. 390 * @param desc a call descriptor whose method type is adapted. 391 * @return a guarded invocation with the new type applied to it. 392 */ 393 public GuardedInvocation asType(final CallSiteDescriptor desc) { 394 return asType(desc.getMethodType()); 395 } 396 397 /** 398 * Applies argument filters to both the invocation and the guard 399 * (if it exists and has at least {@code pos + 1} parameters) with 400 * {@link MethodHandles#filterArguments(MethodHandle, int, MethodHandle...)}. 401 * @param pos the position of the first argument being filtered 402 * @param filters the argument filters 403 * @return a filtered invocation 404 */ 405 public GuardedInvocation filterArguments(final int pos, final MethodHandle... filters) { 406 return replaceMethods(MethodHandles.filterArguments(invocation, pos, filters), 407 guard == null || pos >= guard.type().parameterCount() ? 408 guard : MethodHandles.filterArguments(guard, pos, filters)); 409 } 410 411 /** 412 * Makes an invocation that drops arguments in both the invocation and the 413 * guard (if it exists and has at least {@code pos} parameters) with 414 * {@link MethodHandles#dropArguments(MethodHandle, int, List)}. 415 * @param pos the position of the first argument being dropped 416 * @param valueTypes the types of the values being dropped 417 * @return an invocation that drops arguments 418 */ 419 public GuardedInvocation dropArguments(final int pos, final List<Class<?>> valueTypes) { 420 return replaceMethods(MethodHandles.dropArguments(invocation, pos, valueTypes), 421 guard == null || pos > guard.type().parameterCount() ? 422 guard : MethodHandles.dropArguments(guard, pos, valueTypes)); 423 } 424 425 /** 426 * Makes an invocation that drops arguments in both the invocation and the 427 * guard (if it exists and has at least {@code pos} parameters) with 428 * {@link MethodHandles#dropArguments(MethodHandle, int, Class...)}. 429 * @param pos the position of the first argument being dropped 430 * @param valueTypes the types of the values being dropped 431 * @return an invocation that drops arguments 432 */ 433 public GuardedInvocation dropArguments(final int pos, final Class<?>... valueTypes) { 434 return replaceMethods(MethodHandles.dropArguments(invocation, pos, valueTypes), 435 guard == null || pos > guard.type().parameterCount() ? 436 guard : MethodHandles.dropArguments(guard, pos, valueTypes)); 437 } 438 439 440 /** 441 * Composes the invocation, guard, switch points, and the exception into a 442 * composite method handle that knows how to fall back when the guard fails 443 * or the invocation is invalidated. 444 * @param fallback the fallback method handle for when a switch point is 445 * invalidated, a guard returns false, or invalidating exception is thrown. 446 * @return a composite method handle. 447 */ 448 public MethodHandle compose(final MethodHandle fallback) { 449 return compose(fallback, fallback, fallback); 450 } 451 452 /** 453 * Composes the invocation, guard, switch points, and the exception into a 454 * composite method handle that knows how to fall back when the guard fails 455 * or the invocation is invalidated. 456 * @param switchpointFallback the fallback method handle in case a switch |