Skip to content

Commit 1980274

Browse files
authored
Keep tuple vararg loop bindings rooted through lowering (#1269)
* Keep lowered vararg tuple locals rooted * Run compiler fuzz tests in the SmallCheck JUnit suite * Fix compiler fuzz suite execution
1 parent aa986c6 commit 1980274

18 files changed

Lines changed: 475 additions & 22 deletions

File tree

de.peeeq.wurstscript/parserspec/jass_im.parseq

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -74,6 +74,9 @@ ImMethod(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace,
7474

7575

7676
ImStmts * ImStmt
77+
ImVarargLoopVars * ImVarargLoopVar
78+
79+
ImVarargLoopVar(ref ImVar var)
7780

7881
ImStmt =
7982
ImIf(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ImExpr condition, ImStmts thenBlock, ImStmts elseBlock)
@@ -82,7 +85,7 @@ ImStmt =
8285
| ImReturn(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ImExprOpt returnValue)
8386
| ImSet(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ImLExpr left, ImExpr right)
8487
| ImExpr
85-
| ImVarargLoop(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ImStmts body, ref ImVar loopVar)
88+
| ImVarargLoop(@ignoreForEquality de.peeeq.wurstscript.ast.Element trace, ImStmts body, ImVarargLoopVars loopVars)
8689

8790

8891
ImExprOpt =

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/intermediatelang/interpreter/RunStatement.java

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,6 @@
11
package de.peeeq.wurstscript.intermediatelang.interpreter;
22

3+
import com.google.common.base.Preconditions;
34
import de.peeeq.wurstio.jassinterpreter.InterpreterException;
45
import de.peeeq.wurstio.jassinterpreter.VarargArray;
56
import de.peeeq.wurstscript.intermediatelang.ILaddress;
@@ -72,11 +73,13 @@ public static void run(ImStmts stmts, ProgramState globalState, LocalState local
7273

7374

7475
public static void run(ImVarargLoop loop, ProgramState globalState, LocalState localState) {
76+
Preconditions.checkState(loop.getLoopVars().size() == 1,
77+
"Expected one vararg loop variable in the interpreter.");
7578
ImFunction func = loop.getNearestFunc();
7679
ImVar varargParam = func.getParameters().get(func.getParameters().size() - 1);
7780
VarargArray val = (VarargArray) localState.getVal(varargParam);
7881
for (int i = 0; i < val.size(); i++) {
79-
localState.setVal(loop.getLoopVar(), val.get(i));
82+
localState.setVal(loop.getLoopVars().get(0).getVar(), val.get(i));
8083
loop.getBody().runStatements(globalState, localState);
8184
}
8285
}

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

Lines changed: 8 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -110,8 +110,10 @@ private static void applyMerges(ImFunction func, Map<ImVar, ImVar> merges) {
110110
}
111111
@Override public void visit(ImVarargLoop varargLoop) {
112112
super.visit(varargLoop);
113-
ImVar m = merges.get(varargLoop.getLoopVar());
114-
if (m != null) varargLoop.setLoopVar(m);
113+
for (ImVarargLoopVar loopVar : varargLoop.getLoopVars()) {
114+
ImVar m = merges.get(loopVar.getVar());
115+
if (m != null) loopVar.setVar(m);
116+
}
115117
}
116118
});
117119
}
@@ -123,6 +125,10 @@ private static int removeUnusedLocals(ImFunction f) {
123125
@Override public void visit(ImVarAccess va) { super.visit(va); used.add(va.getVar()); }
124126
@Override public void visit(ImMemberAccess ma) { super.visit(ma); used.add(ma.getVar()); }
125127
@Override public void visit(ImVarArrayAccess vaa) { super.visit(vaa); used.add(vaa.getVar()); }
128+
@Override public void visit(ImVarargLoop loop) {
129+
super.visit(loop);
130+
loop.getLoopVars().forEach(v -> used.add(v.getVar()));
131+
}
126132
});
127133
List<ImVar> locals = new ArrayList<>(f.getLocals());
128134
int before = locals.size();

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -261,9 +261,9 @@ private void indexElementAfterChildren(Element element, ImFunction owner, Object
261261
} else if (element instanceof ImVarargLoop) {
262262
ImVar varargParameter = varargParameter(owner);
263263
if (varargParameter != null) {
264-
addDependency(
265-
variableFact(varargParameter),
266-
variableFact(((ImVarargLoop) element).getLoopVar()));
264+
for (ImVarargLoopVar loopVar : ((ImVarargLoop) element).getLoopVars()) {
265+
addDependency(variableFact(varargParameter), variableFact(loopVar.getVar()));
266+
}
267267
}
268268
}
269269

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

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -316,7 +316,7 @@ public void visit(ImSet va) {
316316
@Override
317317
public void visit(ImVarargLoop va) {
318318
super.visit(va);
319-
imVars.add(va.getLoopVar());
319+
va.getLoopVars().forEach(v -> imVars.add(v.getVar()));
320320
}
321321

322322
});
@@ -405,7 +405,7 @@ public void visit(ImSet va) {
405405
@Override
406406
public void visit(ImVarargLoop va) {
407407
super.visit(va);
408-
imVars.add(va.getLoopVar());
408+
va.getLoopVars().forEach(v -> imVars.add(v.getVar()));
409409
}
410410

411411
});

