diff options
author | Kartik K. Agaram <vc@akkartik.com> | 2022-03-16 23:51:23 -0700 |
---|---|---|
committer | Kartik K. Agaram <vc@akkartik.com> | 2022-03-16 23:53:08 -0700 |
commit | 5380817ce63e1c830646a04edffb4b49aa16342e (patch) | |
tree | 1d94063a60360280b19a54c9563fc3b1da184767 /src/teliva.c | |
parent | 76d1dda2402d24f5f43387d13773b3c2d03e180b (diff) | |
download | teliva-5380817ce63e1c830646a04edffb4b49aa16342e.tar.gz |
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.
Diffstat (limited to 'src/teliva.c')
-rw-r--r-- | src/teliva.c | 44 |
1 files 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); |