<html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body>
<br>
<br>
<div class="moz-cite-prefix">On 6/14/2022 2:54 PM, Dan Heidinga
wrote:<br>
</div>
<blockquote type="cite" cite="mid:CAJq4Gi7S8fZ2+NHybQuUp6y7Ji=nD7ppCqC4M+zHCrh=rxCgrQ@mail.gmail.com">
<blockquote type="cite" style="color: #007cff;">
<pre class="moz-quote-pre" wrap="">But (and there's a whole conversation to be had here) it does mean that
there is separate access control on LFoo vs QFoo,
</pre>
</blockquote>
<pre class="moz-quote-pre" wrap="">Pulling on this thread a little, is it the class that has different
access control or something else?</pre>
</blockquote>
<br>
We've meandered a bit over the years on the distinction between the
class Foo, the types Foo.ref and Foo.val, and their respective
mirrors. It's probably time for a check-in on where we are there.
<br>
<br>
Today, Integer is a class, with a full-power mirror Integer.class;
int is a type, with a limited mirror int.class, whose job is mostly
limited to reflecting over field and method descriptors. <br>
<br>
With Valhalla, Point is a class, with types Point.ref and Point.val;
Point.class is a full-power mirror for Point.ref, and
Point.val.class is a limited mirror that is analogous to the int
mirror. If you ask a Point for its getClass(), it always returns
Point.class. It would not bother me if the Point.val.class mirror
is fully limited, and the only way to do lookups (e.g., getMethods)
is to switch over to the class mirror (for which we'd probably have
a `Class::getPrimaryClass` method.) <br>
<br>
Having the two encode separate accessibilities sounds a little
messy, but the various Lookup::checkAccess methods key off of a
Class, so that seems a reasonable place to hang this information. I
would assume such checks would check both the primary class and then
the secondary class, or we'd arrange that the primary mirror always
was at least as accessible as the secondary mirror. (Protected
isn't a useful option, and public/package/private are suitably
ordered.) <br>
<br>
At the language level, there is a question about how to present the
val class. One obvious (but possibly bad) idea is to pretend it is
a special kind of nested class (which is supported by the Point.val
naming convention):<br>
<br>
value class Rational { <br>
private class val { }<br>
}<br>
<br>
This is a little cheesy, but may fit mostly cleanly into user's
mental models. In this case, the accessibility is going on
something that looks like a class declaration at the source level,
and which has a class mirror at the VM level, but it really a
"shadow class", just like the class described by int.class (or
String[].class.) This might be OK. <br>
<br>
At one point I considered whether we could hang this on the
accessibility of the no-arg constructor, but I quickly soured on
this idea. But that has an accessibility too. <br>
<br>
Or we could invent a new kind of member, to describe the val
projection, and hang accessibility on that. <br>
<br>
<blockquote type="cite" cite="mid:CAJq4Gi7S8fZ2+NHybQuUp6y7Ji=nD7ppCqC4M+zHCrh=rxCgrQ@mail.gmail.com">
<pre class="moz-quote-pre" wrap="">To create an identity object, we do access control on the both class
(public/package) and the constructor (public/package/private (aka
nest)).
To create a value object, we do nest mate access control (aka private)
on the bytecodes that create values (aconst_init / withfield). This
proposal extends the nest mates access check to the default values of
Qs.</pre>
</blockquote>
<br>
It's not just nestmate access control; it would be reasonable to
declare the val as package-access, and trust your package mates
too. <br>
<br>
<blockquote type="cite" cite="mid:CAJq4Gi7S8fZ2+NHybQuUp6y7Ji=nD7ppCqC4M+zHCrh=rxCgrQ@mail.gmail.com">
<pre class="moz-quote-pre" wrap="">In both cases, we're looking at the access control of two things - the
class and the "creator of instances". Are we applying different
access control to LFoo vs QFoo, or to construction mechanisms?</pre>
</blockquote>
<br>
The thing we're trying to protect is creation of uninitialized
heap-based instances. But it felt a little weird to draw such a
complex line; seemed simpler (and not giving up much) to
access-control the type name. But we can explore this some more.
Maybe we are access-controlling the `defaultvalue` bytecode, since
its effectively public if someone can create a flat array. <br>
<br>
<br>
</body>
</html>