src/java.base/share/classes/java/lang/invoke/MethodHandle.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File jdk Sdiff src/java.base/share/classes/java/lang/invoke

src/java.base/share/classes/java/lang/invoke/MethodHandle.java

Print this page
rev 10591 : 8049555: Move varargsArray from sun.invoke.util package to java.lang.invoke
Reviewed-by: ?
rev 10592 : 8050052: Small cleanups in java.lang.invoke code
Reviewed-by: ?
rev 10593 : 8050053: Improve caching of different invokers
Reviewed-by: vlivanov, ?
Contributed-by: john.r.rose@oracle.com
rev 10594 : 8050166: Get rid of some package-private methods on arguments in j.l.i.MethodHandle
Reviewed-by: vlivanov, ?
Contributed-by: john.r.rose@oracle.com
rev 10595 : 8050173: Add j.l.i.MethodHandle.copyWith(MethodType, LambdaForm)
Reviewed-by: vlivanov, ?
Contributed-by: john.r.rose@oracle.com
rev 10597 : 8050174: Support overriding of isInvokeSpecial flag in WrappedMember
Reviewed-by: vlivanov, ?
Contributed-by: john.r.rose@oracle.com
rev 10598 : 8050057: Improve caching of MethodHandle reinvokers
Reviewed-by: vlivanov, ?
Contributed-by: john.r.rose@oracle.com
rev 10599 : 8050200: Make LambdaForm intrinsics detection more robust
Reviewed-by: vlivanov, ?
Contributed-by: john.r.rose@oracle.com
rev 10600 : imported patch 11.8050877.conv
rev 10603 : 8057654: Extract checks performed during MethodHandle construction into separate methods
Reviewed-by: vlivanov, ?
Contributed-by: john.r.rose@oracle.com


 852      * @param arrayType usually {@code Object[]}, the type of the array argument from which to extract the spread arguments
 853      * @param arrayLength the number of arguments to spread from an incoming array argument
 854      * @return a new method handle which spreads its final array argument,
 855      *         before calling the original method handle
 856      * @throws NullPointerException if {@code arrayType} is a null reference
 857      * @throws IllegalArgumentException if {@code arrayType} is not an array type,
 858      *         or if target does not have at least
 859      *         {@code arrayLength} parameter types,
 860      *         or if {@code arrayLength} is negative,
 861      *         or if the resulting method handle's type would have
 862      *         <a href="MethodHandle.html#maxarity">too many parameters</a>
 863      * @throws WrongMethodTypeException if the implied {@code asType} call fails
 864      * @see #asCollector
 865      */
 866     public MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
 867         asSpreaderChecks(arrayType, arrayLength);
 868         int spreadArgPos = type.parameterCount() - arrayLength;
 869         return MethodHandleImpl.makeSpreadArguments(this, arrayType, spreadArgPos, arrayLength);
 870     }
 871 
 872     private void asSpreaderChecks(Class<?> arrayType, int arrayLength) {




 873         spreadArrayChecks(arrayType, arrayLength);
 874         int nargs = type().parameterCount();
 875         if (nargs < arrayLength || arrayLength < 0)
 876             throw newIllegalArgumentException("bad spread array length");
 877         if (arrayType != Object[].class && arrayLength != 0) {
 878             boolean sawProblem = false;
 879             Class<?> arrayElement = arrayType.getComponentType();


 880             for (int i = nargs - arrayLength; i < nargs; i++) {
 881                 if (!MethodType.canConvert(arrayElement, type().parameterType(i))) {
 882                     sawProblem = true;



 883                     break;
 884                 }
 885             }
 886             if (sawProblem) {
 887                 ArrayList<Class<?>> ptypes = new ArrayList<>(type().parameterList());
 888                 for (int i = nargs - arrayLength; i < nargs; i++) {
 889                     ptypes.set(i, arrayElement);
 890                 }



 891                 // elicit an error:
 892                 this.asType(MethodType.methodType(type().returnType(), ptypes));
 893             }
 894         }
 895     }
 896 
 897     private void spreadArrayChecks(Class<?> arrayType, int arrayLength) {
 898         Class<?> arrayElement = arrayType.getComponentType();
 899         if (arrayElement == null)
 900             throw newIllegalArgumentException("not an array type", arrayType);
 901         if ((arrayLength & 0x7F) != arrayLength) {
 902             if ((arrayLength & 0xFF) != arrayLength)
 903                 throw newIllegalArgumentException("array length is not legal", arrayLength);
 904             assert(arrayLength >= 128);
 905             if (arrayElement == long.class ||
 906                 arrayElement == double.class)
 907                 throw newIllegalArgumentException("array length is not legal for long[] or double[]", arrayLength);
 908         }
 909     }
 910 
 911     /**
 912      * Makes an <em>array-collecting</em> method handle, which accepts a given number of trailing
 913      * positional arguments and collects them into an array argument.
 914      * The new method handle adapts, as its <i>target</i>,




 852      * @param arrayType usually {@code Object[]}, the type of the array argument from which to extract the spread arguments
 853      * @param arrayLength the number of arguments to spread from an incoming array argument
 854      * @return a new method handle which spreads its final array argument,
 855      *         before calling the original method handle
 856      * @throws NullPointerException if {@code arrayType} is a null reference
 857      * @throws IllegalArgumentException if {@code arrayType} is not an array type,
 858      *         or if target does not have at least
 859      *         {@code arrayLength} parameter types,
 860      *         or if {@code arrayLength} is negative,
 861      *         or if the resulting method handle's type would have
 862      *         <a href="MethodHandle.html#maxarity">too many parameters</a>
 863      * @throws WrongMethodTypeException if the implied {@code asType} call fails
 864      * @see #asCollector
 865      */
 866     public MethodHandle asSpreader(Class<?> arrayType, int arrayLength) {
 867         asSpreaderChecks(arrayType, arrayLength);
 868         int spreadArgPos = type.parameterCount() - arrayLength;
 869         return MethodHandleImpl.makeSpreadArguments(this, arrayType, spreadArgPos, arrayLength);
 870     }
 871 
 872     /**
 873      * See if {@code asSpreader} can be validly called with the given arguments.
 874      * Return the type of the method handle call after spreading but before conversions.
 875      */
 876     private MethodType asSpreaderChecks(Class<?> arrayType, int arrayLength) {
 877         spreadArrayChecks(arrayType, arrayLength);
 878         int nargs = type().parameterCount();
 879         if (nargs < arrayLength || arrayLength < 0)
 880             throw newIllegalArgumentException("bad spread array length");


 881         Class<?> arrayElement = arrayType.getComponentType();
 882         MethodType mtype = type();
 883         boolean match = true, fail = false;
 884         for (int i = nargs - arrayLength; i < nargs; i++) {
 885             Class<?> ptype = mtype.parameterType(i);
 886             if (ptype != arrayElement) {
 887                 match = false;
 888                 if (!MethodType.canConvert(arrayElement, ptype)) {
 889                     fail = true;
 890                     break;
 891                 }
 892             }




 893         }
 894         if (match)  return mtype;
 895         MethodType needType = mtype.asSpreaderType(arrayType, arrayLength);
 896         if (!fail)  return needType;
 897         // elicit an error:
 898         this.asType(needType);
 899         throw newInternalError("should not return", null);

 900     }
 901 
 902     private void spreadArrayChecks(Class<?> arrayType, int arrayLength) {
 903         Class<?> arrayElement = arrayType.getComponentType();
 904         if (arrayElement == null)
 905             throw newIllegalArgumentException("not an array type", arrayType);
 906         if ((arrayLength & 0x7F) != arrayLength) {
 907             if ((arrayLength & 0xFF) != arrayLength)
 908                 throw newIllegalArgumentException("array length is not legal", arrayLength);
 909             assert(arrayLength >= 128);
 910             if (arrayElement == long.class ||
 911                 arrayElement == double.class)
 912                 throw newIllegalArgumentException("array length is not legal for long[] or double[]", arrayLength);
 913         }
 914     }
 915 
 916     /**
 917      * Makes an <em>array-collecting</em> method handle, which accepts a given number of trailing
 918      * positional arguments and collects them into an array argument.
 919      * The new method handle adapts, as its <i>target</i>,


src/java.base/share/classes/java/lang/invoke/MethodHandle.java
Index Unified diffs Context diffs Sdiffs Patch New Old Previous File Next File