Skip to content

Commit 48c2f77

Browse files
committed
Preserve generic static initializer order
1 parent 94adc34 commit 48c2f77

2 files changed

Lines changed: 13 additions & 5 deletions

File tree

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/translation/imtranslation/EliminateGenerics.java

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -61,6 +61,8 @@ private record RuntimeTypeUse(ImClass clazz, GenericTypes generics) {
6161
// NEW: Track specialized global variables for generic static fields
6262
// Key: (original generic global var, concrete type instantiation) -> specialized var
6363
private final Table<ImVar, GenericTypes, ImVar> specializedGlobals = HashBasedTable.create();
64+
/** Last specialized initializer emitted for each original initializer, preserving discovery order. */
65+
private final Map<ImStmt, ImStmt> specializedInitializerTails = new IdentityHashMap<>();
6466

6567
// NEW: Track which global vars belong to which generic class
6668
// This helps us know which globals need specialization
@@ -2188,10 +2190,14 @@ private void createSpecializedGlobals(ImClass originalClass, GenericTypes generi
21882190
ImLExpr newLeft = specializeLhs.apply(origSet.getLeft());
21892191
ImSet specSet = JassIm.ImSet(originalGlobal.attrTrace(), newLeft, rhs);
21902192

2191-
// schedule insertion right after origSet in its parent ImStmts
2193+
// Append after earlier specializations of this initializer. Each invocation of
2194+
// createSpecializedGlobals has its own insertion batch; always inserting after
2195+
// origSet would therefore reverse specialization discovery/initializer order.
2196+
ImStmt insertionPoint = specializedInitializerTails.getOrDefault(origSet, origSet);
21922197
IdentityHashMap<ImStmt, List<ImStmt>> byStmt =
21932198
insertsByParent.computeIfAbsent(parentStmts, k -> new IdentityHashMap<>());
2194-
byStmt.computeIfAbsent(origSet, k -> new ArrayList<>(1)).add(specSet);
2199+
byStmt.computeIfAbsent(insertionPoint, k -> new ArrayList<>(1)).add(specSet);
2200+
specializedInitializerTails.put(origSet, specSet);
21952201

21962202
// keep prog.getGlobalInits consistent, but do NOT reuse the tree-attached node elsewhere
21972203
specializedInitsForMap.add((ImSet) specSet.copy());

de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/LuaBackendAuditTests.java

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -884,7 +884,7 @@ public void tupleSpecializedStaticKeepsAllLiveInitializers() {
884884
" static function get() returns int",
885885
" return value",
886886
"init",
887-
" if Box<int>.get() + Box<pair>.get() == 3 and Box<int>.get() != Box<pair>.get() and bumps == 2",
887+
" if Box<int>.get() == 1 and Box<pair>.get() == 2 and bumps == 2",
888888
" testSuccess()"
889889
);
890890
}
@@ -902,10 +902,12 @@ public void tupleSpecializedStaticKeepsInitializerForConstructedErasedClass() {
902902
"class Box<T:>",
903903
" static int value = bump()",
904904
" construct()",
905+
" static function get() returns int",
906+
" return value",
905907
"init",
906908
" new Box<int>()",
907909
" new Box<pair>()",
908-
" if bumps == 2",
910+
" if Box<int>.get() == 1 and Box<pair>.get() == 2 and bumps == 2",
909911
" testSuccess()"
910912
);
911913
}
@@ -1046,7 +1048,7 @@ public void eachConstructedErasedInstantiationGetsItsOwnStaticInitializer() {
10461048
"init",
10471049
" new Box<string>()",
10481050
" new Box<real>()",
1049-
" if Box<int>.get() >= 1 and bumps == 3",
1051+
" if Box<string>.get() == 1 and Box<real>.get() == 2 and Box<int>.get() == 3 and bumps == 3",
10501052
" testSuccess()"
10511053
);
10521054
}

0 commit comments

Comments
 (0)