MethodHandle.bindTo chain fails with "IllegalArgumentException: no leading reference parameter"

Vladimir Ivanov vladimir.x.ivanov at oracle.com
Tue Jul 25 18:00:13 UTC 2017


> If you are using value types straight from source code (e.g. __Value), 
> then yes, this appears to be a problem in javac. However, if you are 
> just using value-capable classes, then javac shouldn't have much say in 
> what you are trying to do, so, if that's the case it would point more in 
> the MH direction.

It's the former case. The exception is thrown from javac-generated code.

   MethodHandle mh2 = MethodHandles.insertArguments(mh1, 0, test_vt);

is translated into:

11: anewarray     #7                  // class java/lang/Object
...
17: getfield      #3                  // Field test_vt:QMyValue1;
20: aastore
21: invokestatic  #8                  // Method 
java/lang/invoke/MethodHandles.insertArguments:(Ljava/lang/invoke/MethodHandle;I[Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle;

where test_vt is a Q-typed field:

   MyValue1 test_vt = MyValue1.createDefaultInline();

__ByValue final class MyValue1 {
...
   __ValueFactory static MyValue1 createDefaultInline() {
     return __MakeDefault MyValue1();
   }
}

aastore @ 20 tries to write a Q-typed value (loaded from test_vt) into 
Object[] before passing it into MethodHandles.insertArguments() which is 
vararg method.

I'd expect test_vt to be boxed first.

Best regards,
Vladimir Ivanov


> 
> Maurizio
> 
> 
> On 25/07/17 18:21, Vladimir Ivanov wrote:
>>> Changing
>>>      MethodHandle mh2 = mh1.bindTo(test_vt);
>>> to
>>>      MethodHandle mh2 = MethodHandles.insertArguments(mh1, 0, test_vt);
>>> fails with:
>>>
>>> Exception in thread "main" java.lang.ArrayStoreException: MyValue1
>>>     at Test.test(Test.java:35)
>>>     at Test.main(Test.java:41)
>>>
>>> Why's that?
>>
>> I'd say it's a problem in javac with auto-boxing of Q-types when 
>> calling vararg methods.
>>
>> It tries to store a Q-typed value into an Object[] which generates an 
>> ArrayStoreException:
>>
>>   long test() throws java.lang.Throwable;
>> ...
>>         10: iconst_1
>>         11: anewarray     #7                  // class java/lang/Object
>>         14: dup
>>         15: iconst_0
>>         16: aload_0
>>         17: getfield      #3                  // Field test_vt:QMyValue1;
>>         20: aastore
>>         21: invokestatic  #8                  // Method 
>> java/lang/invoke/MethodHandles.insertArguments:(Ljava/lang/invoke/MethodHandle;I[Ljava/lang/Object;)Ljava/lang/invoke/MethodHandle; 
>>
>>
>> Best regards,
>> Vladimir Ivanov
> 


More information about the valhalla-dev mailing list