| 834 | |
| 835 | |
| 836 | static void GCTM (lua_State *L) { |
| 837 | global_State *g = G(L); |
| 838 | const TValue *tm; |
| 839 | TValue v; |
| 840 | lua_assert(!g->gcemergency); |
| 841 | setgcovalue(L, &v, udata2finalize(g)); |
| 842 | tm = luaT_gettmbyobj(L, &v, TM_GC); |
| 843 | if (!notm(tm)) { /* is there a finalizer? */ |
| 844 | int status; |
| 845 | lu_byte oldah = L->allowhook; |
| 846 | int running = g->gcrunning; |
| 847 | L->allowhook = 0; /* stop debug hooks during GC metamethod */ |
| 848 | g->gcrunning = 0; /* avoid GC steps */ |
| 849 | setobj2s(L, L->top++, tm); /* push finalizer... */ |
| 850 | setobj2s(L, L->top++, &v); /* ... and its argument */ |
| 851 | L->ci->callstatus |= CIST_FIN; /* will run a finalizer */ |
| 852 | status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); |
| 853 | L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */ |
| 854 | L->allowhook = oldah; /* restore hooks */ |
| 855 | g->gcrunning = running; /* restore state */ |
| 856 | if (unlikely(status != LUA_OK)) { /* error while running __gc? */ |
| 857 | luaE_warnerror(L, "__gc metamethod"); |
| 858 | L->top--; /* pops error object */ |
| 859 | } |
| 860 | } |
| 861 | } |
| 862 | |
| 863 | |
| 864 | /* |
no test coverage detected