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