8187237: Need to define the behaviour for 0 and 1 argument method type in StringConcatFactory.makeConcat
authorpsandoz
Wed, 29 Nov 2017 12:39:59 -0800
changeset 47985 80a058c0f993
parent 47984 89c26000ce52
child 47986 45c5d7817e9e
8187237: Need to define the behaviour for 0 and 1 argument method type in StringConcatFactory.makeConcat 8186737: Lookup argument for StringConcatFactory.makeConcat & makeConcatWithConstants cannot have privileges less than PRIVATE Reviewed-by: mchung
src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java
src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java
test/jdk/java/lang/String/concat/StringConcatFactoryInvariants.java
--- a/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java	Wed Nov 29 21:23:57 2017 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/LambdaMetafactory.java	Wed Nov 29 12:39:59 2017 -0800
@@ -263,8 +263,12 @@
      * methods from {@code Object}.
      *
      * @param caller Represents a lookup context with the accessibility
-     *               privileges of the caller.  When used with {@code invokedynamic},
-     *               this is stacked automatically by the VM.
+     *               privileges of the caller.  Specifically, the lookup context
+     *               must have
+     *               <a href="MethodHandles.Lookup.html#privacc">private access</a>
+     *               privileges.
+     *               When used with {@code invokedynamic}, this is stacked
+     *               automatically by the VM.
      * @param invokedName The name of the method to implement.  When used with
      *                    {@code invokedynamic}, this is provided by the
      *                    {@code NameAndType} of the {@code InvokeDynamic}
@@ -294,7 +298,8 @@
      *         instances of the interface named by {@code invokedType}
      * @throws LambdaConversionException If any of the linkage invariants
      *                                   described {@link LambdaMetafactory above}
