From 0fcb8b502fa698401494b2604313e02679e960de Mon Sep 17 00:00:00 2001 From: Phil Hagelberg Date: Sun, 13 Oct 2024 15:04:44 -0700 Subject: [PATCH] Use debug.traceback for stack traces in Lua-based carts. Fennel carts have debug.traceback set to fennel.traceback during initialization, which is a function that uses sourcemaps to convert the traceback data which Lua knows about (with line numbers based on the Lua output from the Fennel compiler) into traceback data based on line numbers in the original source code. Previously this had no effect because debug.traceback was never actually run; luaapi.c contained a call to the underlying luaL_traceback function instead, which did not know about sourcemaps. Replacing it with a call to debug.traceback allows us to see stack traces that use sourcemap data. This change should have no effect on Lua carts; only Fennel carts and perhaps Moonscript carts. Also in this patch we set the filename field when compiling Fennel carts; without this the custom fennel.traceback function can't use sourcemaps as needed. --- src/api/fennel.c | 3 ++- src/api/luaapi.c | 8 +++++++- 2 files changed, 9 insertions(+), 2 deletions(-) diff --git a/src/api/fennel.c b/src/api/fennel.c index 44cc3a4f4..ce330d4a5 100644 --- a/src/api/fennel.c +++ b/src/api/fennel.c @@ -31,7 +31,8 @@ static const char* execute_fennel_src = FENNEL_CODE( io = { read = true } local fennel = require("fennel") debug.traceback = fennel.traceback - local opts = {allowedGlobals = false, ["error-pinpoint"]={">>", "<<"}} + local opts = {allowedGlobals = false, ["error-pinpoint"]={">>", "<<"}, + filename="game.fnl"} local src = ... if(src:find("\n;; +strict: *true")) then opts.allowedGlobals = nil end local ok, msg = pcall(fennel.eval, src, opts) diff --git a/src/api/luaapi.c b/src/api/luaapi.c index e1cde9dca..fea36f5ce 100644 --- a/src/api/luaapi.c +++ b/src/api/luaapi.c @@ -1676,7 +1676,13 @@ static s32 msghandler (lua_State *lua) else msg = lua_pushfstring(lua, "(error object is a %s value)", luaL_typename(lua, 1)); } - luaL_traceback(lua, lua, msg, 1); /* append a standard traceback */ + /* call the debug.traceback function instead of luaL_traceback so */ + /* customized sourcemap-aware debug.traceback can give better line numbers */ + lua_getglobal(lua, "debug"); + lua_pushstring(lua, "traceback"); + lua_gettable(lua, -2); + lua_pushstring(lua, msg); + lua_call(lua, 1, 1); return 1; /* return the traceback */ }