From 5380817ce63e1c830646a04edffb4b49aa16342e Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Wed, 16 Mar 2022 23:51:23 -0700 Subject: [PATCH] function names from globals rather than debug info This reclaims all the slowdown in sieve.tlv, and it also is now smart enough to detect calls to global bindings that pass through variables. On the flip side, we lose names for non-globals. But that's not very useful anyway in Teliva's context. This is still not enough to detect callers through coroutines (intervening anonymous functions), though. --- src/teliva.c | 44 ++++++++++++++++++++++---------------------- 1 file changed, 22 insertions(+), 22 deletions(-) diff --git a/src/teliva.c b/src/teliva.c index c85e823..b0e6a56 100644 --- a/src/teliva.c +++ b/src/teliva.c @@ -309,33 +309,32 @@ static const char* name_of_global(lua_State* L, const CallInfo* ci, int frame) { int gt = lua_gettop(L); lua_pushinteger(L, func); lua_rawget(L, gt); - if (lua_isnil(L, -1)) { - // set value if it doesn't exist yet - lua_Debug f; - lua_getstack(L, frame, &f); - lua_getinfo(L, "n", &f); - lua_pushinteger(L, func); - if (f.name) { - result = strdup(f.name); - lua_pushstring(L, result); - } - else { - lua_pushinteger(L, 0); - } - lua_rawset(L, gt); - } - else if (lua_isnumber(L, -1)) { - // return null - } - else { - result = lua_tostring(L, -1); - } + if (!lua_isnil(L, -1)) + result = lua_tostring(L, -1); // safe because global names are long-lived and never GC'd lua_pop(L, 1); // value - lua_pop(L, 1); // table of function names + lua_pop(L, 1); // table of global names assert(lua_gettop(L) == oldtop); return result; } +static void precompute_names_of_globals(lua_State* L) { + int oldtop = lua_gettop(L); + luaL_newmetatable(L, "__teliva_global_name"); + int gt = lua_gettop(L); + lua_pushvalue(L, LUA_GLOBALSINDEX); + int table = lua_gettop(L); + for (lua_pushnil(L); lua_next(L, table) != 0; lua_pop(L, 1)) { + const char* key = lua_tostring(L, -2); + const char* value = lua_topointer(L, -1); + lua_pushinteger(L, value); + lua_pushstring(L, key); + lua_rawset(L, gt); + } + lua_pop(L, 1); // table of globals + lua_pop(L, 1); // table of global names + assert(lua_gettop(L) == oldtop); +} + static void save_caller(lua_State* L, const char* name, const char* caller_name) { int oldtop = lua_gettop(L); // push table of caller tables @@ -1802,6 +1801,7 @@ int load_image(lua_State* L, char** argv, int n) { //? exit(1); status = load_definitions(L); if (status != 0) return 0; + precompute_names_of_globals(L); /* run tests */ status = run_tests(L); if (status != 0) return report_in_developer_mode(L, status);