<!DOCTYPE html><html><head>
<meta http-equiv="Content-Type" content="text/html; charset=utf-8">
</head>
<body><div style="font-family: sans-serif;"><div class="markdown" style="white-space: normal;">
<p dir="auto">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.</p>
<p dir="auto">When we employed Q-descriptors, we translated Foo! (or Foo.val) uniformly to /QFoo;/ but now we do something different.</p>
<p dir="auto">Here are assembly sequences that used to employ Q-descriptors but which will have to change:</p>
<p dir="auto">// Foo foo = …; return (Foo!)foo;<br>
(one ref on stack)<br>
checkcast[QFoo;] (if TOS is already LFoo;)<br>
⇒<br>
dup<br>
invokestatic Objects::requireNonNull<br>
pop</p>
<p dir="auto">// (Foo!)obj<br>
(one ref on stack)<br>
checkcast[QFoo;] (otherwise)<br>
⇒<br>
invokestatic Objects::requireNonNull<br>
checkcast[LFoo;]</p>
<p dir="auto">// obj instanceof Foo!<br>
(one ref on stack)<br>
instanceof[QFoo;]<br>
⇒<br>
instanceof[LFoo;] (note that loading is lazier here)</p>
<p dir="auto">// new Foo![dim]<br>
(one int on stack)<br>
anewarray[QFoo;]<br>
⇒<br>
ldc[Condy[Foo.class.asNullRestrictedType]]<br>
swap<br>
invokestatic Array::newInstance(Class,int)<br>
checkcast[[LFoo;] (as necessary)</p>
<p dir="auto">// new Foo![dim0][dim1…]<br>
(#Dim ints on stack)<br>
multianewarray[(‘[’*#Dim)QFoo;,#Dim]<br>
⇒<br>
ldc #Dim (or bipush etc.)<br>
dup; istore $P<br>
newarray[T_INTEGER]<br>
dup2; swap; iinc $P, -1; iload $P; iastore (#Dim times)<br>
invokestatic Array::newInstance(Class,int[])<br>
checkcast[[[…LFoo;] (as necessary)</p>
<p dir="auto">For arrays, generally speaking, we erase Foo![][] to Foo[][], not translating to multi-level /[[…QFoo;/</p>
<p dir="auto">Thus remaining hypothetical uses of /[…QLFoo;/ would get replaced by /[…LFoo;/.</p>
<p dir="auto">For example:</p>
<p dir="auto">multianewarray[(‘[’<em>#Dim)[…QFoo;,#Dim]<br>
⇒<br>
multianewarray[(‘[’</em>#Dim)[…LFoo;,#Dim]</p>
</div></div></body>
</html>