de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/translation/imoptimizer/ImInliner.java

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import de.peeeq.wurstscript.types.TypesHelper;
1111

1212
import java.util.*;
13+
import java.util.stream.Collectors;
1314

1415
import static de.peeeq.wurstscript.jassIm.JassIm.ImStatementExpr;
1516
import static de.peeeq.wurstscript.jassIm.JassIm.ImStmts;
@@ -278,7 +279,10 @@ private ImStmts rewriteStmtForEarlyReturn(ImStmt s, ImVar doneVar, ImVar retVar)
278279
ImStmts loopBody = JassIm.ImStmts();
279280
loopBody.add(JassIm.ImExitwhen(l.getTrace(), JassIm.ImVarAccess(doneVar)));
280281
loopBody.addAll(rewriteForEarlyReturns(l.getBody().copy(), doneVar, retVar).removeAll());
281-
return JassIm.ImStmts(JassIm.ImVarargLoop(l.getTrace(), loopBody, l.getLoopVar()));
282+
return JassIm.ImStmts(JassIm.ImVarargLoop(l.getTrace(), loopBody,
283+
JassIm.ImVarargLoopVars(l.getLoopVars().stream()
284+
.map(v -> JassIm.ImVarargLoopVar(v.getVar()))
285+
.collect(Collectors.toList()))));
282286
}
283287
// Keep tree ownership valid when rewrapping statements into new blocks.
284288
return JassIm.ImStmts(s.copy());

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

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -43,7 +43,9 @@ public void check(Element e) {
4343
checkType(e, ((ImMethod) e).getMethodClass());
4444
checkRooted(e, ((ImMethod) e).getImplementation());
4545
} else if (e instanceof ImVarargLoop) {
46-
checkRooted(e, ((ImVarargLoop) e).getLoopVar());
46+
for (ImVarargLoopVar loopVar : ((ImVarargLoop) e).getLoopVars()) {
47+
checkRooted(e, loopVar.getVar());
48+
}
4749
} else if (e instanceof ImTypeVarDispatch) {
4850
checkRooted(e, ((ImTypeVarDispatch) e).getTypeClassFunc());
4951
checkRooted(e, ((ImTypeVarDispatch) e).getTypeVariable());

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

Lines changed: 14 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -427,6 +427,20 @@ public void visit(ImVarAccess va) {
427427
}
428428
}
429429

430+
@Override
431+
public void visit(ImVarargLoop loop) {
432+
super.visit(loop);
433+
Preconditions.checkState(loop.getLoopVars().size() == 1,
434+
"Expected one vararg loop variable before tuple elimination.");
435+
ImVar loopVar = loop.getLoopVars().get(0).getVar();
436+
if (TypesHelper.typeContainsTuples(loopVar.getType())) {
437+
loop.setLoopVars(JassIm.ImVarargLoopVars(
438+
translator.getTupleScalarVars(loopVar).stream()
439+
.map(JassIm::ImVarargLoopVar)
440+
.collect(Collectors.toList())));
441+
}
442+
}
443+
430444
@Override
431445
public void visit(ImVarArrayAccess va) {
432446
super.visit(va);

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

Lines changed: 9 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
import java.util.Arrays;
1111
import java.util.Collections;
1212
import java.util.List;
13+
import java.util.stream.Collectors;
1314

1415
import static de.peeeq.wurstscript.jassIm.JassIm.*;
1516

@@ -659,7 +660,14 @@ public static Result flatten(ImGetStackTrace e, ImTranslator translator,
659660

660661
public static Result flatten(ImVarargLoop s, ImTranslator translator, ImFunction f) {
661662
return new Result(Collections.singletonList(
662-
JassIm.ImVarargLoop(s.getTrace(), flattenStatements(s.getBody(), translator, f), s.getLoopVar())));
663+
JassIm.ImVarargLoop(s.getTrace(), flattenStatements(s.getBody(), translator, f),
664+
copyVarargLoopVars(s.getLoopVars()))));
665+
}
666+
667+
private static ImVarargLoopVars copyVarargLoopVars(ImVarargLoopVars loopVars) {
668+
return JassIm.ImVarargLoopVars(loopVars.stream()
669+
.map(v -> JassIm.ImVarargLoopVar(v.getVar()))
670+
.collect(Collectors.toList()));
663671
}
664672

665673

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

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -507,7 +507,9 @@ public static void print(ImCompiletimeExpr e, Appendable sb, int indent) {
507507

508508
public static void print(ImVarargLoop e, Appendable sb, int indent) {
509509
append(sb, "foreach vararg ");
510-
e.getLoopVar().print(sb, indent);
510+
append(sb, e.getLoopVars().stream()
511+
.map(v -> v.getVar().getName())
512+
.collect(Collectors.joining(", ")));
511513
append(sb, " {\n");
512514
e.getBody().print(sb, indent + 1);
513515
indent(sb, indent);
@@ -599,6 +601,10 @@ public static String asString(ImTypeArgument s) {
599601
return s.getType() + "" + s.getTypeClassBinding();
600602
}
601603

604+
public static String asString(ImVarargLoopVar s) {
605+
return s.getVar().getName() + smallHash(s.getVar());
606+
}
607+
602608
public static void print(ImCast e, Appendable sb, int indent) {
603609
append(sb, "(");
604610
e.getExpr().print(sb, indent);

0 commit comments

Comments
 (0)