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
--- 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) {