vis

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

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

commit 4eb3e283df37d3f69db112b63f469ac85d39e188
parent 74a0800df2bedc58c465a2124152010923caef3c
Author: Marc André Tanner <mat@brain-dump.org>
Date:   Fri, 24 Mar 2017 12:51:43 +0100

vis-lua: register a panic handler

The intention here is to catch any errors in unprotected mode,
close the lua state and jump back to the mainloop to give the
user the opportunity to take care of unsaved changes.

We abuse the infrastructure Lua provides for custom memory
allocators to associate our vis instance pointer with the lua
state. In the panic handler we can then use lua_getallocf to
get our context back. The actual memory allocater is equivalent
to the one used by default and just forwards everything to the
libc.

Diffstat:
Mvis-lua.c | 32+++++++++++++++++++++++++++++++-
1 file changed, 31 insertions(+), 1 deletion(-)

diff --git a/vis-lua.c b/vis-lua.c @@ -221,6 +221,25 @@ static void stack_dump(lua_State *L, const char *format, ...) { #endif +static int panic_handler(lua_State *L) { + void *ud = NULL; + lua_getallocf(L, &ud); + if (ud) { + Vis *vis = ud; + vis->lua = NULL; + if (vis->event) + vis->event->win_status = window_status_update; + const char *msg = NULL; + if (lua_type(L, -1) == LUA_TSTRING) + msg = lua_tostring(L, -1); + vis_info_show(vis, "Fatal Lua error: %s", msg ? msg : "unknown reason"); + lua_close(L); + if (vis->running) + siglongjmp(vis->sigbus_jmpbuf, 1); + } + return 0; +} + static int error_handler(lua_State *L) { Vis *vis = lua_touserdata(L, lua_upvalueindex(1)); if (vis->errorhandler) @@ -2408,6 +2427,15 @@ static bool package_exist(Vis *vis, lua_State *L, const char *name) { return ret; } +static void *alloc_lua(void *ud, void *ptr, size_t osize, size_t nsize) { + if (nsize == 0) { + free(ptr); + return NULL; + } else { + return realloc(ptr, nsize); + } +} + /*** * Editor initialization completed. * This event is emitted immediately after `visrc.lua` has been sourced, but @@ -2418,10 +2446,12 @@ static bool package_exist(Vis *vis, lua_State *L, const char *name) { * @function init */ void vis_lua_init(Vis *vis) { - lua_State *L = luaL_newstate(); + lua_State *L = lua_newstate(alloc_lua, vis); if (!L) return; vis->lua = L; + lua_atpanic(L, &panic_handler); + luaL_openlibs(L); #if CONFIG_LPEG