about summary refs log tree commit diff stats
diff options
context:
space:
mode:
authorKartik K. Agaram <vc@akkartik.com>2022-01-03 13:26:38 -0800
committerKartik K. Agaram <vc@akkartik.com>2022-01-03 13:26:38 -0800
commit7812ebc5f119cd4c47e6a91db0561008c7080bc5 (patch)
treee57163280775e4608c2f03f84940f39e48f07c38
parent1c78ab3d2e380ca633a3812e4779de0e67abf3d6 (diff)
downloadteliva-7812ebc5f119cd4c47e6a91db0561008c7080bc5.tar.gz
start saving callers of functions
I think this is significantly slowing things down. Perhaps we should
sample or something.
-rw-r--r--src/ldo.c6
-rw-r--r--src/teliva.c50
-rw-r--r--src/teliva.h1
3 files changed, 55 insertions, 2 deletions
diff --git a/src/ldo.c b/src/ldo.c
index de2ccdd..6316b24 100644
--- a/src/ldo.c
+++ b/src/ldo.c
@@ -30,7 +30,7 @@
 #include "lundump.h"
 #include "lvm.h"
 #include "lzio.h"
-
+#include "teliva.h"
 
 
 
@@ -283,7 +283,9 @@ void record_metadata_about_function_call (lua_State *L, CallInfo *ci) {
     return;
   int g = GETARG_Bx(i);  /* global index */
   lua_assert(ttisstring(&p->k[g]));
-  assign_call_graph_depth_to_name(L, ci - L->base_ci, svalue(&p->k[g]));
+  const char* function_name = svalue(&p->k[g]);
+  assign_call_graph_depth_to_name(L, ci - L->base_ci, function_name);
+  save_caller(L, function_name);
 }
 
 
diff --git a/src/teliva.c b/src/teliva.c
index a1a684c..1dc68ae 100644
--- a/src/teliva.c
+++ b/src/teliva.c
@@ -276,6 +276,56 @@ void assign_call_graph_depth_to_name(lua_State* L, int depth, const char* name)
   lua_pop(L, 1);  // table
 }
 
+int array_contains_string(lua_State* L, int array_index, const char* s) {
+  int oldtop = lua_gettop(L);
+  assert(lua_istable(L, array_index));
+  int array_size = luaL_getn(L, array_index);
+  int result = false;
+  for (int i = 1; i <= array_size; ++i) {
+    lua_rawgeti(L, array_index, i);
+    assert(lua_isstring(L, -1));
+    const char* curr = lua_tostring(L, -1);
+    result = result || (strcmp(curr, s) == 0);
+    lua_pop(L, 1);  // current element
+    if (result) break;
+  }
+  assert(oldtop == lua_gettop(L));
+  return result;
+}
+
+void append_string_to_array(lua_State* L, int array_index, const char* s) {
+  assert(lua_istable(L, array_index));
+  int array_size = luaL_getn(L, array_index);
+  int new_index = array_size+1;
+  lua_pushstring(L, s);
+  lua_rawseti(L, array_index, new_index);
+}
+
+void save_caller(lua_State* L, const char* name) {
+  lua_Debug ar;
+  lua_getstack(L, 2, &ar);
+  lua_getinfo(L, "n", &ar);
+  if (!ar.name) return;
+  // push table of caller tables
+  luaL_newmetatable(L, "__teliva_caller");
+  int ct = lua_gettop(L);
+  // if key doesn't already exist, map it to an empty caller table
+  lua_getfield(L, ct, name);
+  if (lua_isnil(L, -1)) {
+    lua_newtable(L);
+    lua_setfield(L, ct, name);
+  }
+  // append the caller's name to the caller table if necessary
+  lua_pop(L, 1);  // old value
+  lua_getfield(L, ct, name);  // new value = caller table
+  int curr_caller_index = lua_gettop(L);
+  lua_pushboolean(L, true);
+  lua_setfield(L, curr_caller_index, ar.name);
+  // clean up
+  lua_pop(L, 1);  // caller table
+  lua_pop(L, 1);  // table of caller tables
+}
+
 /* return true if submitted */
 static int edit_current_definition(lua_State* L);
 static void recent_changes_view(lua_State* L);
diff --git a/src/teliva.h b/src/teliva.h
index f783eec..6484298 100644
--- a/src/teliva.h
+++ b/src/teliva.h
@@ -163,6 +163,7 @@ extern void save_to_current_definition_and_editor_buffer(lua_State* L, const cha
 extern void save_editor_state(int rowoff, int coloff, int cy, int cx);
 
 extern void assign_call_graph_depth_to_name(lua_State* L, int depth, const char* name);
+extern void save_caller(lua_State* L, const char* name);
 extern void append_to_audit_log(lua_State* L, const char* buffer);
 
 /* Standard UI elements */