Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Original file line number Diff line number Diff line change
Expand Up @@ -233,8 +233,7 @@ public void visit(ImOperatorCall call) {
if (call.getOp() == WurstOperator.PLUS && args.size() == 2
&& TypesHelper.isStringType(args.get(0).attrTyp())
&& TypesHelper.isStringType(args.get(1).attrTyp())) {
call.replaceBy(JassIm.ImFunctionCall(call.attrTrace(), translator.stringConcatFunc,
JassIm.ImTypeArguments(), args.copy(), false, CallType.NORMAL));
call.replaceBy(callWithStacktrace(call.attrTrace(), translator.stringConcatFunc, args.copy()));
}
}
});
Expand Down Expand Up @@ -362,12 +361,29 @@ public void visit(ImVarArrayAccess access) {
if (ensureFunc == null) {
return;
}
access.replaceBy(JassIm.ImFunctionCall(access.attrTrace(), ensureFunc,
JassIm.ImTypeArguments(), JassIm.ImExprs(access.copy()), false, CallType.NORMAL));
access.replaceBy(callWithStacktrace(access.attrTrace(), ensureFunc, JassIm.ImExprs(access.copy())));
}
});
}

private static ImFunctionCall callWithStacktrace(de.peeeq.wurstscript.ast.Element trace, ImFunction f, ImExprs args) {
int stacktraceIndex = stacktraceParamIndex(f);
if (stacktraceIndex >= 0) {
args.add(stacktraceIndex, JassIm.ImStringVal("when calling " + f.getName()
+ StackTraceInjector2.getCallPos(trace.attrErrorPos())));
}
return JassIm.ImFunctionCall(trace, f, JassIm.ImTypeArguments(), args, false, CallType.NORMAL);
}

private static int stacktraceParamIndex(ImFunction f) {
for (int i = 0; i < f.getParameters().size(); i++) {
if (StackTraceInjector2.STACK_POS_PARAM.equals(f.getParameters().get(i).getName())) {
return i;
}
}
return -1;
}

private static ImFunction ensureFunctionFor(ImType type, ImTranslator translator) {
if (TypesHelper.isIntType(type)) {
return translator.ensureIntFunc;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,10 @@ private String compiledLua(String testName) throws IOException {

private String compileOptimizedLua(String testName, String... lines) {
RunArgs runArgs = new RunArgs().with("-lua", "-inline", "-localOptimizations");
return compileLuaWithRunArgs(testName, runArgs, lines);
}

private String compileLuaWithRunArgs(String testName, RunArgs runArgs, String... lines) {
WurstGuiCliImpl gui = new WurstGuiCliImpl();
WurstCompilerJassImpl compiler = new WurstCompilerJassImpl(null, gui, null, runArgs);
WurstModel model = parseFiles(Collections.emptyList(),
Expand Down Expand Up @@ -490,6 +494,30 @@ public void optimizedMovedImHelpersHaveNoDanglingReferences() {
assertTrue("repro must exercise real mod lowering", compiled.contains("__wurst_rawFmodReal"));
}

/**
* Stacktrace injection runs before Lua-native lowering. The lowering pass
* introduces fresh calls to existing IM helpers, so those calls must carry
* the injected stacktrace argument when the helper signature already has it.
*/
@Test
public void stacktracedLuaLoweringPassesHelperStacktraceArguments() {
compileLuaWithRunArgs(
"LuaBackendAuditTests_stacktracedLuaLoweringPassesHelperStacktraceArguments",
new RunArgs().with("-lua", "-inline", "-localOptimizations", "-stacktraces"),
"package Test",
"native print(string message)",
"native I2S(int value) returns string",
"int array values",
"function readValue(int index) returns int",
" return values[index]",
"function join(string left, string right) returns string",
" return left + right",
"init",
" values[1] = 7",
" print(join(\"value=\", I2S(readValue(1))))"
);
}

private void assertHelperDefinedWhenCalled(String compiled, String helperName) {
int definitions = countOccurrences(compiled, "function " + helperName + "(");
int calls = countOccurrences(compiled, helperName + "(") - definitions;
Expand Down
Loading