[jep-334] Asymmetric method types of MHD vs MH
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
> 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
> - MHDesc has no method called type(), but instead has
> 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"
> "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
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:
Yes, for a method or ctor, its what you pass to this. But for a field,
> 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
> and lookup.findGetter(), but there seem to be reasons for all three of
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
> 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