Save currently executing lua_State in g->cur_L.

This is only a good approximation due to deficiencies in the design of
the Lua/C API. It indicates _some_ valid state that is/was executing.
Also reorder L->cframe stores to achieve a synchronously consistent state.
This commit is contained in:
Mike Pall
2013-08-28 13:06:19 +02:00
parent 5120240b77
commit 517500ba48
15 changed files with 89 additions and 67 deletions

View File

@@ -91,7 +91,7 @@ void lj_state_shrinkstack(lua_State *L, MSize used)
if (4*used < L->stacksize &&
2*(LJ_STACK_START+LJ_STACK_EXTRA) < L->stacksize &&
/* Don't shrink stack of live trace. */
(tvref(G(L)->jit_base) == NULL || obj2gco(L) != gcref(G(L)->jit_L)))
(tvref(G(L)->jit_base) == NULL || obj2gco(L) != gcref(G(L)->cur_L)))
resizestack(L, L->stacksize >> 1);
}
@@ -237,6 +237,7 @@ LUA_API void lua_close(lua_State *L)
{
global_State *g = G(L);
int i;
setgcrefnull(g->cur_L);
L = mainthread(g); /* Only the main thread can be closed. */
lj_func_closeuv(L, tvref(L->stack));
lj_gc_separateudata(g, 1); /* Separate udata which have GC metamethods. */
@@ -248,8 +249,8 @@ LUA_API void lua_close(lua_State *L)
for (i = 0;;) {
hook_enter(g);
L->status = 0;
L->cframe = NULL;
L->base = L->top = tvref(L->stack) + 1;
L->cframe = NULL;
if (lj_vm_cpcall(L, NULL, NULL, cpfinalize) == 0) {
if (++i >= 10) break;
lj_gc_separateudata(g, 1); /* Separate udata again. */
@@ -281,6 +282,8 @@ lua_State *lj_state_new(lua_State *L)
void LJ_FASTCALL lj_state_free(global_State *g, lua_State *L)
{
lua_assert(L != mainthread(g));
if (obj2gco(L) == gcref(g->cur_L))
setgcrefnull(g->cur_L);
lj_func_closeuv(L, tvref(L->stack));
lua_assert(gcref(L->openupval) == NULL);
lj_mem_freevec(g, tvref(L->stack), L->stacksize, TValue);