Hi Peter,

once more: thank you very much for your explanations, efforts and patience! :)

On 10.06.2018 17:04, Peter Levart wrote:
> I showed you some code samples in Java language, so I had to explain what 
> java compiler is doing
> too, for you to fully understand what's going on. You see, when using Java and
> HM.invokeWithArguments(), conversions (varargs included) are taking place at 
> two levels. The 1st
> conversion is performed by javac generated bytecode (when invoking 
> .invokeWithArguments, which is
> a varargs method) and the 2nd is the conversion performed by the 
> HM.invokeWithArguments() method
> itself when it invokes the target method. The 1st is specified by JLS, while 
> the 2nd is specified
> in the javadoc of .invokeWithArguments.
> If we skip the 1st conversion, since you probably know what compiler is 
> doing, you still have to
> be aware of the 2nd conversion, performed by MH.invokeWithArguments() (and 
> MH.invoke()). First
> thing you have to know is the following:
> /Method handles produced by lookups or constant loads from methods or 
> constructors with the
> variable arity modifier bit (0x0080) have a corresponding variable arity, as 
> if they were defined
> with the help of asVarargsCollector.//
> /
> This part does not mention the MethodHandles.Lookup.unreflect(Method) way of 
> producing
> MethodHandle(s), but its all the same. You have to be aware that some method 
> handles returned to
> you have a special property: they are varargs collectors. When invoking those 
> methods, they accept
> any number of trailing positional arguments and collect them into an array 
> argument.
> This does not happen when you invoke such methods using reflection.
> So if you want HM.invokeWithArguments() to behave the same as 
> Method.invoke(), you have to
> transform the method handles obtained from lookup / unreflect with 
> MH.asFixedArity() method. If
> the method handle is already a fixed arity method handle, this method will 
> just return it, else it
> will return the equivalent method handle that doesn't perform collection of 
> trailing positional
> arguments into an array argument. Using MH.asFixedArity() on each and every 
> method handle you
> obtain by unreflect should give you the same behavior of 
> MH.invokeWithArguments() as using
> Method.invoke().
Indeed, this seems to solve the problem, which is really great as this problem 
can be put to rest
and it makes it safe to use MH invocations in the bridge from Java 8 on!

Thank you *very* much again!
(And now, "after the fact" of your explanations I have become able to 
understand the cause of the
problem and its solution. I simply was not aware that by default a varargs 
collector would be
employed for the last (in this case single) argument for a varargs argument.)


Now, I would have another request in this context: are there any tutorials that 
would introduce one
into the world of MethodHandle(s) in the sort of "for dummies"? The reason I 
ask is as follows: in
the past years I have followed the introduction of MethodHandle(s) with Java 7 
and from time to time
skimmed over articles demonstrating the basics of taking advantage of MH. Yet 
when starting to use
them for rewriting the reflective invocation part I encountered a world that is 
documented, but
maybe too briefly (and for MH experts). It took me quite a long time to learn 
about the most
important methods and how to employ them. (But obviously, there is too much I 
am still not aware of.)

My take is that probably a little bit of more documentation and/or brief 
tutorials that stress
different aspects of MH programming (for the uninitiated, newbies) would help 
considerably. Maybe
brief ("nutshell") tutorials each explaining and demonstrating the different 
kinds of MH methods
(what problem do they solve, how would one program a problem solution).

So if anyone could point to such brief tutorials/articles "for newbies/dummies" 
covering and
demonstrating all the MH methods, this would be really great!


mlvm-dev mailing list

Reply via email to