[jep-334] Asymmetric method types of MHD vs MH
Michael van Acken
michael.van.acken at gmail.com
Tue Nov 20 22:41:07 UTC 2018
Brian Goetz <brian.goetz at oracle.com> schrieb am Di., 20. Nov. 2018 um
19:40 Uhr:
> 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.
>
Don't know if it helps, but my ad hoc code to emit invoke() currently
bottoms out
in a three-way split on ASM level:
getter
visitFieldInsn(opc, owner, name,
dmhd.methodType().returnType().descriptorString())
setter
visitFieldInsn(opc, owner, name,
dmhd.methodType().parameterType(last).descriptorString())
method
visitMethodInsn(opc, owner, name, dmhd.methodType().descriptorString(),
itf)
That is, for fields there is a gap where the type descriptor passed to ASM
must be
recovered from refKind() & methodType().
-- Michael van Acken
> 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