Skip to content

Commit

Permalink
vis-lua.c: stop obj_ref_get() from leaving the lua stack modified
Browse files Browse the repository at this point in the history
The only place where this behaviour was encountered was in
file_lines_iterator() and it was just being worked around.
  • Loading branch information
rnpnr committed Aug 10, 2023
1 parent d1f2c27 commit f4840ed
Showing 1 changed file with 8 additions and 17 deletions.
25 changes: 8 additions & 17 deletions vis-lua.c
Original file line number Diff line number Diff line change
Expand Up @@ -367,7 +367,10 @@ static void *obj_ref_get(lua_State *L, void *addr, const char *type) {
else if (*handle != addr)
debug("get: vis.objects[%p] = %s (BUG: handle mismatch %p)\n", addr, type, *handle);
}
return luaL_checkudata(L, -1, type);
/* verify that obj is correct type then unmodify the stack */
luaL_checkudata(L, -1, type);
lua_pop(L, 1);
return addr;
}

/* expects a userdatum at the top of the stack and sets
Expand Down Expand Up @@ -441,22 +444,12 @@ static void *obj_ref_new(lua_State *L, void *addr, const char *type) {
return addr;
}

/* retrieve object stored in reference at stack location `idx' */
static void *obj_ref_check_get(lua_State *L, int idx, const char *type) {
/* (type) check validity of object reference at stack location `idx' and retrieve it */
static void *obj_ref_check(lua_State *L, int idx, const char *type) {
void **addr = luaL_checkudata(L, idx, type);
if (!obj_ref_get(L, *addr, type))
return NULL;
return *addr;
}

/* (type) check validity of object reference at stack location `idx' */
static void *obj_ref_check(lua_State *L, int idx, const char *type) {
void *obj = obj_ref_check_get(L, idx, type);
if (obj)
lua_pop(L, 1);
else
luaL_argerror(L, idx, "invalid object reference");
return obj;
return *addr;
}

static void *obj_ref_check_containerof(lua_State *L, int idx, const char *type, size_t offset) {
Expand Down Expand Up @@ -2243,10 +2236,8 @@ static int file_delete(lua_State *L) {
*/
static int file_lines_iterator_it(lua_State *L);
static int file_lines_iterator(lua_State *L) {
/* need to check second parameter first, because obj_ref_check_get
* modifies the stack */
File *file = obj_ref_check(L, 1, VIS_LUA_TYPE_FILE);
size_t line = luaL_optunsigned(L, 2, 1);
File *file = obj_ref_check_get(L, 1, VIS_LUA_TYPE_FILE);
size_t *pos = lua_newuserdata(L, sizeof *pos);
*pos = text_pos_by_lineno(file->text, line);
lua_pushcclosure(L, file_lines_iterator_it, 2);
Expand Down

0 comments on commit f4840ed

Please sign in to comment.