implicit constructor translation?

John Rose john.r.rose at oracle.com
Wed Jun 7 02:29:07 UTC 2023


On 1 Jun 2023, at 11:30, Dan Smith wrote:

>> On Jun 1, 2023, at 10:59 AM, Brian Goetz <brian.goetz at oracle.com> 
>> wrote:
>>
>> I think that there should be an explicit (and not synthetic) 
>> method_info for the implicit constructor, with the obvious Code 
>> attribute (`defaultvalue` / `areturn`.)
>>
>> My rationale is: "the declaration said there's a no-arg constructor, 
>> I should be able to call it".  And that intuition is entirely 
>> reasonable.  Users should be able to say `new Complex()` and get a 
>> default complex value.  (Maybe they can also say `Complex.default`; 
>> maybe we won't need that.)  And the same for reflection.

I like this.  A non-Java language might omit such a method from its 
classfile, or even give it a different body.  (A non-Java language might 
use such a body for some language-specific purpose.  That’s up to the 
translation strategy of that other language.)  For Java, the constructor 
will either not exist or will always have the given two-instruction 
body.  It will never have a body of explicitly user-written statements.

>>
>> Also, in case it is not obvious, the following class is illegal:
>>
>>     value class X {
>>         implicit X();
>>         X() { ... }
>>     }
>>
>> because it is trying to declare the same constructor twice.  An 
>> implicit constructor is a constructor, just one for which the 
>> compiler can deduce specific known semantics.

That all hangs together well.

It allows `new C()` to be a valid expression with a regular translation 
(as a call to <vnew>).  We could “optimize” `new C()` to 
`defaultvalue`, but why bother?  If we keep it as `invokestatic <vnew>` 
then JVMTI has something to work with; you can put breakpoints on the 
implicit constructor.

(No, those breakpoints won’t fire for implicit construction, such as 
in a flat field or array element.  But they will fire for explicit `new 
C()`.)

> Agree with all of this. Some of these details were initially unclear a 
> few weeks ago, but I think we've settled on a design in which the 
> implicit constructor is a "real", invokable constructor, in addition 
> to signaling some metadata about the class.
>
>> On 6/1/2023 10:47 AM, Dan Heidinga wrote:
>>> Alas representing implicit constructors with a `method_info` is not 
>>> without costs: primarily specing how the method_info exists and 
>>> explaining why it doesn't have a code attribute.
>
> There would be nothing special about the <vnew> method. It only exists 
> as a code path for explicit constructor invocations. The "I have a 
> default instance" metadata comes from ImplicitCreation.

Yes.  Except, I’d like to note a subtle issue here:  All value classes 
“have” default values, because the `aconst_default` bytecode works 
for all value classes.  (Otherwise, there would be no primordial value 
to start from in `<vnew>` methods.)

I’d prefer to say this, probably not for the JLS, but for the JVMS:  
For some value types, the default values are private and for some they 
are public.  (There are no intermediate access levels; we tried that and 
it was horrible.)  What the JLS calls a missing default value the JVMS 
calls a private default value.  This is necessary whenever we write 
about translation strategies.  A private default value (invisible in the 
JLS) can have a rather rich career in the bytecodes of the JVMS.

I think I’m on record as saying that both `aconst_default` and 
`withfield` should be private to the nest of the declared value class 
they operate within.  Their use will initially be confined to 
constructors generated statically by a Java translation strategy.  But 
in the future, with “with” statements or serialization frameworks, 
it will be useful to support those instructions at other places in the 
nest, including in dynamically injected nestmates.  The JVM already 
knows how to make privacy checks; we should have the resolution of those 
instructions include the same privacy check, rather than some new ad hoc 
check.

> (Do we expect reflection to reconstruct ImplicitCreation+no-arg <vnew> 
> --> 'Constructor.isImplicit' or 'ACC_IMPLICIT'? Maybe. Not entirely 
> sure yet what the reflection surface will look like.)

Perhaps ACC_MANDATED applies here, to the implicit constructor?  I guess 
not; but it has some of the feel of a mandated parameter, which is not 
present in the code but visible reflectively.

Then again, an implicit constructor *IS* visible in the code, though 
abbreviated.  Kind of like a canonical constructor of a record is 
visible, though abbreviated.

In any case, since Java won’t allow nullary ctors of value types to 
have arbitrary code, it’s a safe bet that if you reflect a value class 
and see a nullary ctor, it’s implicit.  What else could it be?
-------------- next part --------------
An HTML attachment was scrubbed...
URL: <https://mail.openjdk.org/pipermail/valhalla-spec-observers/attachments/20230606/1e6ff7ce/attachment-0001.htm>


More information about the valhalla-spec-observers mailing list