diff options
| author | Marc André Tanner <mat@brain-dump.org> | 2017-03-24 12:51:43 +0100 |
|---|---|---|
| committer | Marc André Tanner <mat@brain-dump.org> | 2017-03-24 13:13:04 +0100 |
| commit | f3fd9c3cd1f2e15e89f9cd96d07c1ba957ae7c89 (patch) | |
| tree | f1b50beb4f82813f2e9d7a48ada332c0f661b744 /vis-lua.c | |
| parent | 4c4bd8ef68655f28c11b20bc35ccce0063744c19 (diff) | |
| download | vis-f3fd9c3cd1f2e15e89f9cd96d07c1ba957ae7c89.tar.gz vis-f3fd9c3cd1f2e15e89f9cd96d07c1ba957ae7c89.tar.xz | |
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 (limited to 'vis-lua.c')
| -rw-r--r-- | vis-lua.c | 32 |
1 files changed, 31 insertions, 1 deletions
@@ -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 |
