| 806 | |
| 807 | |
| 808 | static void GCTM (lua_State *L, int propagateerrors) { |
| 809 | global_State *g = G(L); |
| 810 | const TValue *tm; |
| 811 | TValue v; |
| 812 | setgcovalue(L, &v, udata2finalize(g)); |
| 813 | tm = luaT_gettmbyobj(L, &v, TM_GC); |
| 814 | if (tm != NULL && ttisfunction(tm)) { /* is there a finalizer? */ |
| 815 | int status; |
| 816 | lu_byte oldah = L->allowhook; |
| 817 | int running = g->gcrunning; |
| 818 | L->allowhook = 0; /* stop debug hooks during GC metamethod */ |
| 819 | g->gcrunning = 0; /* avoid GC steps */ |
| 820 | setobj2s(L, L->top, tm); /* push finalizer... */ |
| 821 | setobj2s(L, L->top + 1, &v); /* ... and its argument */ |
| 822 | L->top += 2; /* and (next line) call the finalizer */ |
| 823 | status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); |
| 824 | L->allowhook = oldah; /* restore hooks */ |
| 825 | g->gcrunning = running; /* restore state */ |
| 826 | if (status != LUA_OK && propagateerrors) { /* error while running __gc? */ |
| 827 | if (status == LUA_ERRRUN) { /* is there an error object? */ |
| 828 | const char *msg = (ttisstring(L->top - 1)) |
| 829 | ? svalue(L->top - 1) |
| 830 | : "no message"; |
| 831 | luaO_pushfstring(L, "error in __gc metamethod (%s)", msg); |
| 832 | status = LUA_ERRGCMM; /* error in __gc metamethod */ |
| 833 | } |
| 834 | luaD_throw(L, status); /* re-throw error */ |
| 835 | } |
| 836 | } |
| 837 | } |
| 838 | |
| 839 | |
| 840 | /* |
no test coverage detected