Regression in newest MLVM build
John Rose
john.r.rose at oracle.com
Mon Jun 13 00:51:32 PDT 2011
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));
}
}
-------------- next part --------------
An HTML attachment was scrubbed...
URL: http://mail.openjdk.java.net/pipermail/mlvm-dev/attachments/20110613/09b65a39/attachment.html
More information about the mlvm-dev
mailing list