On 2 Jul 2022, at 20:24, John Rose wrote:
…
http://cr.openjdk.java.net/~jrose/values/encapsulating-val.md
http://cr.openjdk.java.net/~jrose/values/encapsulating-val.html
On 3 Jul 2022, at 5:25, Remi Forax wrote:
…
One kind of sad thing with CONSTANT\_Class QC; is that we need it now
but once we will have the new generics, we will not need it anymore
because it can be express with a CONSTANT\_Specialization\_Linkage + a
constant dynamic. So it's a kind of temporary design.
That’s probably true. But (like you?) I think this “sad thing” is
too hard to avoid. One consolation: The existing descriptor syntax for
a CONSTANT\_Class of an *array type* is much older sad thing of the same
type. The two sad things can keep each other company in a corner of the
JVMS.
I wonder if it's not "better" to separate checkcast from unbox/box
given that mixing them together result in different resolution for all
checkcasts (compare to anewarray). From the language POV, those two
kind of checkcasts are different anyway.
But from the JVM POV lumping behaviors into bytecodes is a much better
move, than splitting them out into separate new bytecodes, when the
lumping makes any sense at all. And in this case it does.
On 4 Jul 2022, at 6:45, Dan Heidinga wrote:
Sorry for top-posting but it was easier to track a list of issues as I
read through:
I actually prefer the top-posting, and the markdown is kind of a mess,
so you don’t need to apologize. :-)
* Miscellaneous privatization checks
--> MethodHandle.asType(MT) and MethodHandle.invoke() will also need
to protect against the zero being introduced.
…Here we see invoke() converting a void to a reference (null) and
similarly for a primitive, to zero. Both these apis will need similar
treatment as ::explictCastArguments.
Good catch. I see you still remember your JSR 292 details. Fixed.
Serialization
--> There's a mention of serialization but if Lambda taught us
anything, it's that serialization requires more thought than we
expected, even if we take that into account =) We should spend some
time on what serialization of a C.val actually means, any format
concerns, and how it interacts with default reconstitution behaviours.
Otherwise, we'll leave a hole here where unconstructed values can be
deserialized.
Added this:
Reconstruction operations defined outside of `C` must be designed
with
great care if they use elevated privileges beyond what `C` provides
directly. Given the historically tricky nature of deserialization,
more work is needed to consider what serialization of a C.val
actually
means and how it interacts with default reconstitution behaviours.
One likely possibility is that wire formats should only work with
`C.ref` types with proper construction paths (enforced by
serialization),
and leave conversion to `C.val` types to deserialization code inside
the encapsulation of `C`.
C.default & Reflection
--> Is "default" a reflectively accessible field or compiler sugar?
If a user does C.val.class.getDeclaredFields will it find "default"?
Or maybe C.class.getDeclaredFields? I'm fine with it being a fiction
but I wasn't clear how far we were pushing that into the reflective
model as well. I think the intent is to expose this with
Class::defaultValue / Lookup::defaultValue APIs but clarification
would be good.
Accessing C.val.class
--> Do we need restrictions here beyond those of accessing C.class?
Those restrictions are a paper tiger, as I think I’ve proven. My
recommendation is to have a second paper tiger on `C.val.class` as well.
This consistency has a specific goal, to help users learn more quickly
how access control of `C.val` works, giving them direct experience with
it via the `C.val.class` syntax.
The mirror may be required to create MethodTypes for use in
MethodHandle lookup().find* apis even by code that can't create a
C.val. Given that it will leak already as shown in the doc, do we
need the extra restrictions?
It’s a paper tiger, but an educational one.