vis

a vi-like editor based on Plan 9's structural regular expressions

git clone https://9o.is/git/vis.git

commit ad29a6e03bfe96f7a2a372734f3051b2a263ba24
parent ef84ab81faad97f09474322ea42bb75b1ab9ba97
Author: Marc André Tanner <mat@brain-dump.org>
Date:   Sun, 22 May 2016 18:03:54 +0200

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.

Diffstat:
Mvis-lua.c | 27++++++++++++++++++++-------
1 file changed, 20 insertions(+), 7 deletions(-)

diff --git 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);