Here’s a bit of “translation strategy lore” that doesn’t need to go into the JEP, but I think might be useful to contemplate.

When we employed Q-descriptors, we translated Foo! (or Foo.val) uniformly to /QFoo;/ but now we do something different.

Here are assembly sequences that used to employ Q-descriptors but which will have to change:

// Foo foo = …; return (Foo!)foo;
(one ref on stack)
checkcast[QFoo;]  (if TOS is already LFoo;)
  ⇒
dup
invokestatic Objects::requireNonNull
pop

// (Foo!)obj
(one ref on stack)
checkcast[QFoo;]  (otherwise)
  ⇒
invokestatic Objects::requireNonNull
checkcast[LFoo;]

// obj instanceof Foo!
(one ref on stack)
instanceof[QFoo;]
  ⇒
instanceof[LFoo;]  (note that loading is lazier here)

// new Foo![dim]
(one int on stack)
anewarray[QFoo;]
  ⇒
ldc[Condy[Foo.class.asNullRestrictedType]]
swap
invokestatic Array::newInstance(Class,int)
checkcast[[LFoo;]  (as necessary)

// new Foo![dim0][dim1…]
(#Dim ints on stack)
multianewarray[(‘[’*#Dim)QFoo;,#Dim]
  ⇒
ldc #Dim  (or bipush etc.)
dup; istore $P
newarray[T_INTEGER]
dup2; swap; iinc $P, -1; iload $P; iastore  (#Dim times)
invokestatic Array::newInstance(Class,int[])
checkcast[[[…LFoo;]  (as necessary)

For arrays, generally speaking, we erase Foo![][] to Foo[][], not translating to multi-level /[[…QFoo;/

Thus remaining hypothetical uses of /[…QLFoo;/ would get replaced by /[…LFoo;/.

For example:

multianewarray[(‘[’*#Dim)[…QFoo;,#Dim]
  ⇒
multianewarray[(‘[’*#Dim)[…LFoo;,#Dim]

Reply via email to