Moving from VVT to the L-world value types (LWVT)

Ali Ebrahimi ali.ebrahimi1781 at gmail.com
Wed Feb 21 05:13:40 UTC 2018


Hi,
Why not have new NonNullable marker interface for marking (new/legacy)
value types. We can have nullable and non-nullable types.
New (true) value types can implements NonNullable interface by default. By
this we can support non-nullable reference types later if want.

On Wed, Feb 21, 2018 at 6:18 AM, John Rose <john.r.rose at oracle.com> wrote:

> On Feb 12, 2018, at 11:12 AM, John Rose <john.r.rose at oracle.com> wrote:
> >
> > On Feb 12, 2018, at 8:53 AM, Srikanth <srikanth.adayapalam at oracle.com>
> wrote:
> >>
> >> Hi Frederic,
> >>
> >> A couple of follow up questions below:
> >>
> >> On Monday 12 February 2018 10:02 PM, Frederic Parain wrote:
> >>
> >> [...]
> >>> The current design allows null references for value types, as long as
> they are not stored
> >>> in a container (field or array) declared as flattenable. This is a
> significant change from
> >>> previous design. So, casting null to a value class type is now legal.
> >>
> >> OK.  This does not call for any change to the specification of
> checkcast in JVMS ?
> >> (I don't know that it does - Just double checking)
> >
> > There might be an option here:  Maybe we could get away with having
> checkcast
> > throw NPE if the target class is a value type.  After all, the checkcast
> instruction resolves
> > its class operand.  Remember that we *must* allow polluting nulls in
> fields which
> > are not explicitly marked as flat, but *only* because of binary
> compatibility requirements.
> > We *do not* allow polluting nulls to be stored into arrays, because
> arrays *must*
> > resolve their element types before the first array is constructed.  I
> think we could
> > put checkcast into either of these two categories:  Allowing polluting
> nulls for
> > compatibility, or forbidding them (throwing NPE).
> >
> > Hmm…  The more aggressive choice (throwing NPE on checkcast) would make
> would
> > prevent instances of generic code (such as List<DoubleComplex>) from
> accepting
> > nulls:
> >
> >  List<DoubleComplex> xs = new ArrayList<>();
> >  xs.add(null);  // to NPE or not to NPE?
> >
> > This is not really a JVM question, but a language question:  Should
> > the above code throw NPE if freshly recompiled?  Yes, probably.
> > What if it is inside a legacy classfile, and is not freshly recompiled?
> > It would break if it threw NPE.  This argues for two slightly different
> > versions of checkcast.  Argh:  An option turns into a two-sided mandate.
> > The checkcast might need a flat-bit.  (Stay away, you Q-types.)
> > Or the checkcast could throw NPE only in newer classfile versions.
> >
> > These considerations also apply to Class::cast.
>
> I thought about this some more, and talked briefly with Brian, and
> here's where I think we should come out:
>
> In new source code it will always be illegal to cast a null to a value
> type.
> The rule for values is, "codes like a class, works like an int". If you
> cast
> a null to (int) you get an NPE. That's what the language needs to do.
> It doesn't matter what the JVM does.
>
> There are two exceptions to this reasoning: Explicit nullability, or
> legacy compilation. If we were to *add* a new feature which allowed
> a type to be nullable, then types which had this nullable aspect
> could be the target of a cast, without a null check, and the JVM
> would process the null appropriately. It would have to use an
> L-type descriptor for the value, of course. But we are not doing
> this at present.
>
> If javac is compiling for legacy code (say, with the experimental
> features turned off) then it should not "notice" class files which
> are defined as value types (or non-nullable types, if we add this
> feature at some point). In that case, *no* null checks should be
> inserted, since that would be incompatible with old code.
>
> To summarize: javac should arrange a null check when it emits a cast
> to a type which is statically known to be a value type, if it is compiling
> at a source level which recognizes value types as such.
>
> Since reflective calls are used by both old and new bytecodes,
> adding a null checks for value-types is not an option for Class::cast.
> Probably we need a new API point, Class::castValue, which senses
> a value type and adds a null check in that case. For reference types,
> the behavior of Class::castValue would be the same as Class::cast.
>
> At the JVM level, we should consider making checkcast incorporate
> a null check, in the case where (a) the class resolves to a value type,
> and (b) the classfile version supports value types. In this way,
> legacy classfile code will continue to be sloppy with nulls, but new
> code will not. Users who need to cast to a value type *without*
> the null check can use Class::cast or some other API point which
> guarantees to allow "polluting" nulls to pass through.
>
> To be clear:  If a classfile contains a checkcast that refers to a
> value type, *and* if the classfile's version number (or other markings)
> allows it to process value types (say, withfield is also allowed),
> *then* the semanatics of the checkcast *should* include a null
> check, even though (for compatibility reasons in old code) the
> JVM would allow a null under the same descriptor.
>
> I admit that giving checkcast a different behavior in different
> classfile versions is odd, and as a temporary fallback it might
> be better to ask javac to insert explicit null checks before
> such checkcasts.
>
>


-- 

Best Regards,
Ali Ebrahimi


More information about the valhalla-dev mailing list