Generate compilable code for non-finite floating-point values

PrimitiveDelegate generated code via "$LF" for Float and "(double) $L"
for Double, which emit the value's toString() verbatim. For NaN and
infinities this produced non-compilable source such as "NaNF" or
"(double) Infinity", causing the generated AOT sources to fail to
compile.

Detect NaN (via isNaN, since NaN is never equal to itself) and the
positive/negative infinities, emitting the corresponding constant
field references (Float.NaN, Double.POSITIVE_INFINITY, etc.) through
the "$T" placeholder. Finite values keep their existing handling.

Signed-off-by: junhyeong9812 <pickjog@gmail.com>
This commit is contained in:
junhyeong9812
2026-09-04 17:23:41 +02:00
committed by Brian Clozel
parent 2b5229ff8f
commit 4a803961bc
2 changed files with 50 additions and 2 deletions
@@ -220,10 +220,28 @@ public abstract class ValueCodeGeneratorDelegates {
if (value instanceof Long) {
return CodeBlock.of("$LL", value);
}
if (value instanceof Float) {
if (value instanceof Float floatValue) {
if (Float.isNaN(floatValue)) {
return CodeBlock.of("$T.NaN", Float.class);
}
if (floatValue == Float.POSITIVE_INFINITY) {
return CodeBlock.of("$T.POSITIVE_INFINITY", Float.class);
}
if (floatValue == Float.NEGATIVE_INFINITY) {
return CodeBlock.of("$T.NEGATIVE_INFINITY", Float.class);
}
return CodeBlock.of("$LF", value);
}
if (value instanceof Double) {
if (value instanceof Double doubleValue) {
if (Double.isNaN(doubleValue)) {
return CodeBlock.of("$T.NaN", Double.class);
}
if (doubleValue == Double.POSITIVE_INFINITY) {
return CodeBlock.of("$T.POSITIVE_INFINITY", Double.class);
}
if (doubleValue == Double.NEGATIVE_INFINITY) {
return CodeBlock.of("$T.NEGATIVE_INFINITY", Double.class);
}
return CodeBlock.of("(double) $L", value);
}
if (value instanceof Character character) {
@@ -157,6 +157,36 @@ class ValueCodeGeneratorTests {
assertThat(generateCode(0.2)).hasToString("(double) 0.2");
}
@Test
void generateWhenFloatNaN() {
assertThat(generateCode(Float.NaN)).hasToString("java.lang.Float.NaN");
}
@Test
void generateWhenFloatPositiveInfinity() {
assertThat(generateCode(Float.POSITIVE_INFINITY)).hasToString("java.lang.Float.POSITIVE_INFINITY");
}
@Test
void generateWhenFloatNegativeInfinity() {
assertThat(generateCode(Float.NEGATIVE_INFINITY)).hasToString("java.lang.Float.NEGATIVE_INFINITY");
}
@Test
void generateWhenDoubleNaN() {
assertThat(generateCode(Double.NaN)).hasToString("java.lang.Double.NaN");
}
@Test
void generateWhenDoublePositiveInfinity() {
assertThat(generateCode(Double.POSITIVE_INFINITY)).hasToString("java.lang.Double.POSITIVE_INFINITY");
}
@Test
void generateWhenDoubleNegativeInfinity() {
assertThat(generateCode(Double.NEGATIVE_INFINITY)).hasToString("java.lang.Double.NEGATIVE_INFINITY");
}
@Test
void generateWhenChar() {
assertThat(generateCode('a')).hasToString("'a'");