stop leaking on the Lua stack, redux

An empty stack is too rigorous a line to hold. Instead we'll just ensure
we leave the stack the way we found it.
This commit is contained in:
Kartik K. Agaram 2021-12-16 20:07:59 -08:00
parent 76ed8d30f4
commit 65b38f96ba
2 changed files with 26 additions and 11 deletions

View File

@ -13,3 +13,10 @@ start -> big picture -> edit A -> move cursor -> run -> exit -> start -> ... ->
start -> big picture -> edit A -> move cursor -> run -> exit -> start -> ... -> edit B | big picture
syntax highlighting for line comments
syntax highlighting for multiline comments
start -> big picture -> recent changes -> add note -> save | note visible
It's very important not to leak space on the Lua stack, particularly
proportionate to keypresses. That's a recipe for segfaults.
This implies that bouncing around between big picture, editor, recent changes,
running app.. shouldn't grow the call stack either.

View File

@ -358,14 +358,14 @@ void save_editor_state (int rowoff, int coloff, int cy, int cx) {
}
void save_to_current_definition_and_editor_buffer (lua_State *L, const char *definition) {
int current_stack_index = lua_gettop(L);
int oldtop = lua_gettop(L);
strncpy(Current_definition, definition, CURRENT_DEFINITION_LEN);
int status = look_up_definition(L, Current_definition);
FILE *out = fopen("teliva_editor_buffer", "w");
if (status)
fprintf(out, "%s", lua_tostring(L, -1));
fclose(out);
lua_settop(L, current_stack_index);
lua_settop(L, oldtop);
}
@ -377,6 +377,7 @@ static void read_editor_buffer (char *out) {
static void update_definition (lua_State *L, const char *name, char *new_contents) {
int oldtop = lua_gettop(L);
lua_getglobal(L, "teliva_program");
int history_array = lua_gettop(L);
/* create a new table containing a single binding */
@ -394,19 +395,26 @@ static void update_definition (lua_State *L, const char *name, char *new_content
int history_array_size = luaL_getn(L, history_array);
++history_array_size;
lua_rawseti(L, history_array, history_array_size);
lua_settop(L, history_array);
lua_settop(L, oldtop);
}
extern void save_tlv (lua_State *L, char *filename);
int load_editor_buffer_to_current_definition_in_image(lua_State *L) {
int oldtop = lua_gettop(L);
char new_contents[8192] = {0};
read_editor_buffer(new_contents);
update_definition(L, Current_definition, new_contents);
save_tlv(L, Image_name);
/* reload binding */
return luaL_loadbuffer(L, new_contents, strlen(new_contents), Current_definition)
|| docall(L, 0, 1);
int status = luaL_loadbuffer(L, new_contents, strlen(new_contents), Current_definition);
if (status == 0) status = docall(L, 0, 1);
if (lua_gettop(L) != oldtop) {
endwin();
printf("load_editor_buffer_to_current_definition_in_image: memory leak %d -> %d\n", oldtop, lua_gettop(L));
exit(1);
}
return status;
}
@ -505,11 +513,14 @@ static int render_wrapped_lua_text (int y, int xmin, int xmax, const char *text)
}
void render_recent_changes (lua_State *L, int history_array, int start_index, int history_array_size) {
void render_recent_changes (lua_State *L, int start_index) {
clear();
attrset(A_BOLD);
mvaddstr(1, 0, "Recent changes");
attrset(A_NORMAL);
lua_getglobal(L, "teliva_program");
int history_array = lua_gettop(L);
int history_array_size = luaL_getn(L, history_array);
int y = 3;
attron(A_REVERSE);
for (int i = start_index; i > 0; --i) {
@ -555,6 +566,7 @@ void render_recent_changes (lua_State *L, int history_array, int start_index, in
y++;
if (y >= LINES-1) break;
}
lua_pop(L, 1);
recent_changes_menu(start_index, history_array_size);
refresh();
}
@ -616,10 +628,7 @@ void recent_changes_view (lua_State *L) {
int quit = 0;
while (!quit) {
/* refresh state after each operation so we pick up modifications */
lua_getglobal(L, "teliva_program");
history_array = lua_gettop(L);
history_array_size = luaL_getn(L, history_array);
render_recent_changes(L, history_array, cursor, history_array_size);
render_recent_changes(L, cursor);
int c = getch();
switch (c) {
case CTRL_X:
@ -650,7 +659,6 @@ void recent_changes_view (lua_State *L) {
}
break;
}
lua_pop(L, 1);
}
}