Skip to content

Commit f402860

Browse files
committed
fix RHS
1 parent 925657d commit f402860

2 files changed

Lines changed: 52 additions & 0 deletions

File tree

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/intermediatelang/optimizer/DispatchCheckDeduplicator.java

Lines changed: 18 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -95,6 +95,9 @@ private boolean invalidatesGuard(ImStmt s, GuardPattern guard) {
9595
if (s instanceof ImSet) {
9696
ImSet set = (ImSet) s;
9797
ImLExpr left = set.getLeft();
98+
if (mayWriteTypeIdFromElement(set.getRight(), guard.failedCond.typeIdVar)) {
99+
return true;
100+
}
98101
if (left instanceof ImVarAccess) {
99102
ImVar v = ((ImVarAccess) left).getVar();
100103
return v == guard.failedCond.receiverVar || v == guard.failedCond.typeIdVar;
@@ -127,6 +130,21 @@ private boolean invalidatesGuard(ImStmt s, GuardPattern guard) {
127130
return false;
128131
}
129132

133+
private boolean mayWriteTypeIdFromElement(Element elem, ImVar typeIdVar) {
134+
if (elem == null) {
135+
return false;
136+
}
137+
if (sideEffectAnalyzer.directlySetVariables(elem).contains(typeIdVar)) {
138+
return true;
139+
}
140+
for (ImFunction called : sideEffectAnalyzer.calledFunctions(elem)) {
141+
if (mayWriteTypeId(called, typeIdVar)) {
142+
return true;
143+
}
144+
}
145+
return false;
146+
}
147+
130148
private boolean mayWriteTypeId(ImFunction f, ImVar typeIdVar) {
131149
if (f == null) {
132150
return true;

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

Lines changed: 34 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -136,6 +136,40 @@ public void repeatedCallsOnSameReceiverAreNotDispatchCachedYet() throws IOExcept
136136
"Expected inlopt output to contain a single dispatch guard, found " + inlOptGuardCount);
137137
}
138138

139+
@Test
140+
public void dispatchGuardNotDedupedAcrossRhsSideEffects() throws IOException {
141+
testAssertOkLines(false,
142+
"package test",
143+
" native testSuccess()",
144+
" class A",
145+
" function bar() returns int",
146+
" return 1",
147+
"",
148+
" function mutatingRhs(A a) returns int",
149+
" destroy a",
150+
" return 0",
151+
"",
152+
" function useA(A a) returns int",
153+
" int r = 0",
154+
" r += a.bar()",
155+
" r = mutatingRhs(a)",
156+
" r += a.bar()",
157+
" return r",
158+
"",
159+
" init",
160+
" let a = new A",
161+
" useA(a)",
162+
" testSuccess()",
163+
"endpackage"
164+
);
165+
166+
File inlOptOut = new File(TEST_OUTPUT_PATH + "ClassesTests_dispatchGuardNotDedupedAcrossRhsSideEffects_inlopt.j");
167+
String inlOpt = Files.readString(inlOptOut.toPath(), StandardCharsets.UTF_8);
168+
int inlOptGuardCount = countOccurrences(inlOpt, "if A_typeId[a] == 0 then");
169+
assertTrue(inlOptGuardCount >= 2,
170+
"Expected inlopt output to keep separate guards across mutating RHS call, found " + inlOptGuardCount);
171+
}
172+
139173
private static int countOccurrences(String text, String needle) {
140174
int c = 0;
141175
int i = 0;

0 commit comments

Comments
 (0)