[jep-334] Asymmetric method types of MHD vs MH
Maurizio Cimadamore
maurizio.cimadamore at oracle.com
Sun Nov 25 21:34:17 UTC 2018
On 25/11/2018 21:29, Maurizio Cimadamore wrote:
>
>
> On 22/11/2018 07:21, Michael van Acken wrote:
>> Maurizio Cimadamore <maurizio.cimadamore at oracle.com
>> <mailto:maurizio.cimadamore at oracle.com>> schrieb am Mi., 21. Nov.
>> 2018 um 00:27 Uhr:
>>
>> 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() ?
>>
>>
>> To verify my understanding: this tentative lookupType() would return a
>> ClassDesc/TypeDescriptor.OfField for a field DMHDesc, and a
>> MethodTypeDesc/TypeDescriptor.OfMethod for a method DMHDesc.
>> Is this correct?
>
> That seems like a valid assumption to me
>
But, maybe I spoke too fast - in the MethodHandle API, calling type()
give you a MethodType - so if we follow that, we should always return a
MethodTypeDesc (with the right signature). Using TypeDescriptor.OfField
is possible, but that would break symmetry with the MethodHandle API
(its runtime equivalent would be a MethodHandle::type() method returning
a j.l.Class<?> value).
So, maybe it's better to stick with different type accessors (for lookup
and invocation type, however called) both returning some suitably typed
MethodTypeDesc.
Maurizio
> Maurizio
>
>>
>> -- Michael van Acken
>>
>>
>> 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
>> <mailto:brian.goetz at oracle.com>>
>> >>> À: "Michael van Acken" <michael.van.acken at gmail.com
>> <mailto:michael.van.acken at gmail.com>>, "amber-dev"
>> >>> <amber-dev at openjdk.java.net <mailto: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
>> <http://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