| 905 | |
| 906 | |
| 907 | static void GCTM (lua_State *L) { |
| 908 | global_State *g = G(L); |
| 909 | const TValue *tm; |
| 910 | TValue v; |
| 911 | lua_assert(!g->gcemergency); |
| 912 | setgcovalue(L, &v, udata2finalize(g)); |
| 913 | tm = luaT_gettmbyobj(L, &v, TM_GC); |
| 914 | if (!notm(tm)) { /* is there a finalizer? */ |
| 915 | int status; |
| 916 | lu_byte oldah = L->allowhook; |
| 917 | int oldgcstp = g->gcstp; |
| 918 | g->gcstp |= GCSTPGC; /* avoid GC steps */ |
| 919 | L->allowhook = 0; /* stop debug hooks during GC metamethod */ |
| 920 | setobj2s(L, L->top.p++, tm); /* push finalizer... */ |
| 921 | setobj2s(L, L->top.p++, &v); /* ... and its argument */ |
| 922 | L->ci->callstatus |= CIST_FIN; /* will run a finalizer */ |
| 923 | status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top.p - 2), 0); |
| 924 | L->ci->callstatus &= ~CIST_FIN; /* not running a finalizer anymore */ |
| 925 | L->allowhook = oldah; /* restore hooks */ |
| 926 | g->gcstp = oldgcstp; /* restore state */ |
| 927 | if (l_unlikely(status != LUA_OK)) { /* error while running __gc? */ |
| 928 | luaE_warnerror(L, "__gc"); |
| 929 | L->top.p--; /* pops error object */ |
| 930 | } |
| 931 | } |
| 932 | } |
| 933 | |
| 934 | |
| 935 | /* |
no test coverage detected