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

Reply via email to