** if object 'o' has a finalizer, remove it from 'allgc' list (must ** search the list to find it) and link it in 'finobj' list. */
| 870 | ** search the list to find it) and link it in 'finobj' list. |
| 871 | */ |
| 872 | void luaC_checkfinalizer (lua_State *L, GCObject *o, Table *mt) { |
| 873 | global_State *g = G(L); |
| 874 | if (testbit(gch(o)->marked, SEPARATED) || /* obj. is already separated... */ |
| 875 | isfinalized(o) || /* ... or is finalized... */ |
| 876 | gfasttm(g, mt, TM_GC) == NULL) /* or has no finalizer? */ |
| 877 | return; /* nothing to be done */ |
| 878 | else { /* move 'o' to 'finobj' list */ |
| 879 | GCObject **p; |
| 880 | GCheader *ho = gch(o); |
| 881 | if (g->sweepgc == &ho->next) { /* avoid removing current sweep object */ |
| 882 | lua_assert(issweepphase(g)); |
| 883 | g->sweepgc = sweeptolive(L, g->sweepgc, NULL); |
| 884 | } |
| 885 | /* search for pointer pointing to 'o' */ |
| 886 | for (p = &g->allgc; *p != o; p = &gch(*p)->next) { /* empty */ } |
| 887 | *p = ho->next; /* remove 'o' from root list */ |
| 888 | ho->next = g->finobj; /* link it in list 'finobj' */ |
| 889 | g->finobj = o; |
| 890 | l_setbit(ho->marked, SEPARATED); /* mark it as such */ |
| 891 | if (!keepinvariantout(g)) /* not keeping invariant? */ |
| 892 | makewhite(g, o); /* "sweep" object */ |
| 893 | else |
| 894 | resetoldbit(o); /* see MOVE OLD rule */ |
| 895 | } |
| 896 | } |
| 897 | |
| 898 | /* }====================================================== */ |
| 899 |
no test coverage detected