< prev index next >

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

Print this page
rev 15544 : imported patch fold_select


3926         int foldArgs   = combinerType.parameterCount();
3927         Class<?> rtype = combinerType.returnType();
3928         int foldVals = rtype == void.class ? 0 : 1;
3929         int afterInsertPos = foldPos + foldVals;
3930         boolean ok = (targetType.parameterCount() >= afterInsertPos + foldArgs);
3931         if (ok) {
3932             for (int i = 0; i < foldArgs; i++) {
3933                 if (combinerType.parameterType(i) != targetType.parameterType(i + afterInsertPos)) {
3934                     ok = false;
3935                     break;
3936                 }
3937             }
3938         }
3939         if (ok && foldVals != 0 && combinerType.returnType() != targetType.parameterType(foldPos))
3940             ok = false;
3941         if (!ok)
3942             throw misMatchedTypes("target and combiner types", targetType, combinerType);
3943         return rtype;
3944     }
3945 



























3946     /**
3947      * Makes a method handle which adapts a target method handle,
3948      * by guarding it with a test, a boolean-valued method handle.
3949      * If the guard fails, a fallback handle is called instead.
3950      * All three method handles must have the same corresponding
3951      * argument and return types, except that the return type
3952      * of the test must be boolean, and the test is allowed
3953      * to have fewer arguments than the other two method handles.
3954      * <p>
3955      * Here is pseudocode for the resulting adapter. In the code, {@code T}
3956      * represents the uniform result type of the three involved handles;
3957      * {@code A}/{@code a}, the types and values of the {@code target}
3958      * parameters and arguments that are consumed by the {@code test}; and
3959      * {@code B}/{@code b}, those types and values of the {@code target}
3960      * parameters and arguments that are not consumed by the {@code test}.
3961      * <blockquote><pre>{@code
3962      * boolean test(A...);
3963      * T target(A...,B...);
3964      * T fallback(A...,B...);
3965      * T adapter(A... a,B... b) {


4932      *          are not identical with the argument types of {@code combiner}
4933      *
4934      * @see #foldArguments(MethodHandle, MethodHandle)
4935      * @since 9
4936      */
4937     public static MethodHandle foldArguments(MethodHandle target, int pos, MethodHandle combiner) {
4938         MethodType targetType = target.type();
4939         MethodType combinerType = combiner.type();
4940         Class<?> rtype = foldArgumentChecks(pos, targetType, combinerType);
4941         BoundMethodHandle result = target.rebind();
4942         boolean dropResult = rtype == void.class;
4943         LambdaForm lform = result.editor().foldArgumentsForm(1 + pos, dropResult, combinerType.basicType());
4944         MethodType newType = targetType;
4945         if (!dropResult) {
4946             newType = newType.dropParameterTypes(pos, pos + 1);
4947         }
4948         result = result.copyWithExtendL(newType, lform, combiner);
4949         return result;
4950     }
4951 






















4952 
4953     private static void checkLoop0(MethodHandle[][] clauses) {
4954         if (clauses == null || clauses.length == 0) {
4955             throw newIllegalArgumentException("null or no clauses passed");
4956         }
4957         if (Stream.of(clauses).anyMatch(Objects::isNull)) {
4958             throw newIllegalArgumentException("null clauses are not allowed");
4959         }
4960         if (Stream.of(clauses).anyMatch(c -> c.length > 4)) {
4961             throw newIllegalArgumentException("All loop clauses must be represented as MethodHandle arrays with at most 4 elements.");
4962         }
4963     }
4964 
4965     private static void checkLoop1a(int i, MethodHandle in, MethodHandle st) {
4966         if (in.type().returnType() != st.type().returnType()) {
4967             throw misMatchedTypes("clause " + i + ": init and step return types", in.type().returnType(),
4968                     st.type().returnType());
4969         }
4970     }
4971 




