diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-12-12 15:47:33 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2001-12-12 15:47:33 -0200 |
| commit | 21259a50e12ca45669379a4b37fbe7e502cdd22d (patch) | |
| tree | cf881a0824e24bcc58eaf4cebbe81c928419e3ba | |
| parent | 9aff171f3bf0125314a29a5ca952470b2d83708e (diff) | |
| download | lua-21259a50e12ca45669379a4b37fbe7e502cdd22d.tar.gz lua-21259a50e12ca45669379a4b37fbe7e502cdd22d.tar.bz2 lua-21259a50e12ca45669379a4b37fbe7e502cdd22d.zip | |
run GC tag methods in protected mod
Diffstat (limited to '')
| -rw-r--r-- | lgc.c | 33 |
1 files changed, 23 insertions, 10 deletions
| @@ -356,32 +356,30 @@ static void checkMbuffer (lua_State *L) { | |||
| 356 | } | 356 | } |
| 357 | 357 | ||
| 358 | 358 | ||
| 359 | static void callgcTM (lua_State *L, Udata *udata) { | 359 | static void do1gcTM (lua_State *L, Udata *udata) { |
| 360 | const TObject *tm = fasttm(L, udata->uv.eventtable, TM_GC); | 360 | const TObject *tm = fasttm(L, udata->uv.eventtable, TM_GC); |
| 361 | if (tm != NULL && ttype(tm) == LUA_TFUNCTION) { | 361 | if (tm != NULL) { |
| 362 | int oldah = L->allowhooks; | ||
| 363 | StkId top = L->top; | 362 | StkId top = L->top; |
| 364 | L->allowhooks = 0; /* stop debug hooks during GC tag methods */ | ||
| 365 | setobj(top, tm); | 363 | setobj(top, tm); |
| 366 | setuvalue(top+1, udata); | 364 | setuvalue(top+1, udata); |
| 367 | L->top += 2; | 365 | L->top += 2; |
| 368 | luaD_call(L, top); | 366 | luaD_call(L, top); |
| 369 | L->top = top; /* restore top */ | 367 | L->top = top; /* restore top */ |
| 370 | L->allowhooks = oldah; /* restore hooks */ | ||
| 371 | } | 368 | } |
| 372 | } | 369 | } |
| 373 | 370 | ||
| 374 | 371 | ||
| 375 | static void callgcTMudata (lua_State *L) { | 372 | static void unprotectedcallGCTM (lua_State *L, void *pu) { |
| 376 | luaD_checkstack(L, 3); | 373 | luaD_checkstack(L, 3); |
| 377 | L->top++; /* reserve space to keep udata while runs its gc method */ | 374 | L->top++; /* reserve space to keep udata while runs its gc method */ |
| 378 | while (G(L)->tmudata != NULL) { | 375 | while (G(L)->tmudata != NULL) { |
| 379 | Udata *udata = G(L)->tmudata; | 376 | Udata *udata = G(L)->tmudata; |
| 380 | G(L)->tmudata = udata->uv.next; /* remove udata from list */ | 377 | G(L)->tmudata = udata->uv.next; /* remove udata from list */ |
| 378 | *(Udata **)pu = udata; /* keep a reference to it (in case of errors) */ | ||
| 379 | setuvalue(L->top - 1, udata); /* and on stack (in case of recursive GC) */ | ||
| 381 | udata->uv.next = G(L)->rootudata; /* resurect it */ | 380 | udata->uv.next = G(L)->rootudata; /* resurect it */ |
| 382 | G(L)->rootudata = udata; | 381 | G(L)->rootudata = udata; |
| 383 | setuvalue(L->top - 1, udata); | 382 | do1gcTM(L, udata); |
| 384 | callgcTM(L, udata); | ||
| 385 | /* mark udata as finalized (default event table) */ | 383 | /* mark udata as finalized (default event table) */ |
| 386 | uvalue(L->top-1)->uv.eventtable = hvalue(defaultet(L)); | 384 | uvalue(L->top-1)->uv.eventtable = hvalue(defaultet(L)); |
| 387 | } | 385 | } |
| @@ -389,11 +387,26 @@ static void callgcTMudata (lua_State *L) { | |||
| 389 | } | 387 | } |
| 390 | 388 | ||
| 391 | 389 | ||
| 390 | static void callGCTM (lua_State *L) { | ||
| 391 | int oldah = L->allowhooks; | ||
| 392 | L->allowhooks = 0; /* stop debug hooks during GC tag methods */ | ||
| 393 | while (G(L)->tmudata != NULL) { | ||
| 394 | Udata *udata; | ||
| 395 | if (luaD_runprotected(L, unprotectedcallGCTM, &udata) != 0) { | ||
| 396 | /* `udata' generated an error during its gc */ | ||
| 397 | /* mark it as finalized (default event table) */ | ||
| 398 | udata->uv.eventtable = hvalue(defaultet(L)); | ||
| 399 | } | ||
| 400 | } | ||
| 401 | L->allowhooks = oldah; /* restore hooks */ | ||
| 402 | } | ||
| 403 | |||
| 404 | |||
| 392 | void luaC_callallgcTM (lua_State *L) { | 405 | void luaC_callallgcTM (lua_State *L) { |
| 393 | lua_assert(G(L)->tmudata == NULL); | 406 | lua_assert(G(L)->tmudata == NULL); |
| 394 | G(L)->tmudata = G(L)->rootudata; /* all udata must be collected */ | 407 | G(L)->tmudata = G(L)->rootudata; /* all udata must be collected */ |
| 395 | G(L)->rootudata = NULL; | 408 | G(L)->rootudata = NULL; |
| 396 | callgcTMudata(L); /* call their GC tag methods */ | 409 | callGCTM(L); /* call their GC tag methods */ |
| 397 | } | 410 | } |
| 398 | 411 | ||
| 399 | 412 | ||
| @@ -416,6 +429,6 @@ void luaC_collectgarbage (lua_State *L) { | |||
| 416 | luaC_collect(L, 0); | 429 | luaC_collect(L, 0); |
| 417 | checkMbuffer(L); | 430 | checkMbuffer(L); |
| 418 | G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */ | 431 | G(L)->GCthreshold = 2*G(L)->nblocks; /* new threshold */ |
| 419 | callgcTMudata(L); | 432 | callGCTM(L); |
| 420 | } | 433 | } |
| 421 | 434 | ||
