diff options
Diffstat (limited to 'lgc.c')
-rw-r--r-- | lgc.c | 11 |
1 files changed, 7 insertions, 4 deletions
@@ -906,16 +906,16 @@ static void GCTM (lua_State *L) { | |||
906 | if (!notm(tm)) { /* is there a finalizer? */ | 906 | if (!notm(tm)) { /* is there a finalizer? */ |
907 | int status; | 907 | int status; |
908 | lu_byte oldah = L->allowhook; | 908 | lu_byte oldah = L->allowhook; |
909 | int running = g->gcrunning; | 909 | int oldgcstp = g->gcstp; |
910 | g->gcstp = GCSTPGC; /* avoid GC steps */ | ||
910 | L->allowhook = 0; /* stop debug hooks during GC metamethod */ | 911 | L->allowhook = 0; /* stop debug hooks during GC metamethod */ |
911 | g->gcrunning = 0; /* avoid GC steps */ | ||
912 | setobj2s(L, L->top++, tm); /* push finalizer... */ | 912 | setobj2s(L, L->top++, tm); /* push finalizer... */ |
913 | setobj2s(L, L->top++, &v); /* ... and its argument */ | 913 | setobj2s(L, L->top++, &v); /* ... and its argument */ |
914 | L->ci->callstatus |= CIST_FIN; /* will run a finalizer */ | 914 | L->ci->callstatus |= CIST_FIN; /* will run a finalizer */ |
915 | status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); | 915 | status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); |
916 | L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */ | 916 | L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */ |
917 | L->allowhook = oldah; /* restore hooks */ | 917 | L->allowhook = oldah; /* restore hooks */ |
918 | g->gcrunning = running; /* restore state */ | 918 | g->gcstp = oldgcstp; /* restore state */ |
919 | if (l_unlikely(status != LUA_OK)) { /* error while running __gc? */ | 919 | if (l_unlikely(status != LUA_OK)) { /* error while running __gc? */ |
920 | luaE_warnerror(L, "__gc metamethod"); | 920 | luaE_warnerror(L, "__gc metamethod"); |
921 | L->top--; /* pops error object */ | 921 | L->top--; /* pops error object */ |
@@ -1502,9 +1502,11 @@ static void deletelist (lua_State *L, GCObject *p, GCObject *limit) { | |||
1502 | */ | 1502 | */ |
1503 | void luaC_freeallobjects (lua_State *L) { | 1503 | void luaC_freeallobjects (lua_State *L) { |
1504 | global_State *g = G(L); | 1504 | global_State *g = G(L); |
1505 | g->gcstp = GCSTPGC; | ||
1505 | luaC_changemode(L, KGC_INC); | 1506 | luaC_changemode(L, KGC_INC); |
1506 | separatetobefnz(g, 1); /* separate all objects with finalizers */ | 1507 | separatetobefnz(g, 1); /* separate all objects with finalizers */ |
1507 | lua_assert(g->finobj == NULL); | 1508 | lua_assert(g->finobj == NULL); |
1509 | g->gcstp = 0; | ||
1508 | callallpendingfinalizers(L); | 1510 | callallpendingfinalizers(L); |
1509 | deletelist(L, g->allgc, obj2gco(g->mainthread)); | 1511 | deletelist(L, g->allgc, obj2gco(g->mainthread)); |
1510 | deletelist(L, g->finobj, NULL); | 1512 | deletelist(L, g->finobj, NULL); |
@@ -1647,6 +1649,7 @@ void luaC_runtilstate (lua_State *L, int statesmask) { | |||
1647 | } | 1649 | } |
1648 | 1650 | ||
1649 | 1651 | ||
1652 | |||
1650 | /* | 1653 | /* |
1651 | ** Performs a basic incremental step. The debt and step size are | 1654 | ** Performs a basic incremental step. The debt and step size are |
1652 | ** converted from bytes to "units of work"; then the function loops | 1655 | ** converted from bytes to "units of work"; then the function loops |
@@ -1678,7 +1681,7 @@ static void incstep (lua_State *L, global_State *g) { | |||
1678 | void luaC_step (lua_State *L) { | 1681 | void luaC_step (lua_State *L) { |
1679 | global_State *g = G(L); | 1682 | global_State *g = G(L); |
1680 | lua_assert(!g->gcemergency); | 1683 | lua_assert(!g->gcemergency); |
1681 | if (g->gcrunning) { /* running? */ | 1684 | if (gcrunning(g)) { /* running? */ |
1682 | if(isdecGCmodegen(g)) | 1685 | if(isdecGCmodegen(g)) |
1683 | genstep(L, g); | 1686 | genstep(L, g); |
1684 | else | 1687 | else |