From a794d3c59a5119fcd1ce0b94e12cbd73c3dc9e58 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Marc=20Andr=C3=A9=20Tanner?= Date: Sun, 22 May 2016 18:03:54 +0200 Subject: vis-lua: introduce light references for short lived objects Light object references are used to type check, but contrary to full object references they are not stored in the Lua registry. This means that they are not bound to the object lifetime of their corresponding C object. Hence such objects must not be used after they have been free(3)-ed by the editor core. Such lightweight object references are always re-created, thus custom properties will not be stored across subsequent accesses. For now light object references are only used for cursor objects. This should ix the crashes introduced by the recent changes which make heavy use of the Lua API. --- vis-lua.c | 27 ++++++++++++++++++++------- 1 file changed, 20 insertions(+), 7 deletions(-) (limited to 'vis-lua.c') diff --git a/vis-lua.c b/vis-lua.c index e1337fd..bb238e1 100644 --- a/vis-lua.c +++ b/vis-lua.c @@ -264,6 +264,19 @@ static void *obj_ref_check(lua_State *L, int idx, const char *type) { return obj; } +static void *obj_lightref_new(lua_State *L, void *addr, const char *type) { + if (!addr) + return NULL; + void **handle = obj_new(L, sizeof(addr), type); + *handle = addr; + return addr; +} + +static void *obj_lightref_check(lua_State *L, int idx, const char *type) { + void **addr = luaL_checkudata(L, idx, type); + return *addr; +} + static int index_common(lua_State *L) { lua_getmetatable(L, 1); lua_pushvalue(L, 2); @@ -556,7 +569,7 @@ static bool command_lua(Vis *vis, Win *win, void *data, bool force, const char * return false; if (!cur) cur = view_cursors_primary_get(win->view); - if (!obj_ref_new(L, cur, "vis.window.cursor")) + if (!obj_lightref_new(L, cur, "vis.window.cursor")) return false; pushrange(L, range); if (pcall(vis, L, 5, 1) != 0) @@ -671,7 +684,7 @@ static int window_index(lua_State *L) { if (strcmp(key, "cursor") == 0) { Cursor *cur = view_cursors_primary_get(win->view); - obj_ref_new(L, cur, "vis.window.cursor"); + obj_lightref_new(L, cur, "vis.window.cursor"); return 1; } @@ -714,7 +727,7 @@ static int window_cursors_iterator_next(lua_State *L) { Cursor **handle = lua_touserdata(L, lua_upvalueindex(1)); if (!*handle) return 0; - Cursor *cur = obj_ref_new(L, *handle, "vis.window.cursor"); + Cursor *cur = obj_lightref_new(L, *handle, "vis.window.cursor"); if (!cur) return 0; *handle = view_cursors_next(cur); @@ -795,7 +808,7 @@ static int window_cursors_index(lua_State *L) { goto err; for (Cursor *c = view_cursors(view); c; c = view_cursors_next(c)) { if (!--index) { - obj_ref_new(L, c, "vis.window.cursor"); + obj_lightref_new(L, c, "vis.window.cursor"); return 1; } } @@ -817,7 +830,7 @@ static const struct luaL_Reg window_cursors_funcs[] = { }; static int window_cursor_index(lua_State *L) { - Cursor *cur = obj_ref_check(L, 1, "vis.window.cursor"); + Cursor *cur = obj_lightref_check(L, 1, "vis.window.cursor"); if (!cur) { lua_pushnil(L); return 1; @@ -856,7 +869,7 @@ static int window_cursor_index(lua_State *L) { } static int window_cursor_newindex(lua_State *L) { - Cursor *cur = obj_ref_check(L, 1, "vis.window.cursor"); + Cursor *cur = obj_lightref_check(L, 1, "vis.window.cursor"); if (!cur) return 0; if (lua_isstring(L, 2)) { @@ -880,7 +893,7 @@ static int window_cursor_newindex(lua_State *L) { } static int window_cursor_to(lua_State *L) { - Cursor *cur = obj_ref_check(L, 1, "vis.window.cursor"); + Cursor *cur = obj_lightref_check(L, 1, "vis.window.cursor"); if (cur) { size_t line = checkpos(L, 2); size_t col = checkpos(L, 3); -- cgit v1.2.3