Thanks for the clarification, John. I'll go with asFixedArity().
Super excited as for the first time in history, Dynalink will get down to 0
failing testcases as OpenJDK bugs making them fail got squashed, yay!
Attila.
On Jun 13, 2011, at 12:51 AM, John Rose wrote:
> On Jun 11, 2011, at 2:18 PM, Attila Szegedi wrote:
>
>> And BTW, attempts at using invoke() or invokeExact() didn't work either…
>> They all behave strangely. What's the sanctioned way to pass an array
>> explicitly as a vararg argument?
>
> See the updated example below. The javadoc for invokeWithArguments contains
> rules that imply the behavior you are seeing. In other words, earlier
> implementations were broken.
>
> If you call a varargs method with invokeExact, no transformations will be
> done. This is the most direct way to turn off the varargs transformation (of
> collecting arguments into an array). But this requires explicit, static
> typing.
>
> Except for invokeExact, a varargs method routinely performs the varargs
> transformation. By analogy with the Java language, you can only avoid the
> varargs transformation if you supply an explicitly typed (statically typed)
> array for the last argument. If the last argument is not an explicitly typed
> array, the argument will be taken to be a single element of an implicitly
> specified argument array. That's what is happening in your example.
>
> More specifically, the convenience method invokeWithArguments works like a
> plain invoke but only on Object types. It cannot express static array types
> (Object[] or int[]) so it cannot bypass the varargs transformation.
>
> There's one more thing you can do: turn off the "varargs bit" with
> asFixedArity. That's probably the most direct way to avoid the varargs
> transformation, in the setting of untyped (Object-only) programming.
>
> -- John
>
>
>
> public class TestVarArgInvoke {
> public static void main(String[] args) throws Throwable {
> java.lang.invoke.MethodHandle x =
> java.lang.invoke.MethodHandles.publicLookup().unreflect(
> TestVarArgInvoke.class.getMethod("x", int.class, int[].class));
> for (int i = 0; i < 20; i++) {
> try {
> System.out.print("case "+i+": ");
> test(x, i);
> } catch (Exception ex) {
> System.out.print("*** throw "+ex); ex.printStackTrace();
> }
> }
> }
> static void test(java.lang.invoke.MethodHandle x, int i) throws Throwable {
> switch (i) {
> case 0: x.invokeWithArguments(
> new TestVarArgInvoke(), 1, new int[] { 2 });
> /*
> java.lang.ClassCastException: [I cannot be cast to
> java.lang.Numberjava.lang.ClassCastException: [I cannot be cast to
> java.lang.Number
> at
> sun.invoke.util.ValueConversions.primitiveConversion(ValueConversions.java:231)
> at
> sun.invoke.util.ValueConversions.unboxInteger(ValueConversions.java:76)
> at
> java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:571)
> at
> java.lang.invoke.MethodHandle.invokeWithArguments(MethodHandle.java:568)
> at TestVarArgInvoke.main(TestVarArgInvoke.java:7)
> */
> return;
> case 1: x.asFixedArity().invokeWithArguments(
> new TestVarArgInvoke(), 1, new int[] { 2 }); return;
> case 2: x.invokeExact(new TestVarArgInvoke(), 1, new int[] { 2 }); return;
> case 3: x.invoke(new TestVarArgInvoke(), 1, new int[] { 2 }); return;
> case 4: x.invoke((Object)new TestVarArgInvoke(), (Object)1, new int[] { 2
> }); return;
> case 5: x.invoke((Object)new TestVarArgInvoke(), (Object)1, (Object) new
> int[] { 2 });
> /*
> java.lang.ClassCastException: [I cannot be cast to
> java.lang.Numberjava.lang.ClassCastException: [I cannot be cast to
> java.lang.Number
> at
> sun.invoke.util.ValueConversions.primitiveConversion(ValueConversions.java:231)
> at
> sun.invoke.util.ValueConversions.unboxInteger(ValueConversions.java:76)
> at TestVarArgInvoke.test(TestVarArgInvoke.java:33)
> at TestVarArgInvoke.main(TestVarArgInvoke.java:9)
> */
> return;
> case 6: x.invokeExact(new TestVarArgInvoke(), 1, 2);
> /*
> java.lang.invoke.WrongMethodTypeException: (LTestVarArgInvoke;I[I)V cannot be
> called as (LTestVarArgInvoke;II)Vjava.lang.invoke.WrongMethodTypeException:
> (LTestVarArgInvoke;I[I)V cannot be called as (LTestVarArgInvoke;II)V
> at TestVarArgInvoke.test(TestVarArgInvoke.java:37)
> at TestVarArgInvoke.main(TestVarArgInvoke.java:9)
> */
> return;
> }
> System.out.println();
> }
>
> public void x(int a, int... b) {
> System.out.println(a+java.util.Arrays.toString(b));
> }
> }
>
> _______________________________________________
> mlvm-dev mailing list
> [email protected]
> http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev
_______________________________________________
mlvm-dev mailing list
[email protected]
http://mail.openjdk.java.net/mailman/listinfo/mlvm-dev