3926         int foldArgs   = combinerType.parameterCount();
3927         Class<?> rtype = combinerType.returnType();
3928         int foldVals = rtype == void.class ? 0 : 1;
3929         int afterInsertPos = foldPos + foldVals;
3930         boolean ok = (targetType.parameterCount() >= afterInsertPos + foldArgs);
3931         if (ok) {
3932             for (int i = 0; i < foldArgs; i++) {
3933                 if (combinerType.parameterType(i) != targetType.parameterType(i + afterInsertPos)) {
3934                     ok = false;
3935                     break;
3936                 }
3937             }
3938         }
3939         if (ok && foldVals != 0 && combinerType.returnType() != targetType.parameterType(foldPos))
3940             ok = false;
3941         if (!ok)
3942             throw misMatchedTypes("target and combiner types", targetType, combinerType);
3943         return rtype;
3944     }
3945     
3946     private static Class<?> foldArgumentChecks(int foldPos, MethodType targetType, MethodType combinerType, int ... argPos) {
3947         int foldArgs = combinerType.parameterCount();
3948         if (argPos.length != foldArgs) {
3949             throw newIllegalArgumentException("combiner and argument map must be equal size", combinerType, argPos.length);
3950         }
3951         Class<?> rtype = combinerType.returnType();
3952         int foldVals = rtype == void.class ? 0 : 1;
3953         boolean ok = true;
3954         for (int i = 0; i < foldArgs; i++) {
3955             int arg = argPos[i];
3956             if (arg < 0 || arg > targetType.parameterCount()) {
3957                 throw newIllegalArgumentException("arg outside of target parameterRange", targetType, arg);
3958             }
3959             if (combinerType.parameterType(i) != targetType.parameterType(arg)) {
3960                 throw newIllegalArgumentException("target argument type at position " + arg 
3961                         + " must match combiner argument type at index " + i + ": " + targetType
3962                         + " -> " + combinerType + ", map: " + Arrays.toString(argPos));
3963             }
3964         }
3965         if (ok && foldVals != 0 && combinerType.returnType() != targetType.parameterType(foldPos)) {
3966             ok = false;
3967         }
3968         if (!ok)
3969             throw misMatchedTypes("target and combiner types", targetType, combinerType);
3970         return rtype;
3971     }
3972 
3973     /**
3974      * Makes a method handle which adapts a target method handle,
3975      * by guarding it with a test, a boolean-valued method handle.
3976      * If the guard fails, a fallback handle is called instead.
3977      * All three method handles must have the same corresponding
3978      * argument and return types, except that the return type
3979      * of the test must be boolean, and the test is allowed
3980      * to have fewer arguments than the other two method handles.
3981      * <p>
3982      * Here is pseudocode for the resulting adapter. In the code, {@code T}
3983      * represents the uniform result type of the three involved handles;
3984      * {@code A}/{@code a}, the types and values of the {@code target}
3985      * parameters and arguments that are consumed by the {@code test}; and
3986      * {@code B}/{@code b}, those types and values of the {@code target}
3987      * parameters and arguments that are not consumed by the {@code test}.
3988      * <blockquote><pre>{@code
3989      * boolean test(A...);
3990      * T target(A...,B...);
3991      * T fallback(A...,B...);
3992      * T adapter(A... a,B... b) {


4959      *          are not identical with the argument types of {@code combiner}
4960      *
4961      * @see #foldArguments(MethodHandle, MethodHandle)
4962      * @since 9
4963      */
4964     public static MethodHandle foldArguments(MethodHandle target, int pos, MethodHandle combiner) {
4965         MethodType targetType = target.type();
4966         MethodType combinerType = combiner.type();
4967         Class<?> rtype = foldArgumentChecks(pos, targetType, combinerType);
4968         BoundMethodHandle result = target.rebind();
4969         boolean dropResult = rtype == void.class;
4970         LambdaForm lform = result.editor().foldArgumentsForm(1 + pos, dropResult, combinerType.basicType());
4971         MethodType newType = targetType;
4972         if (!dropResult) {
4973             newType = newType.dropParameterTypes(pos, pos + 1);
4974         }
4975         result = result.copyWithExtendL(newType, lform, combiner);
4976         return result;
4977     }
4978 
4979     /** 
4980      * 
4981      * @param target
4982      * @param pos
4983      * @param combiner
4984      * @param argPositions
4985      * @return 
4986      */
4987     static MethodHandle foldArguments(MethodHandle target, int pos, MethodHandle combiner, int ... argPositions) {
4988         MethodType targetType = target.type();
4989         MethodType combinerType = combiner.type();
4990         Class<?> rtype = foldArgumentChecks(pos, targetType, combinerType, argPositions);
4991         BoundMethodHandle result = target.rebind();
4992         boolean dropResult = rtype == void.class;
4993         LambdaForm lform = result.editor().foldArgumentsForm(1 + pos, dropResult, combinerType.basicType(), argPositions);
4994         MethodType newType = targetType;
4995         if (!dropResult) {
4996             newType = newType.dropParameterTypes(pos, pos + 1);
4997         }
4998         result = result.copyWithExtendL(newType, lform, combiner);
4999         return result;
5000     }
5001     
5002     private static void checkLoop0(MethodHandle[][] clauses) {
5003         if (clauses == null || clauses.length == 0) {
5004             throw newIllegalArgumentException("null or no clauses passed");
5005         }
5006         if (Stream.of(clauses).anyMatch(Objects::isNull)) {
5007             throw newIllegalArgumentException("null clauses are not allowed");
5008         }
5009         if (Stream.of(clauses).anyMatch(c -> c.length > 4)) {
5010             throw newIllegalArgumentException("All loop clauses must be represented as MethodHandle arrays with at most 4 elements.");
5011         }
5012     }
5013 
5014     private static void checkLoop1a(int i, MethodHandle in, MethodHandle st) {
5015         if (in.type().returnType() != st.type().returnType()) {
5016             throw misMatchedTypes("clause " + i + ": init and step return types", in.type().returnType(),
5017                     st.type().returnType());
5018         }
5019     }
5020 


< prev index next >