diff --git a/de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/translation/imtranslation/StackTraceInjector2.java b/de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/translation/imtranslation/StackTraceInjector2.java index 8df4773e3..47a695cac 100644 --- a/de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/translation/imtranslation/StackTraceInjector2.java +++ b/de.peeeq.wurstscript/src/main/java/de/peeeq/wurstscript/translation/imtranslation/StackTraceInjector2.java @@ -380,14 +380,15 @@ private void rewriteFuncRefs(final List funcRefs, Set ImVar traceLimit = JassIm.ImVar(trace, TypesHelper.imInt(), "stacktraceLimit", false); f.getLocals().add(traceLimit); ImStmts stmts = JassIm.ImStmts(); - stmts.add(JassIm.ImSet(trace, JassIm.ImVarAccess(traceStr), JassIm.ImStringVal(""))); + stmts.add(JassIm.ImSet(trace, JassIm.ImVarAccess(traceStr), JassIm.ImStringVal(" Stacktrace:"))); stmts.add(JassIm.ImSet(trace, JassIm.ImVarAccess(traceI), JassIm.ImVarAccess(stackSize))); stmts.add(JassIm.ImSet(trace, JassIm.ImVarAccess(traceLimit), JassIm.ImIntVal(0))); ImStmts loopBody = JassIm.ImStmts(); @@ -447,6 +448,12 @@ private void rewriteErrorStatements(final Multimap JassIm.ImOperatorCall(WurstOperator.PLUS, JassIm.ImExprs(JassIm.ImStringVal("\n "), JassIm.ImVarArrayAccess(trace, stack, JassIm.ImExprs(JassIm.ImVarAccess(traceI))))))))); + // Make empty traces explicit instead of returning an empty string. + stmts.add(JassIm.ImIf(trace, JassIm.ImOperatorCall(WurstOperator.EQ, + JassIm.ImExprs(JassIm.ImVarAccess(traceStr), JassIm.ImStringVal(" Stacktrace:"))), + JassIm.ImStmts(JassIm.ImSet(trace, JassIm.ImVarAccess(traceStr), JassIm.ImStringVal(" Stacktrace: "))), + JassIm.ImStmts())); + s.replaceBy(JassIm.ImStatementExpr(stmts, JassIm.ImVarAccess(traceStr))); } } diff --git a/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/BugTests.java b/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/BugTests.java index d7b869f3d..fc376fbbb 100644 --- a/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/BugTests.java +++ b/de.peeeq.wurstscript/src/test/java/tests/wurstscript/tests/BugTests.java @@ -1,5 +1,7 @@ package tests.wurstscript.tests; +import com.google.common.base.Charsets; +import com.google.common.io.Files; import de.peeeq.wurstio.jassinterpreter.InterpreterException; import de.peeeq.wurstscript.ast.ClassDef; import de.peeeq.wurstscript.ast.FuncDef; @@ -1070,6 +1072,18 @@ public void testStacktrace() { " if foo(bar(1), bar(2))", " testSuccess()" ); + + try { + String jass = Files.toString( + new File(TEST_OUTPUT_PATH + "BugTests_testStacktrace_stacktraceinlopt.j"), + Charsets.UTF_8 + ); + Assert.assertTrue(jass.contains("wurst_stack_depth")); + Assert.assertTrue(jass.contains("wurst_stack")); + Assert.assertFalse(jass.contains("return \"\"")); + } catch (IOException e) { + throw new RuntimeException(e); + } } @Test @@ -1450,6 +1464,37 @@ public void executeFuncWithStackTrace() { ); } + @Test + public void executeFuncBridgeKeepsCallerStackFrames() { + test().executeProg(false).executeTests(false).lines( + "package Test", + "@extern native ExecuteFunc(string f)", + "function getStackTraceString() returns string", + " return \"\"", + "function foo()", + " getStackTraceString()", + "function caller()", + " getStackTraceString()", + " ExecuteFunc(\"foo\")", + " getStackTraceString()", + "init", + " caller()" + ); + + try { + String jass = Files.toString( + new File(TEST_OUTPUT_PATH + "BugTests_executeFuncBridgeKeepsCallerStackFrames_stacktraceinlopt.j"), + Charsets.UTF_8 + ); + Assert.assertTrue(jass.contains("function bridge_foo")); + Assert.assertFalse(jass.contains("bridge_oldStackDepth")); + Assert.assertFalse(jass.contains("set wurst_stack_depth = 0")); + Assert.assertTrue(jass.contains("via ExecuteFunc")); + } catch (IOException e) { + throw new RuntimeException(e); + } + } + @Test public void agentTypeComparisonsWurst() { testAssertErrorsLinesWithStdLib(true, "Cannot compare types sound with rect",