aboutsummaryrefslogtreecommitdiff
path: root/lgc.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-05-21 17:06:11 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2009-05-21 17:06:11 -0300
commit019ebcb85fa5ab03f424e21f6758d8533a5b3126 (patch)
tree9638ae9fc8823c58cbd0ea36536518203fa9fb28 /lgc.c
parent889284ebd01dbc923403b0aa38b82dc80ed86af8 (diff)
downloadlua-019ebcb85fa5ab03f424e21f6758d8533a5b3126.tar.gz
lua-019ebcb85fa5ab03f424e21f6758d8533a5b3126.tar.bz2
lua-019ebcb85fa5ab03f424e21f6758d8533a5b3126.zip
errors in finalizers are propagated with code LUA_ERRGCMM (ERRor in
__gc MetaMethod)
Diffstat (limited to 'lgc.c')
-rw-r--r--lgc.c21
1 files changed, 15 insertions, 6 deletions
diff --git a/lgc.c b/lgc.c
index 9563da82..509415c0 100644
--- a/lgc.c
+++ b/lgc.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lgc.c,v 2.51 2009/04/28 19:04:36 roberto Exp roberto $ 2** $Id: lgc.c,v 2.52 2009/04/29 17:09:41 roberto Exp roberto $
3** Garbage Collector 3** Garbage Collector
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -617,11 +617,12 @@ static void dothecall (lua_State *L, void *ud) {
617} 617}
618 618
619 619
620static void GCTM (lua_State *L) { 620static void GCTM (lua_State *L, int propagateerrors) {
621 global_State *g = G(L); 621 global_State *g = G(L);
622 Udata *udata = udata2finalize(g); 622 Udata *udata = udata2finalize(g);
623 const TValue *tm = gfasttm(g, udata->uv.metatable, TM_GC); 623 const TValue *tm = gfasttm(g, udata->uv.metatable, TM_GC);
624 if (tm != NULL && ttisfunction(tm)) { 624 if (tm != NULL && ttisfunction(tm)) {
625 int status;
625 lu_byte oldah = L->allowhook; 626 lu_byte oldah = L->allowhook;
626 lu_mem oldt = g->GCthreshold; 627 lu_mem oldt = g->GCthreshold;
627 L->allowhook = 0; /* stop debug hooks during GC tag method */ 628 L->allowhook = 0; /* stop debug hooks during GC tag method */
@@ -629,7 +630,15 @@ static void GCTM (lua_State *L) {
629 setobj2s(L, L->top, tm); 630 setobj2s(L, L->top, tm);
630 setuvalue(L, L->top+1, udata); 631 setuvalue(L, L->top+1, udata);
631 L->top += 2; 632 L->top += 2;
632 luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0); 633 status = luaD_pcall(L, dothecall, NULL, savestack(L, L->top - 2), 0);
634 if (status != LUA_OK && propagateerrors) { /* error while running __gc? */
635 if (status == LUA_ERRRUN) { /* is there an error msg.? */
636 luaO_pushfstring(L, "error in __gc tag method (%s)",
637 lua_tostring(L, -1));
638 status = LUA_ERRGCMM; /* error in __gc metamethod */
639 }
640 luaD_throw(L, status); /* re-send error */
641 }
633 L->allowhook = oldah; /* restore hooks */ 642 L->allowhook = oldah; /* restore hooks */
634 g->GCthreshold = oldt; /* restore threshold */ 643 g->GCthreshold = oldt; /* restore threshold */
635 } 644 }
@@ -637,10 +646,10 @@ static void GCTM (lua_State *L) {
637 646
638 647
639/* 648/*
640** Call all GC tag methods 649** Call all GC tag methods (without raising errors)
641*/ 650*/
642void luaC_callAllGCTM (lua_State *L) { 651void luaC_callAllGCTM (lua_State *L) {
643 while (G(L)->tobefnz) GCTM(L); 652 while (G(L)->tobefnz) GCTM(L, 0);
644} 653}
645 654
646 655
@@ -783,7 +792,7 @@ static l_mem singlestep (lua_State *L) {
783 } 792 }
784 case GCSfinalize: { 793 case GCSfinalize: {
785 if (g->tobefnz) { 794 if (g->tobefnz) {
786 GCTM(L); 795 GCTM(L, 1);
787 if (g->estimate > GCFINALIZECOST) 796 if (g->estimate > GCFINALIZECOST)
788 g->estimate -= GCFINALIZECOST; 797 g->estimate -= GCFINALIZECOST;
789 return GCFINALIZECOST; 798 return GCFINALIZECOST;