Skip to content

Commit 0e4e9f1

Browse files
authored
Don't reset stackframes at function bridges (#1145)
1 parent f4d9c0a commit 0e4e9f1

2 files changed

Lines changed: 56 additions & 4 deletions

File tree

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

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -380,14 +380,15 @@ private void rewriteFuncRefs(final List<ImFuncRefOrCall> funcRefs, Set<ImFunctio
380380
ImExprs args = JassIm.ImExprs(str);
381381
ImStmts body = bridgeFunc.getBody();
382382
de.peeeq.wurstscript.ast.Element trace = frTrace;
383-
// reset stack and add information for callback:
384-
body.add(JassIm.ImSet(trace, JassIm.ImVarAccess(stackSize), JassIm.ImIntVal(0)));
385383

386384
ImFunctionCall call = JassIm.ImFunctionCall(frTrace, f, JassIm.ImTypeArguments(), args, true, CallType.NORMAL);
387385
if (bridgeFunc.getReturnType() instanceof ImVoid) {
388386
stmt = call;
389387
} else {
390-
stmt = JassIm.ImReturn(frTrace, call);
388+
ImVar bridgeReturn = JassIm.ImVar(trace, bridgeFunc.getReturnType().copy(), "bridge_return", false);
389+
bridgeFunc.getLocals().add(bridgeReturn);
390+
body.add(JassIm.ImSet(trace, JassIm.ImVarAccess(bridgeReturn), call));
391+
stmt = JassIm.ImReturn(frTrace, JassIm.ImVarAccess(bridgeReturn));
391392
}
392393
body.add(stmt);
393394

@@ -426,7 +427,7 @@ private void rewriteErrorStatements(final Multimap<ImFunction, ImGetStackTrace>
426427
ImVar traceLimit = JassIm.ImVar(trace, TypesHelper.imInt(), "stacktraceLimit", false);
427428
f.getLocals().add(traceLimit);
428429
ImStmts stmts = JassIm.ImStmts();
429-
stmts.add(JassIm.ImSet(trace, JassIm.ImVarAccess(traceStr), JassIm.ImStringVal("")));
430+
stmts.add(JassIm.ImSet(trace, JassIm.ImVarAccess(traceStr), JassIm.ImStringVal(" Stacktrace:")));
430431
stmts.add(JassIm.ImSet(trace, JassIm.ImVarAccess(traceI), JassIm.ImVarAccess(stackSize)));
431432
stmts.add(JassIm.ImSet(trace, JassIm.ImVarAccess(traceLimit), JassIm.ImIntVal(0)));
432433
ImStmts loopBody = JassIm.ImStmts();
@@ -447,6 +448,12 @@ private void rewriteErrorStatements(final Multimap<ImFunction, ImGetStackTrace>
447448
JassIm.ImOperatorCall(WurstOperator.PLUS, JassIm.ImExprs(JassIm.ImStringVal("\n "),
448449
JassIm.ImVarArrayAccess(trace, stack, JassIm.ImExprs(JassIm.ImVarAccess(traceI)))))))));
449450

451+
// Make empty traces explicit instead of returning an empty string.
452+
stmts.add(JassIm.ImIf(trace, JassIm.ImOperatorCall(WurstOperator.EQ,
453+
JassIm.ImExprs(JassIm.ImVarAccess(traceStr), JassIm.ImStringVal(" Stacktrace:"))),
454+
JassIm.ImStmts(JassIm.ImSet(trace, JassIm.ImVarAccess(traceStr), JassIm.ImStringVal(" Stacktrace: <none>"))),
455+
JassIm.ImStmts()));
456+
450457
s.replaceBy(JassIm.ImStatementExpr(stmts, JassIm.ImVarAccess(traceStr)));
451458
}
452459
}

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

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,5 +1,7 @@
11
package tests.wurstscript.tests;
22

3+
import com.google.common.base.Charsets;
4+
import com.google.common.io.Files;
35
import de.peeeq.wurstio.jassinterpreter.InterpreterException;
46
import de.peeeq.wurstscript.ast.ClassDef;
57
import de.peeeq.wurstscript.ast.FuncDef;
@@ -1070,6 +1072,18 @@ public void testStacktrace() {
10701072
" if foo(bar(1), bar(2))",
10711073
" testSuccess()"
10721074
);
1075+
1076+
try {
1077+
String jass = Files.toString(
1078+
new File(TEST_OUTPUT_PATH + "BugTests_testStacktrace_stacktraceinlopt.j"),
1079+
Charsets.UTF_8
1080+
);
1081+
Assert.assertTrue(jass.contains("wurst_stack_depth"));
1082+
Assert.assertTrue(jass.contains("wurst_stack"));
1083+
Assert.assertFalse(jass.contains("return \"\""));
1084+
} catch (IOException e) {
1085+
throw new RuntimeException(e);
1086+
}
10731087
}
10741088

10751089
@Test
@@ -1450,6 +1464,37 @@ public void executeFuncWithStackTrace() {
14501464
);
14511465
}
14521466

1467+
@Test
1468+
public void executeFuncBridgeKeepsCallerStackFrames() {
1469+
test().executeProg(false).executeTests(false).lines(
1470+
"package Test",
1471+
"@extern native ExecuteFunc(string f)",
1472+
"function getStackTraceString() returns string",
1473+
" return \"\"",
1474+
"function foo()",
1475+
" getStackTraceString()",
1476+
"function caller()",
1477+
" getStackTraceString()",
1478+
" ExecuteFunc(\"foo\")",
1479+
" getStackTraceString()",
1480+
"init",
1481+
" caller()"
1482+
);
1483+
1484+
try {
1485+
String jass = Files.toString(
1486+
new File(TEST_OUTPUT_PATH + "BugTests_executeFuncBridgeKeepsCallerStackFrames_stacktraceinlopt.j"),
1487+
Charsets.UTF_8
1488+
);
1489+
Assert.assertTrue(jass.contains("function bridge_foo"));
1490+
Assert.assertFalse(jass.contains("bridge_oldStackDepth"));
1491+
Assert.assertFalse(jass.contains("set wurst_stack_depth = 0"));
1492+
Assert.assertTrue(jass.contains("via ExecuteFunc"));
1493+
} catch (IOException e) {
1494+
throw new RuntimeException(e);
1495+
}
1496+
}
1497+
14531498
@Test
14541499
public void agentTypeComparisonsWurst() {
14551500
testAssertErrorsLinesWithStdLib(true, "Cannot compare types sound with rect",

0 commit comments

Comments
 (0)