diff --git a/src/nvim/lua/executor.c b/src/nvim/lua/executor.c index bffa924d8f..402fbcd52f 100644 --- a/src/nvim/lua/executor.c +++ b/src/nvim/lua/executor.c @@ -1061,12 +1061,14 @@ static lua_State *nlua_init_state(bool thread) return lstate; } +/// Disposes global Lua state. Idempotent, harmless if called multiple times. void nlua_free_all_mem(void) { if (!global_lstate) { return; } lua_State *lstate = global_lstate; + global_lstate = NULL; nlua_unref_global(lstate, require_ref); nlua_common_free_all_mem(lstate); nlua_treesitter_free(); diff --git a/src/nvim/memory.c b/src/nvim/memory.c index 0b1b884b11..e9dbd28210 100644 --- a/src/nvim/memory.c +++ b/src/nvim/memory.c @@ -861,9 +861,10 @@ void free_all_mem(void) { buf_T *buf, *nextbuf; - // When we cause a crash here it is caught and Vim tries to exit cleanly. - // Don't try freeing everything again. + // If a routine below recurses into free_all_mem, don't try freeing everything again. if (entered_free_all_mem) { + // Except the Lua state. #39675 + nlua_free_all_mem(); return; } entered_free_all_mem = true;