mirror of https://github.com/rusefi/lua.git
run GC tag methods in protected mod
This commit is contained in:
parent
9aff171f3b
commit
21259a50e1
33
lgc.c
33
lgc.c
|
@ -356,32 +356,30 @@ static void checkMbuffer (lua_State *L) {
|
|||
}
|
||||
|
||||
|
||||
static void callgcTM (lua_State *L, Udata *udata) {
|
||||
static void do1gcTM (lua_State *L, Udata *udata) {
|
||||
const TObject *tm = fasttm(L, udata->uv.eventtable, TM_GC);
|
||||
if (tm != NULL && ttype(tm) == LUA_TFUNCTION) {
|
||||
int oldah = L->allowhooks;
|
||||
if (tm != NULL) {
|
||||
StkId top = L->top;
|
||||
L->allowhooks = 0; /* stop debug hooks during GC tag methods */
|
||||
setobj(top, tm);
|
||||
setuvalue(top+1, udata);
|
||||
L->top += 2;
|
||||
luaD_call(L, top);
|
||||
L->top = top; /* restore top */
|
||||
L->allowhooks = oldah; /* restore hooks */
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
static void callgcTMudata (lua_State *L) {
|
||||
static void unprotectedcallGCTM (lua_State *L, void *pu) {
|
||||
luaD_checkstack(L, 3);
|
||||
L->top++; /* reserve space to keep udata while runs its gc method */
|
||||
while (G(L)->tmudata != NULL) {
|
||||
Udata *udata = G(L)->tmudata;
|
||||
G(L)->tmudata = udata->uv.next; /* remove udata from list */
|
||||
*(Udata **)pu = udata; /* keep a reference to it (in case of errors) */
|
||||
setuvalue(L->top - 1, udata); /* and on stack (in case of recursive GC) */
|
||||
udata->uv.next = G(L)->rootudata; /* resurect it */
|
||||
G(L)->rootudata = udata;
|
||||
setuvalue(L->top - 1, udata);
|
||||
callgcTM(L, udata);
|
||||
do1gcTM(L, udata);
|
||||
/* mark udata as finalized (default event table) */
|
||||
uvalue(L->top-1)->uv.eventtable = hvalue(defaultet(L));
|
||||
}
|
||||
|
@ -389,11 +387,26 @@ static void callgcTMudata (lua_State *L) {
|
|||
}
|
||||
|
||||
|
||||
static void callGCTM (lua_State *L) {
|
||||
int oldah = L->allowhooks;
|
||||
L->allowhooks = 0; /* stop debug hooks during GC tag methods */
|
||||
while (G(L)->tmudata != NULL) {
|
||||
Udata *udata;
|
||||
if (luaD_runprotected(L, unprotectedcallGCTM, &udata) != 0) {
|
||||
/* `udata' generated an error during its gc */
|
||||
/* mark it as finalized (default event table) */
|
||||
udata->uv.eventtable = hvalue(defaultet(L));
|
||||
}
|
||||
}
|
||||
L->allowhooks = oldah; /* restore hooks */
|
||||
}
|
||||
|
||||
|
||||
void luaC_callallgcTM (lua_State *L) {
|
||||
lua_assert(G(L)->tmudata == NULL);
|
||||
G(L)->tmudata = G(L)->rootudata; /* all udata must be collected */
|
||||
G(L)->rootudata = NULL;
|
||||
callgcTMudata(L); /* call their GC tag methods */
|
||||
callGCTM(L); /* call their GC tag methods */
|
||||
}
|
||||
|
||||
|
||||
|
@ -416,6 +429,6 @@ void luaC_collectgarbage (lua_State *L) {
|
|||
luaC_collect(L, 0);
|
||||
checkMbuffer(L);
|
||||
G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */
|
||||
callgcTMudata(L);
|
||||
callGCTM(L);
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue