Skip to content

Commit dc16680

Browse files
committed
Booleans should be zero.
1 parent 5abd15b commit dc16680

2 files changed

Lines changed: 78 additions & 8 deletions

File tree

‎src/main/java/org/ikvm/javarefplugin/MethodBodyStripper.java‎

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -57,28 +57,23 @@ private List<JCTree.JCStatement> generateDefaultStaticFieldAssignments(JCTree.JC
5757
return statements.toList();
5858
}
5959

60-
// Assign default values to static fields WITHOUT initializers:
61-
// 1. static non-final fields without initializers
62-
// 2. static final fields without initializers (must assign in static {} block)
63-
// Do NOT assign to any static fields that already have initializers
60+
// Assign defaults to static fields without initializers.
61+
// Skip fields that have initializers - they are already assigned and shouldn't be reassigned.
6462
for (JCTree def : classTree.defs) {
6563
if (def instanceof JCTree.JCVariableDecl) {
6664
JCTree.JCVariableDecl varDecl = (JCTree.JCVariableDecl) def;
6765
boolean isStatic = (varDecl.mods.flags & Flags.STATIC) != 0;
6866

69-
// Only process static fields
7067
if (!isStatic) {
7168
continue;
7269
}
7370

7471
boolean hasInitializer = varDecl.init != null;
7572

76-
// Skip any field that already has an initializer
7773
if (hasInitializer) {
7874
continue;
7975
}
8076

81-
// Assign default to static fields without initializers
8277
JCTree.JCExpression defaultValue = generateDefaultValue(varDecl.vartype);
8378
JCTree.JCAssign assignment = maker.Assign(
8479
maker.Ident(varDecl.name),
@@ -98,7 +93,8 @@ private JCTree.JCExpression generateDefaultValue(JCTree.JCExpression typeExpr) {
9893
|| "float".equals(typeStr) || "double".equals(typeStr)) {
9994
return maker.Literal(TypeTag.INT, 0);
10095
} else if ("boolean".equals(typeStr)) {
101-
return maker.Literal(TypeTag.BOOLEAN, Boolean.FALSE);
96+
// javac expects boolean literals as numeric payload (0/1) for TypeTag.BOOLEAN
97+
return maker.Literal(TypeTag.BOOLEAN, 0);
10298
} else if ("char".equals(typeStr)) {
10399
return maker.Literal(TypeTag.CHAR, 0);
104100
}

‎src/test/java/org/ikvm/javarefplugin/JavaRefPluginTest.java‎

Lines changed: 74 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,7 @@
11
package org.ikvm.javarefplugin;
22

33
import static org.junit.jupiter.api.Assertions.assertEquals;
4+
import static org.junit.jupiter.api.Assertions.assertFalse;
45
import static org.junit.jupiter.api.Assertions.assertNotNull;
56
import static org.junit.jupiter.api.Assertions.assertThrows;
67
import static org.junit.jupiter.api.Assertions.assertTrue;
@@ -481,4 +482,77 @@ void staticInitializerOptimizationHandlesAllFieldTypes() throws Exception {
481482
assertTrue(mutableFailure.getCause() instanceof NullPointerException);
482483
}
483484

485+
@Test
486+
void staticFieldsAllCombinations() throws Exception {
487+
Map<String, String> sources = new LinkedHashMap<>();
488+
sources.put(
489+
"example/AllStaticFields.java",
490+
joinLines(
491+
"package example;",
492+
"",
493+
"public class AllStaticFields {",
494+
" // static final WITH initializer - should NOT be reassigned",
495+
" static final long WITH_INIT_FINAL = 42L;",
496+
"",
497+
" // static final WITHOUT initializer - MUST be assigned",
498+
" static final String WITHOUT_INIT_FINAL;",
499+
"",
500+
" // static non-final WITH initializer - should NOT be reassigned?",
501+
" static int WITH_INIT_MUTABLE = 100;",
502+
"",
503+
" // static non-final WITHOUT initializer - should be assigned to 0",
504+
" static int WITHOUT_INIT_MUTABLE;",
505+
"",
506+
" static {",
507+
" WITHOUT_INIT_FINAL = \"initialized\";",
508+
" WITHOUT_INIT_MUTABLE = 200;",
509+
" }",
510+
"",
511+
" public static void dummy() { }",
512+
"}"
513+
)
514+
);
515+
516+
// Just verify the plugin can compile this without errors
517+
CompilationResult result = compile(sources);
518+
assertNotNull(result.loadClass("example.AllStaticFields"));
519+
}
520+
521+
@Test
522+
void staticBooleanFieldsCombinationsAreHandled() throws Exception {
523+
Map<String, String> sources = new LinkedHashMap<>();
524+
sources.put(
525+
"example/StaticBooleanFields.java",
526+
joinLines(
527+
"package example;",
528+
"",
529+
"public class StaticBooleanFields {",
530+
" static final boolean WITH_INIT_FINAL = true;",
531+
" static final boolean WITHOUT_INIT_FINAL;",
532+
" static boolean WITH_INIT_MUTABLE = true;",
533+
" static boolean WITHOUT_INIT_MUTABLE;",
534+
"",
535+
" static {",
536+
" WITHOUT_INIT_FINAL = true;",
537+
" WITHOUT_INIT_MUTABLE = true;",
538+
" }",
539+
"}"
540+
)
541+
);
542+
543+
CompilationResult result = compile(sources);
544+
Class<?> type = result.loadClass("example.StaticBooleanFields");
545+
546+
assertTrue(getStaticBoolean(type, "WITH_INIT_FINAL"));
547+
assertFalse(getStaticBoolean(type, "WITHOUT_INIT_FINAL"));
548+
assertTrue(getStaticBoolean(type, "WITH_INIT_MUTABLE"));
549+
assertFalse(getStaticBoolean(type, "WITHOUT_INIT_MUTABLE"));
550+
}
551+
552+
private static boolean getStaticBoolean(Class<?> type, String fieldName) throws Exception {
553+
java.lang.reflect.Field field = type.getDeclaredField(fieldName);
554+
field.setAccessible(true);
555+
return field.getBoolean(null);
556+
}
557+
484558
}

0 commit comments

Comments
 (0)