-     *                                   are violated
+     *                                   are violated, or the lookup context
+     *                                   does not have private access privileges.
      */
     public static CallSite metafactory(MethodHandles.Lookup caller,
                                        String invokedName,
@@ -404,8 +409,12 @@
      * </ul>
      *
      * @param caller Represents a lookup context with the accessibility
-     *               privileges of the caller.  When used with {@code invokedynamic},
-     *               this is stacked automatically by the VM.
+     *               privileges of the caller.  Specifically, the lookup context
+     *               must have
+     *               <a href="MethodHandles.Lookup.html#privacc">private access</a>
+     *               privileges.
+     *               When used with {@code invokedynamic}, this is stacked
+     *               automatically by the VM.
      * @param invokedName The name of the method to implement.  When used with
      *                    {@code invokedynamic}, this is provided by the
      *                    {@code NameAndType} of the {@code InvokeDynamic}
@@ -429,7 +438,8 @@
      *         instances of the interface named by {@code invokedType}
      * @throws LambdaConversionException If any of the linkage invariants
      *                                   described {@link LambdaMetafactory above}
-     *                                   are violated
+     *                                   are violated, or the lookup context
+     *                                   does not have private access privileges.
      */
     public static CallSite altMetafactory(MethodHandles.Lookup caller,
                                           String invokedName,
--- a/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Wed Nov 29 21:23:57 2017 +0100
+++ b/src/java.base/share/classes/java/lang/invoke/StringConcatFactory.java	Wed Nov 29 12:39:59 2017 -0800
@@ -385,9 +385,16 @@
      * invoked, it returns the result of String concatenation, taking all
      * function arguments passed to the linkage method as inputs for
      * concatenation. The target signature is given by {@code concatType}.
-     * The arguments are concatenated as per requirements stated in JLS 15.18.1
-     * "String Concatenation Operator +". Notably, the inputs are converted as
-     * per JLS 5.1.11 "String Conversion", and combined from left to right.
+     * For a target accepting:
+     * <ul>
+     *     <li>zero inputs, concatenation results in an empty string;</li>
+     *     <li>one input, concatenation results in the single
+     *     input converted as per JLS 5.1.11 "String Conversion"; otherwise</li>
+     *     <li>two or more inputs, the inputs are concatenated as per
+     *     requirements stated in JLS 15.18.1 "String Concatenation Operator +".
+     *     The inputs are converted as per JLS 5.1.11 "String Conversion",
+     *     and combined from left to right.</li>
+     * </ul>
      *
      * <p>Assume the linkage arguments are as follows:
      *
@@ -404,8 +411,12 @@
      * </ul>
      *
      * @param lookup   Represents a lookup context with the accessibility
-     *                 privileges of the caller.  When used with {@code
-     *                 invokedynamic}, this is stacked automatically by the VM.
+     *                 privileges of the caller. Specifically, the lookup
+     *                 context must have
+     *                 <a href="MethodHandles.Lookup.html#privacc">private access</a>
+     *                 privileges.
+     *                 When used with {@code invokedynamic}, this is stacked
+     *                 automatically by the VM.
      * @param name     The name of the method to implement. This name is
      *                 arbitrary, and has no meaning for this linkage method.
      *                 When used with {@code invokedynamic}, this is provided by
@@ -422,7 +433,8 @@
      * concatenation, with dynamic concatenation arguments described by the given
      * {@code concatType}.
      * @throws StringConcatException If any of the linkage invariants described
-     *                               here are violated.
+     *                               here are violated, or the lookup context
+     *                               does not have private access privileges.
      * @throws NullPointerException If any of the incoming arguments is null.
      *                              This will never happen when a bootstrap method
      *                              is called with invokedynamic.
@@ -452,10 +464,17 @@
      * invoked, it returns the result of String concatenation, taking all
      * function arguments and constants passed to the linkage method as inputs for
      * concatenation. The target signature is given by {@code concatType}, and
-     * does not include constants. The arguments are concatenated as per requirements
-     * stated in JLS 15.18.1 "String Concatenation Operator +". Notably, the inputs
-     * are converted as per JLS 5.1.11 "String Conversion", and combined from left
-     * to right.
+     * does not include constants.
+     * For a target accepting:
+     * <ul>
+     *     <li>zero inputs, concatenation results in an empty string;</li>
+     *     <li>one input, concatenation results in the single
+     *     input converted as per JLS 5.1.11 "String Conversion"; otherwise</li>
+     *     <li>two or more inputs, the inputs are concatenated as per
+     *     requirements stated in JLS 15.18.1 "String Concatenation Operator +".
+     *     The inputs are converted as per JLS 5.1.11 "String Conversion",
+     *     and combined from left to right.</li>
+     * </ul>
      *
      * <p>The concatenation <em>recipe</em> is a String description for the way to
      * construct a concatenated String from the arguments and constants. The
@@ -502,9 +521,12 @@
      * </ul>
      *
      * @param lookup    Represents a lookup context with the accessibility
-     *                  privileges of the caller. When used with {@code
-     *                  invokedynamic}, this is stacked automatically by the
-     *                  VM.
+     *                  privileges of the caller. Specifically, the lookup
+     *                  context must have
+     *                  <a href="MethodHandles.Lookup.html#privacc">private access</a>
+     *                  privileges.
+     *                  When used with {@code invokedynamic}, this is stacked
+     *                  automatically by the VM.
      * @param name      The name of the method to implement. This name is
      *                  arbitrary, and has no meaning for this linkage method.
      *                  When used with {@code invokedynamic}, this is provided
@@ -524,7 +546,8 @@
      * concatenation, with dynamic concatenation arguments described by the given
      * {@code concatType}.
      * @throws StringConcatException If any of the linkage invariants described
-     *                               here are violated.
+     *                               here are violated, or the lookup context
+     *                               does not have private access privileges.
      * @throws NullPointerException If any of the incoming arguments is null, or
      *                              any constant in {@code recipe} is null.
      *                              This will never happen when a bootstrap method
--- a/test/jdk/java/lang/String/concat/StringConcatFactoryInvariants.java	Wed Nov 29 21:23:57 2017 +0100
+++ b/test/jdk/java/lang/String/concat/StringConcatFactoryInvariants.java	Wed Nov 29 12:39:59 2017 -0800
@@ -282,6 +282,30 @@
         // Advanced factory: public Lookup is rejected
         fail("Passing public Lookup",
                 () -> StringConcatFactory.makeConcatWithConstants(MethodHandles.publicLookup(), methodName, mtEmpty, recipeEmpty));
+
+        // Zero inputs
+        {
+            MethodType zero = MethodType.methodType(String.class);
+            CallSite cs = StringConcatFactory.makeConcat(lookup, methodName, zero);
+            test("", (String) cs.getTarget().invokeExact());
+
+            cs = StringConcatFactory.makeConcatWithConstants(lookup, methodName, zero, "");
+            test("", (String) cs.getTarget().invokeExact());
+        }
+
+        // One input
+        {
+            MethodType zero = MethodType.methodType(String.class);
+            MethodType one = MethodType.methodType(String.class, String.class);
+            CallSite cs = StringConcatFactory.makeConcat(lookup, methodName, one);
+            test("A", (String) cs.getTarget().invokeExact("A"));
+
+            cs = StringConcatFactory.makeConcatWithConstants(lookup, methodName, one, "\1");
+            test("A", (String) cs.getTarget().invokeExact("A"));
+
+            cs = StringConcatFactory.makeConcatWithConstants(lookup, methodName, zero, "\2", "A");
+            test("A", (String) cs.getTarget().invokeExact());
+        }
     }
 
     public static void ok(String msg, Callable runnable) {