Thanks for the review and the great comments!

This version is far better than the previous one,

... or the previous seven :)

MethodHandleDesc.Kind: The JVMS defines names for these constants, why using 
different names here ?

Mostly for readability of client code.  Happy to consider alternatives.

ClassDesc.isClassOrInterface() seems very specific, does it includes annotation 
or enums, how will it works when value types will be included ?

Hah, this was added based on a previous review, where someone said "you have isArray() and isPrimitive(), but there are methods that only work on non-array, non-primitive (e.g., packageName()), so you should have a corresponding method for this, and then the isXxx methods partition the space."  After some bikeshed painting, So isClassOrInterface(), which means "not array, not primitive", seemed the best choice.   (The VM sees enums as classes and annotations as interfaces, and this is essentially a VM interop API.)  For value types, value types will be classes ("codes like a class!") so they will be included by this method.

We could have call this isClassWhoseDescriptorStartsWithL() but that seemed a bit less friendly, though that's basically the intent.

it seems to be defined as !isPrimitive() and !isArray(), in that case, i think 
it can be removed.

Tried that, see above :)

EnumDesc and VarHandleDesc, those should be static inner classes of 
respectively Enum and VarHandle,
they are not part of the main API but nice addons.

Good thought!  Will consider this (need to work through some of the other specializations we intend to add, to make sure this scales properly.)

DynamicCallSiteDesc is not a Desc (a ConstantDesc), so the name is very 
confusing.

It's not a ConstantDesc, but it _is_ a nominal descriptor.  Just not a nominal descriptor for a (loadable) constant.  The confusing bit is that its the only one of its kind, for now; later, I think this will become more common.  (If we had descriptors for the non-loadable constants in the CP (e.g., NameAndType), they'd be in this boat too.)


DynamicConstantDesc, it's not clear to me why this is not an interface like 
ClassDesc or MethodHandleDesc
Fair question; we went back and forth on this a few times.  It could be shredded into a pair like ClassDesc/ConstantClassDesc.  However, in reality, we expect that all implementations of DCD would want to extend the base implementation anyway, since it provides useful functionality for which there's no point in reinventing.  Which means really DCD/ConstantDCD/AbstractDCD.  Which is starting to seem a little silly?   But I agree that things are a bit all over the map here.  (This is in part due to trying to cover the seam between primitive and reference class mirrors with a single abstraction, because the alternative is far worse.)

For ConstantClassDesc, ConstantMethodTypeDesc, ConstantMethodHandleDesc, do we 
really need to make these classes public, in theory they should not have a 
proper name because they have the same API as there interface counter parts and 
it will be easier to retrofit them as value type if there are not part of the 
public APIs. By doing that, i believe that FieldDescriptor and TypeDescriptor 
will not need to be generics anymore.

The reason these were made public is that we expect bytecode APIs to case over them.  If you're writing out an LDC based on a ConstantDesc, you can case over: String, Integer (and friends), Constant{Class,MT,MH}Desc, DynamicConstantDesc -- which are the concrete types that correspond exactly to the loadable CP types defined in JVMS -- and you're done.  If we made ConstantMHDesc private, the API gets more complicated, because now there are a bunch of methods that only work on direct method handles.

It seems that java.lang.invoke.Intrinsics has disappear (at least from the 
javadoc).

We split JEP 334 off from 303; Intrinsics remains in 303, and will come later.  This is the foundation.

Constable.describeConstable() is weirdly named, does asConstantDesc better ?

Yeah, we had quite a loooooong discussion on this...suffice it to say we considered every possible option, and then some.  The basic challenge is that ConstantDesc implements Constable, and code like

    constantDesc.asConstantDesc()

would totally look like a no-op -- but it's not!  It's asking the constantDesc to _describe itself_ as a constantDesc.  So calling it

    constantDesc.describeConstable()

is more clearly asking a Constable to describe itself.

Some implementation of Constable do not have the return type of describeConstable 
being tidy up (i.e. the return type uses the Optional<? ...> instead of a more 
specific one).

I'll take a look at these.  Some are trickier than they look.

I really dislike the fact that there is a method describeConstable in 
java.lang.Enum. Given the number of people that are interested by 
describeConstable(), i think this interface should be removed and static 
methods should be used instead. And fundamentally, i do not like the fact that 
you can go from a live object to its ConstantDesc representation, people will 
abuse of that like currently we use a java.lang.Class instead of a ClassDesc. 
This API, for me, goes in the wrong direction and pollute too many classes.

Yeah, this is a sharp edge.  But there's also a reason for it; it enables the compiler to much more aggressively constant-fold things into condy.

The problem is not the method, or the mechanism -- the mechanism is awesome.  The problem is that this is a very low-level method bleeding into the Javadoc of some high-level things, which is sure to confuse users.  (We have the same problem with the two new methods on String -- describeConstable and resolveConstantDesc. Both are kind of silly on String, since they are basically identities.  In fact, the reason these methods are named so oddly is because they are going to show up in the API of some very general classes, like String.)


Reply via email to