[jep-334] Asymmetric method types of MHD vs MH

John Rose john.r.rose at oracle.com
Fri Nov 23 22:05:35 UTC 2018


I think MemberName calls them type and invocationType. That seems like a good division of labor to me, but then I wrote it. :-)

> On Nov 20, 2018, at 3:26 PM, Maurizio Cimadamore <maurizio.cimadamore at oracle.com> wrote:
> 
> I agree - there are two types: the one based on real classfile descriptor and the unified, curried one exposed by MethodHandle::type(). The former is used for lookup, the latter for invocation. Maybe lookupType() and invocationType() ?
> 
> Maurizio
> 
>> On 20/11/2018 18:40, Brian Goetz wrote:
>> There are actually two types here, and they both should be exposed.  One is a property of MHDesc (which is correctly called type()) which describes the invocation type of the MH; the other is a propertly of DirectMHDesc (which needs a new name) and which is the type that one would provide to the lookup / place in the NameAndType. We're currently in an inconsistent situation.
>> 
>>> On 11/20/2018 10:20 AM, Remi Forax wrote:
>>> Hi Brian,
>>> while i agree that the API is primarily a mirror the JVMS view and not the java.lang.invoke view,
>>> one way to avoid that ambiguity is to rename methodType() to type() (as in NameAndType).
>>> 
>>> Rémi
>>> 
>>> ----- Mail original -----
>>>> De: "Brian Goetz" <brian.goetz at oracle.com>
>>>> À: "Michael van Acken" <michael.van.acken at gmail.com>, "amber-dev" <amber-dev at openjdk.java.net>
>>>> Envoyé: Mardi 20 Novembre 2018 14:28:06
>>>> Objet: Re: [jep-334] Asymmetric method types of MHD vs MH
>>>> Thanks for poking into these new APIs.  This is a good question.
>>>> 
>>>> Your mental model is a good first-order approximation, but it has some
>>>> risk; in the event of conflict, XxDesc's classes loyalty will be to
>>>> Constant_Xxx_info (the classfile format), rather than its live-type
>>>> counterpart.
>>>> 
>>>> MethodHandle embeds the invocation mode (static, virtual, interface,
>>>> special) in the MH itself, so that you can treat the receiver as just
>>>> another parameter.  This is tremendously useful as the primary purpose
>>>> of method handles is to be invoked; it collapse four invocation modes
>>>> into one.
>>>> 
>>>> DirectMethodHandleDesc models the classfile structure of an invocation;
>>>> the MethodRef_info/NameAndType/invocation bytecode -- as shown in your
>>>> example:
>>>> 
>>>>      jshell> var mhd = (MethodHandleDesc)mh.describeConstable().get()
>>>>      mhd ==> MethodHandleDesc[VIRTUAL/PrintStream::println()void]
>>>> 
>>>> I think what you're saying is: there is enough information here to correctly
>>>> compose the type() -- for virtual/special/interface, curry the owner type on --
>>>> and that this would provide alignment with the live MethodHandle behavior.
>>>> 
>>>> But, it would separate from the classfile Constant_MethodHandle_info behavior;
>>>> what goes in the NameAndType here (for instance methods) is the receiver-less
>>>> version.  Hence the conflict.
>>>> 
>>>> I think what is really going on here is that there are two types -- the MH type,
>>>> and the lookup type; the latter is a property of the DMHDesc, while the former
>>>> is a property of the MHDesc?
>>>> 
>>>> 
>>>>> On 11/20/2018 7:06 AM, Michael van Acken wrote:
>>>>> While tracking down unexpected behavior in my compiler, I noticed that
>>>>> MethodHandleDesc and MethodHandle differ in what they list in their
>>>>> method type.  I was expecting that the MHD matches the MH, in that
>>>>> the receiver of a virtual method is included in the parameter list.
>>>>> Instead,
>>>>> it is omitted.  (See below for a jshell example.)
>>>>> 
>>>>> As a compiler writer, I find the MH's unified view on static and virtual
>>>>> method types very helpful.  The current implementation's MHD class
>>>>> does not mirror this view, which means I would have to special case the
>>>>> method types for some operations.
>>>>> 
>>>>> My mental model of the descriptor classes is, that they are one-to-one
>>>>> symbolic representations of their handle counterparts.  I am very confused
>>>>> by the difference in structure, with the receiver dropping out of the
>>>>> method type.
>>>>> 
>>>>> 
>>>>> |  Welcome to JShell -- Version 12-internal
>>>>> |  For an introduction type: /help intro
>>>>> 
>>>>> jshell> import java.lang.invoke.*
>>>>> 
>>>>> jshell> import java.lang.constant.*
>>>>> 
>>>>> jshell> var l = MethodHandles.lookup()
>>>>> l ==>
>>>>> 
>>>>> jshell> var mt = MethodType.methodType(Void.TYPE)
>>>>> mt ==> ()void
>>>>> 
>>>>> jshell> var mh = l.findVirtual(java.io.PrintStream.class, "println", mt)
>>>>> mh ==> MethodHandle(PrintStream)void
>>>>> 
>>>>> jshell> mh.type()
>>>>> $6 ==> (PrintStream)void
>>>>> 
>>>>> jshell> mh.type().parameterCount()
>>>>> $7 ==> 1
>>>>> 
>>>>> jshell> var mhd = (MethodHandleDesc)mh.describeConstable().get()
>>>>> mhd ==> MethodHandleDesc[VIRTUAL/PrintStream::println()void]
>>>>> 
>>>>> jshell> mhd.methodType()
>>>>> $9 ==> MethodTypeDesc[()void]
>>>>> 
>>>>> jshell> mhd.methodType().parameterCount()
>>>>> $10 ==> 0
>>>>> 
>>>>> 
>>>>> Regards,
>>>>> Michael van Acken
>> 



More information about the amber-dev mailing list