From ef5195dee92732408466a9cc8dd48a63ff46667b Mon Sep 17 00:00:00 2001 From: "Kartik K. Agaram" Date: Wed, 16 Mar 2022 21:19:19 -0700 Subject: [PATCH] simplify function call instrumentation src/ldo.c now has a minimal diff with Lua 5.1. It might be a bit slower than it was before, but not noticeably so.. This approach doesn't support indirect calls. --- src/ldo.c | 33 +-------------------------------- src/teliva.c | 25 +++++++++++++++++++------ src/teliva.h | 3 --- 3 files changed, 20 insertions(+), 41 deletions(-) diff --git a/src/ldo.c b/src/ldo.c index 39f8cbe..1857e0d 100644 --- a/src/ldo.c +++ b/src/ldo.c @@ -29,7 +29,6 @@ #include "lundump.h" #include "lvm.h" #include "lzio.h" -#include "teliva.h" @@ -256,37 +255,7 @@ static StkId tryfuncTM (lua_State *L, StkId func) { } -/* based on getfuncname */ -extern Instruction symbexec (const Proto *pt, int lastpc, int reg); -extern int luaL_newmetatable (lua_State *L, const char *tname); -void record_metadata_about_function_call (lua_State *L, CallInfo *ci) { - if (!isLua(ci)) - return; - if (ci->tailcalls > 0) - return; - if (!isLua(ci - 1)) - return; - ci--; /* calling function */ - if (ci == L->ci) - ci->savedpc = L->savedpc; - int pc = cast(int, ci->savedpc - ci_func(ci)->l.p->code) - 1; - lua_assert(pc != -1); // TODO: lua_assert not triggering - Instruction i = ci_func(ci)->l.p->code[pc]; - if (GET_OPCODE(i) != OP_CALL && GET_OPCODE(i) != OP_TAILCALL && - GET_OPCODE(i) != OP_TFORLOOP) - return; - Proto *p = ci_func(ci)->l.p; - i = symbexec(p, pc, GETARG_A(i)); /* previous instruction that writes to call's RA */ - if (GET_OPCODE(i) != OP_GETGLOBAL) - return; - int g = GETARG_Bx(i); /* global index */ - lua_assert(ttisstring(&p->k[g])); - int call_graph_depth = ci - L->base_ci; - const char* function_name = svalue(&p->k[g]); - assign_call_graph_depth_to_name(L, call_graph_depth, function_name); - save_caller(L, function_name, call_graph_depth); -} - +extern void record_metadata_about_function_call (lua_State *L, CallInfo *ci); #define inc_ci(L) \ ((L->ci == L->end_ci) ? growCI(L) : \ diff --git a/src/teliva.c b/src/teliva.c index 1bc06d5..3d20267 100644 --- a/src/teliva.c +++ b/src/teliva.c @@ -13,6 +13,9 @@ #include "lua.h" #include "lauxlib.h" #include "lualib.h" + +#undef getstr +#include "lstate.h" #include "teliva.h" #include "tlv.h" @@ -341,11 +344,21 @@ static void save_caller_as(lua_State* L, const char* name, const char* caller_na lua_pop(L, 1); // table of caller tables } -void save_caller(lua_State* L, const char* name, int call_graph_depth) { - lua_Debug ar; - lua_getstack(L, 1, &ar); - lua_getinfo(L, "n", &ar); - if (ar.name) save_caller_as(L, name, ar.name); +void record_metadata_about_function_call (lua_State *L, CallInfo *ci) { + lua_Debug f; + lua_getstack(L, 0, &f); + lua_getinfo(L, "n", &f); + long int call_depth = ci - L->base_ci; + /* note to self: the function pointer is at ci_func(ci) */ + if (f.name) { + assign_call_graph_depth_to_name(L, call_depth, f.name); + if (call_depth <= 1) return; + lua_Debug caller_f; + lua_getstack(L, 1, &caller_f); + lua_getinfo(L, "n", &caller_f); + if (caller_f.name) + save_caller_as(L, f.name, caller_f.name); + } } static void clear_caller(lua_State* L) { @@ -496,7 +509,7 @@ restart: y += 2; mvprintw(y, 0, "functions: "); y++; - for (int depth = /*ignore call_main*/2; ; ++depth) { + for (int depth = /*ignore callers of main*/3; ; ++depth) { mvaddstr(y, 0, " "); bool drew_anything = false; index_within_level = 0; diff --git a/src/teliva.h b/src/teliva.h index 2e79956..5808382 100644 --- a/src/teliva.h +++ b/src/teliva.h @@ -165,10 +165,7 @@ extern void save_editor_state(int rowoff, int coloff, int cy, int cx); int editor_view_in_progress(lua_State* L); extern void assign_call_graph_depth_to_name(lua_State* L, int depth, const char* name); -extern char* get_caller(lua_State* L); -extern void save_caller(lua_State* L, const char* name, int call_graph_depth); extern void draw_callers_of_current_definition(lua_State* L); -extern char* get_caller_of_caller(lua_State* L); extern void append_to_audit_log(lua_State* L, const char* buffer);