[jep-334] Asymmetric method types of MHD vs MH
Brian Goetz
brian.goetz at oracle.com
Tue Nov 20 18:40:20 UTC 2018
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