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

Brian Goetz brian.goetz at oracle.com
Fri Nov 30 15:37:22 UTC 2018

On 11/30/2018 3:27 AM, Michael van Acken wrote:
> Brian Goetz <brian.goetz at oracle.com <mailto:brian.goetz at oracle.com>> 
> schrieb am Do., 29. Nov. 2018 um 17:27 Uhr:
>     MemberName calls them type and invocationType; unfortunately, what
>     MethodHandle calls type() is the invocation type, and this seems
>     pretty
>     natural for MethodHandle (what else are you going to do with a MH,
>     except invoke it?)  Which suggests either:
>       - MHDesc has a method called type(), and it is also be the
>     invocation
>     type;
>       - MHDesc has no method called type(), but instead has
>     invocationType()
>     and lookupType(), or some other better name.
> I believe this would match the usage of invocationType() in
> DynamicCallSiteDesc as well.

Yes, DCSD is not perturbed by the strange receiver-less lookup behavior 
(which we inherit from MH.Lookup and reflection, which is inherited from 
the classfile format.)

> Is the distinction "invocationType() is a thing of the operand stack" 
> while
> "lookupType() is a thing of the constant pool" a useful mental model here?

I'd like it to be, but it doesn't quite fit, because in the CP, field 
access method handles refer to FieldRef, not MethodRef, constants.  So 
the best we can say is lookupType() is the invocation type for a field 
access MH, but the descriptor that would appear in the CP for a method 
access MH.

The seam we're trying to paper over is that the classfile uses a union 
of (FRef|MRef), but we don't want to expose APIs that truck in such a 
union, at least not until we have sealed types where we can define an 
exclusive sum of CD|MTD.  So we invent this half-beast lookup type, 
which really has no analogue in the CP, which is a wart.

>     I think the latter is probably safer.
>     Now, what should the lookupType() be?  There's again two ways to go:
>       - Return a ClassDesc for field ops, and a MethodTypeDesc for
>     method ops;
>       - Return a MethodTypeDesc for both
> My first association for "lookupType()" was the table of lookup.findXXX()
> methods with its clear separation MethodType / Class here:
> https://docs.oracle.com/en/java/javase/11/docs/api/java.base/java/lang/invoke/MethodHandles.Lookup.html

Yes, for a method or ctor, its what you pass to this.  But for a field, 
not exactly.

>     Another is if you want to feed a MHDesc back into the lookup methods:
>          MHDesc.of(mhd.kind(), mhd.owner(), mhd.name
>     <http://mhd.name>(), mhd.lookupType())
> Looks to me like this could be made to work with lookupType() returning
> either of String, TypeDescriptor, or MethodTypeDesc.
> Trying to understand the implications, I have two questions:
> What should the descriptorString overload of MHDesc.of() take e.g. for an
> instance getter?  In MHDesc.of(GETTER, clazz, name, X) the X could be
> one of "(R)T", "()T", or "T".  From my experience with ASM, I assume that
> the field descriptor variant "T" is closest to both constant pool 
> representation
> and lookup.findGetter(), but there seem to be reasons for all three of 
> them.

Currently, we treat it as a method type descriptor string, but you are 
correct, we could accept either, since both are embedded in strings, and 
the two are easily disambiguated (look at the first char).  That would 
be a nice addition.

> Related to this: What is it of benefit in looking at a *field* DMHDesc 
> through
> the lens of a method descriptor/MethodTypeDesc, outside of the point of
> view offered by invocationType()?

Largely, totalizing the factory operation.  We want to be able to take 
apart a DMHD into a tuple (kind, owner, name, desc), and be able to put 
it back together easily.

More information about the amber-dev mailing list