<div dir="ltr">I just started to move my most recent Clojure compiler iteration to<br>the Classfile API.  It is a pleasure to use.  I appreciate the huge<br>amount of work that is going into this.<br><br>While going through my constant handling tests I found three issues.<br><div><br></div><div>First, I expected ConstantDescs.NULL to be mapped to ACONST_NULL.  I<br>can just as well special case this in the compiler, of course.<br><br>Second, to get a test case for the literal constant -0.0 to round-trip<br>I had to patch CodeBuilder.java to go via LDC:<br><br>   cause: expected not equivalent to actual value<br>expected: [(LDC2_W   -0.0) (DRETURN)]<br>  actual: [(DCONST_0     ) (DRETURN)]<br><br>Third, a round-trip involving the describeConstable() of a Character<br>instance (via ConstantDescs.BSM_EXPLICIT_CAST) was read back as a DCD<br>with a nameAndType of "_":"LC;" instead of the expected "_":"C".<br>Changing the ofCanonical invocation in ConcreteEntry.java fixed this<br>particular case for me, but I am only fishing around here.<br></div><div><br></div><div>The patch below has more details.</div><div><br></div><div>-- mva</div><div><br></div><div><br></div><div>diff --git a/src/java.base/share/classes/jdk/classfile/CodeBuilder.java b/src/java.base/share/classes/jdk/classfile/CodeBuilder.java<br>index 154050ae8b4..330980af725 100755<br>--- a/src/java.base/share/classes/jdk/classfile/CodeBuilder.java<br>+++ b/src/java.base/share/classes/jdk/classfile/CodeBuilder.java<br>@@ -27,6 +27,7 @@ package jdk.classfile;<br> <br> import java.lang.constant.ClassDesc;<br> import java.lang.constant.ConstantDesc;<br>+import java.lang.constant.ConstantDescs;<br> import java.lang.constant.DirectMethodHandleDesc;<br> import java.lang.constant.DynamicCallSiteDesc;<br> import java.lang.constant.MethodTypeDesc;<br>@@ -424,7 +425,7 @@ public sealed interface CodeBuilder<br> <br>     default CodeBuilder constantInstruction(ConstantDesc value) {<br>         // This method must ensure any call to constant(Opcode, ConstantDesc) has a non-null Opcode.<br>-        if (value == null) {<br>+        if (value == null || ConstantDescs.NULL.equals(value)) {<br>             return constantInstruction(Opcode.ACONST_NULL, null);<br>         }<br>         else if (value instanceof Integer iVal) {<br>@@ -437,16 +438,16 @@ public sealed interface CodeBuilder<br>             else<br>                 return constantInstruction(Opcode.LDC2_W, lVal);<br>         } else if (value instanceof Float fVal) {<br>-            if (fVal == 0.0)<br>+            if (fVal.compareTo(0.0f) == 0) // 0.0f but not -0.0f<br>                 return with(ConstantInstruction.ofIntrinsic(Opcode.FCONST_0));<br>-            else if (fVal == 1.0)<br>+            else if (fVal == 1.0f)<br>                 return with(ConstantInstruction.ofIntrinsic(Opcode.FCONST_1));<br>-            else if (fVal == 2.0)<br>+            else if (fVal == 2.0f)<br>                 return with(ConstantInstruction.ofIntrinsic(Opcode.FCONST_2));<br>             else<br>                 return constantInstruction(Opcode.LDC, fVal);<br>         } else if (value instanceof Double dVal) {<br>-            if (dVal == 0.0d)<br>+            if (dVal.compareTo(0.0d) == 0) // 0.0d but not -0.0d<br>                 return with(ConstantInstruction.ofIntrinsic(Opcode.DCONST_0));<br>             else if (dVal == 1.0d)<br>                 return with(ConstantInstruction.ofIntrinsic(Opcode.DCONST_1));<br>diff --git a/src/java.base/share/classes/jdk/classfile/impl/ConcreteEntry.java b/src/java.base/share/classes/jdk/classfile/impl/ConcreteEntry.java<br>index bead58d7618..9dcc8eeb7e1 100755<br>--- a/src/java.base/share/classes/jdk/classfile/impl/ConcreteEntry.java<br>+++ b/src/java.base/share/classes/jdk/classfile/impl/ConcreteEntry.java<br>@@ -797,7 +797,7 @@ public abstract sealed class ConcreteEntry {<br>                 staticArgs[i] = args.get(i).constantValue();<br> <br>             return DynamicConstantDesc.ofCanonical(bootstrap().bootstrapMethod().asSymbol(),<br>-                                                   nameAndType().name().stringValue(), ClassDesc.of(Util.toClassString(Util.descriptorToClass(nameAndType().type().stringValue()))), staticArgs);<br>+                                                   nameAndType().name().stringValue(), ClassDesc.ofDescriptor(nameAndType().type().stringValue()), staticArgs);<br>         }<br>     }<br> <br></div></div>