diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2005-01-18 15:18:09 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2005-01-18 15:18:09 -0200 |
| commit | 334ba8132bd0471ffe2a9964b577d3ae89ec490a (patch) | |
| tree | 3e0dde3bca4f1f51dad42d8c85ad9cb624aab1fa | |
| parent | ac71a0891d8571816ce32b5c2c1fd97942decf71 (diff) | |
| download | lua-334ba8132bd0471ffe2a9964b577d3ae89ec490a.tar.gz lua-334ba8132bd0471ffe2a9964b577d3ae89ec490a.tar.bz2 lua-334ba8132bd0471ffe2a9964b577d3ae89ec490a.zip | |
cleaner way to remark open upvalues
| -rw-r--r-- | lfunc.c | 38 | ||||
| -rw-r--r-- | lfunc.h | 3 | ||||
| -rw-r--r-- | lgc.c | 37 | ||||
| -rw-r--r-- | lobject.h | 10 | ||||
| -rw-r--r-- | lstate.c | 22 | ||||
| -rw-r--r-- | lstate.h | 4 | ||||
| -rw-r--r-- | lstring.c | 8 | ||||
| -rw-r--r-- | ltests.c | 15 |
8 files changed, 74 insertions, 63 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lfunc.c,v 2.4 2004/04/30 20:13:38 roberto Exp roberto $ | 2 | ** $Id: lfunc.c,v 2.5 2004/11/24 19:20:21 roberto Exp $ |
| 3 | ** Auxiliary functions to manipulate prototypes and closures | 3 | ** Auxiliary functions to manipulate prototypes and closures |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -43,42 +43,66 @@ Closure *luaF_newLclosure (lua_State *L, int nelems, TValue *e) { | |||
| 43 | UpVal *luaF_newupval (lua_State *L) { | 43 | UpVal *luaF_newupval (lua_State *L) { |
| 44 | UpVal *uv = luaM_new(L, UpVal); | 44 | UpVal *uv = luaM_new(L, UpVal); |
| 45 | luaC_link(L, obj2gco(uv), LUA_TUPVAL); | 45 | luaC_link(L, obj2gco(uv), LUA_TUPVAL); |
| 46 | uv->v = &uv->value; | 46 | uv->v = &uv->u.value; |
| 47 | setnilvalue(uv->v); | 47 | setnilvalue(uv->v); |
| 48 | return uv; | 48 | return uv; |
| 49 | } | 49 | } |
| 50 | 50 | ||
| 51 | 51 | ||
| 52 | UpVal *luaF_findupval (lua_State *L, StkId level) { | 52 | UpVal *luaF_findupval (lua_State *L, StkId level) { |
| 53 | global_State *g = G(L); | ||
| 53 | GCObject **pp = &L->openupval; | 54 | GCObject **pp = &L->openupval; |
| 54 | UpVal *p; | 55 | UpVal *p; |
| 55 | UpVal *uv; | 56 | UpVal *uv; |
| 56 | while ((p = ngcotouv(*pp)) != NULL && p->v >= level) { | 57 | while ((p = ngcotouv(*pp)) != NULL && p->v >= level) { |
| 58 | lua_assert(p->v != &p->u.value); | ||
| 57 | if (p->v == level) return p; | 59 | if (p->v == level) return p; |
| 58 | pp = &p->next; | 60 | pp = &p->next; |
| 59 | } | 61 | } |
| 60 | uv = luaM_new(L, UpVal); /* not found: create a new one */ | 62 | uv = luaM_new(L, UpVal); /* not found: create a new one */ |
| 61 | uv->tt = LUA_TUPVAL; | 63 | uv->tt = LUA_TUPVAL; |
| 62 | uv->marked = luaC_white(G(L)); | 64 | uv->marked = luaC_white(g); |
| 63 | uv->v = level; /* current value lives in the stack */ | 65 | uv->v = level; /* current value lives in the stack */ |
| 64 | uv->next = *pp; /* chain it in the proper position */ | 66 | uv->next = *pp; /* chain it in the proper position */ |
| 65 | *pp = obj2gco(uv); | 67 | *pp = obj2gco(uv); |
| 68 | lua_assert(g->uvhead.u.l.next->u.l.prev == &g->uvhead && | ||
| 69 | g->uvhead.u.l.prev->u.l.next == &g->uvhead); | ||
| 70 | uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */ | ||
| 71 | uv->u.l.next = g->uvhead.u.l.next; | ||
| 72 | uv->u.l.next->u.l.prev = uv; | ||
| 73 | g->uvhead.u.l.next = uv; | ||
| 74 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); | ||
| 66 | return uv; | 75 | return uv; |
| 67 | } | 76 | } |
| 68 | 77 | ||
| 69 | 78 | ||
| 79 | static void unlinkupval (UpVal *uv) { | ||
| 80 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); | ||
| 81 | uv->u.l.next->u.l.prev = uv->u.l.prev; /* remove from `uvhead' list */ | ||
| 82 | uv->u.l.prev->u.l.next = uv->u.l.next; | ||
| 83 | } | ||
| 84 | |||
| 85 | |||
| 86 | void luaF_freeupval (lua_State *L, UpVal *uv) { | ||
| 87 | if (uv->v != &uv->u.value) /* is it open? */ | ||
| 88 | unlinkupval(uv); /* remove from open list */ | ||
| 89 | luaM_free(L, uv); /* free upvalue */ | ||
| 90 | } | ||
| 91 | |||
| 92 | |||
| 70 | void luaF_close (lua_State *L, StkId level) { | 93 | void luaF_close (lua_State *L, StkId level) { |
| 71 | UpVal *uv; | 94 | UpVal *uv; |
| 72 | global_State *g = G(L); | 95 | global_State *g = G(L); |
| 73 | while ((uv = ngcotouv(L->openupval)) != NULL && uv->v >= level) { | 96 | while ((uv = ngcotouv(L->openupval)) != NULL && uv->v >= level) { |
| 74 | GCObject *o = obj2gco(uv); | 97 | GCObject *o = obj2gco(uv); |
| 75 | lua_assert(!isblack(o)); | 98 | lua_assert(!isblack(o) && uv->v != &uv->u.value); |
| 76 | L->openupval = uv->next; /* remove from `open' list */ | 99 | L->openupval = uv->next; /* remove from `open' list */ |
| 77 | if (isdead(g, o)) | 100 | if (isdead(g, o)) |
| 78 | luaM_free(L, uv); /* free upvalue */ | 101 | luaF_freeupval(L, uv); /* free upvalue */ |
| 79 | else { | 102 | else { |
| 80 | setobj(L, &uv->value, uv->v); | 103 | unlinkupval(uv); |
| 81 | uv->v = &uv->value; /* now current value lives here */ | 104 | setobj(L, &uv->u.value, uv->v); |
| 105 | uv->v = &uv->u.value; /* now current value lives here */ | ||
| 82 | luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ | 106 | luaC_linkupval(L, uv); /* link upvalue into `gcroot' list */ |
| 83 | } | 107 | } |
| 84 | } | 108 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lfunc.h,v 1.23 2003/11/24 18:50:36 roberto Exp roberto $ | 2 | ** $Id: lfunc.h,v 2.1 2003/12/10 12:13:36 roberto Exp $ |
| 3 | ** Auxiliary functions to manipulate prototypes and closures | 3 | ** Auxiliary functions to manipulate prototypes and closures |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -26,6 +26,7 @@ UpVal *luaF_findupval (lua_State *L, StkId level); | |||
| 26 | void luaF_close (lua_State *L, StkId level); | 26 | void luaF_close (lua_State *L, StkId level); |
| 27 | void luaF_freeproto (lua_State *L, Proto *f); | 27 | void luaF_freeproto (lua_State *L, Proto *f); |
| 28 | void luaF_freeclosure (lua_State *L, Closure *c); | 28 | void luaF_freeclosure (lua_State *L, Closure *c); |
| 29 | void luaF_freeupval (lua_State *L, UpVal *uv); | ||
| 29 | 30 | ||
| 30 | const char *luaF_getlocalname (const Proto *func, int local_number, int pc); | 31 | const char *luaF_getlocalname (const Proto *func, int local_number, int pc); |
| 31 | 32 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lgc.c,v 2.20 2005/01/05 18:20:51 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.21 2005/01/14 14:19:42 roberto Exp $ |
| 3 | ** Garbage Collector | 3 | ** Garbage Collector |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -83,10 +83,9 @@ static void reallymarkobject (global_State *g, GCObject *o) { | |||
| 83 | } | 83 | } |
| 84 | case LUA_TUPVAL: { | 84 | case LUA_TUPVAL: { |
| 85 | UpVal *uv = gco2uv(o); | 85 | UpVal *uv = gco2uv(o); |
| 86 | if (uv->v == &uv->value) { /* closed? */ | 86 | markvalue(g, uv->v); |
| 87 | markvalue(g, uv->v); | 87 | if (uv->v == &uv->u.value) /* closed? */ |
| 88 | gray2black(o); | 88 | gray2black(o); /* open upvalues are never black */ |
| 89 | } | ||
| 90 | return; | 89 | return; |
| 91 | } | 90 | } |
| 92 | case LUA_TFUNCTION: { | 91 | case LUA_TFUNCTION: { |
| @@ -126,11 +125,11 @@ static void marktmu (global_State *g) { | |||
| 126 | /* move `dead' udata that need finalization to list `tmudata' */ | 125 | /* move `dead' udata that need finalization to list `tmudata' */ |
| 127 | size_t luaC_separateudata (lua_State *L, int all) { | 126 | size_t luaC_separateudata (lua_State *L, int all) { |
| 128 | size_t deadmem = 0; | 127 | size_t deadmem = 0; |
| 129 | GCObject **p = &G(L)->firstudata; | 128 | GCObject **p = &G(L)->mainthread->next; |
| 130 | GCObject *curr; | 129 | GCObject *curr; |
| 131 | GCObject *collected = NULL; /* to collect udata with gc event */ | 130 | GCObject *collected = NULL; /* to collect udata with gc event */ |
| 132 | GCObject **lastcollected = &collected; | 131 | GCObject **lastcollected = &collected; |
| 133 | while ((curr = *p)->gch.tt == LUA_TUSERDATA) { | 132 | while ((curr = *p) != NULL) { |
| 134 | if (!(iswhite(curr) || all) || isfinalized(gco2u(curr))) | 133 | if (!(iswhite(curr) || all) || isfinalized(gco2u(curr))) |
| 135 | p = &curr->gch.next; /* don't bother with them */ | 134 | p = &curr->gch.next; /* don't bother with them */ |
| 136 | else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) { | 135 | else if (fasttm(L, gco2u(curr)->metatable, TM_GC) == NULL) { |
| @@ -146,7 +145,6 @@ size_t luaC_separateudata (lua_State *L, int all) { | |||
| 146 | lastcollected = &curr->gch.next; | 145 | lastcollected = &curr->gch.next; |
| 147 | } | 146 | } |
| 148 | } | 147 | } |
| 149 | lua_assert(curr == obj2gco(G(L)->mainthread)); | ||
| 150 | /* insert collected udata with gc event into `tmudata' list */ | 148 | /* insert collected udata with gc event into `tmudata' list */ |
| 151 | *lastcollected = G(L)->tmudata; | 149 | *lastcollected = G(L)->tmudata; |
| 152 | G(L)->tmudata = collected; | 150 | G(L)->tmudata = collected; |
| @@ -380,7 +378,7 @@ static void freeobj (lua_State *L, GCObject *o) { | |||
| 380 | switch (o->gch.tt) { | 378 | switch (o->gch.tt) { |
| 381 | case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; | 379 | case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break; |
| 382 | case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break; | 380 | case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break; |
| 383 | case LUA_TUPVAL: luaM_free(L, gco2uv(o)); break; | 381 | case LUA_TUPVAL: luaF_freeupval(L, gco2uv(o)); break; |
| 384 | case LUA_TTABLE: luaH_free(L, gco2h(o)); break; | 382 | case LUA_TTABLE: luaH_free(L, gco2h(o)); break; |
| 385 | case LUA_TTHREAD: { | 383 | case LUA_TTHREAD: { |
| 386 | lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread); | 384 | lua_assert(gco2th(o) != L && gco2th(o) != G(L)->mainthread); |
| @@ -461,8 +459,8 @@ static void GCTM (lua_State *L) { | |||
| 461 | Udata *udata = rawgco2u(o); | 459 | Udata *udata = rawgco2u(o); |
| 462 | const TValue *tm; | 460 | const TValue *tm; |
| 463 | g->tmudata = udata->uv.next; /* remove udata from `tmudata' */ | 461 | g->tmudata = udata->uv.next; /* remove udata from `tmudata' */ |
| 464 | udata->uv.next = g->firstudata->uv.next; /* return it to `root' list */ | 462 | udata->uv.next = g->mainthread->next; /* return it to `root' list */ |
| 465 | g->firstudata->uv.next = o; | 463 | g->mainthread->next = o; |
| 466 | makewhite(g, o); | 464 | makewhite(g, o); |
| 467 | tm = fasttm(L, udata->uv.metatable, TM_GC); | 465 | tm = fasttm(L, udata->uv.metatable, TM_GC); |
| 468 | if (tm != NULL) { | 466 | if (tm != NULL) { |
| @@ -510,18 +508,11 @@ static void markroot (lua_State *L) { | |||
| 510 | 508 | ||
| 511 | 509 | ||
| 512 | static void remarkupvals (global_State *g) { | 510 | static void remarkupvals (global_State *g) { |
| 513 | GCObject *o; | 511 | UpVal *uv; |
| 514 | for (o = obj2gco(g->mainthread); o; o = o->gch.next) { | 512 | for (uv = g->uvhead.u.l.next; uv != &g->uvhead; uv = uv->u.l.next) { |
| 515 | lua_assert(!isblack(o)); | 513 | lua_assert(uv->u.l.next->u.l.prev == uv && uv->u.l.prev->u.l.next == uv); |
| 516 | if (iswhite(o)) { | 514 | if (isgray(obj2gco(uv))) |
| 517 | GCObject *curr; | 515 | markvalue(g, uv->v); |
| 518 | for (curr = gco2th(o)->openupval; curr != NULL; curr = curr->gch.next) { | ||
| 519 | if (isgray(curr)) { | ||
| 520 | UpVal *uv = gco2uv(curr); | ||
| 521 | markvalue(g, uv->v); | ||
| 522 | } | ||
| 523 | } | ||
| 524 | } | ||
| 525 | } | 516 | } |
| 526 | } | 517 | } |
| 527 | 518 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.h,v 2.8 2004/12/04 18:10:22 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 2.9 2005/01/05 18:20:51 roberto Exp $ |
| 3 | ** Type definitions for Lua objects | 3 | ** Type definitions for Lua objects |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -271,7 +271,13 @@ typedef struct LocVar { | |||
| 271 | typedef struct UpVal { | 271 | typedef struct UpVal { |
| 272 | CommonHeader; | 272 | CommonHeader; |
| 273 | TValue *v; /* points to stack or to its own value */ | 273 | TValue *v; /* points to stack or to its own value */ |
| 274 | TValue value; /* the value (when closed) */ | 274 | union { |
| 275 | TValue value; /* the value (when closed) */ | ||
| 276 | struct { /* double linked list (when open) */ | ||
| 277 | struct UpVal *prev; | ||
| 278 | struct UpVal *next; | ||
| 279 | } l; | ||
| 280 | } u; | ||
| 275 | } UpVal; | 281 | } UpVal; |
| 276 | 282 | ||
| 277 | 283 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.c,v 2.21 2005/01/05 18:20:51 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 2.22 2005/01/14 14:19:42 roberto Exp $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -76,16 +76,8 @@ static void freestack (lua_State *L, lua_State *L1) { | |||
| 76 | ** open parts that may cause memory-allocation errors | 76 | ** open parts that may cause memory-allocation errors |
| 77 | */ | 77 | */ |
| 78 | static void f_luaopen (lua_State *L, void *ud) { | 78 | static void f_luaopen (lua_State *L, void *ud) { |
| 79 | Udata *u; /* head of udata list */ | ||
| 80 | global_State *g = G(L); | 79 | global_State *g = G(L); |
| 81 | UNUSED(ud); | 80 | UNUSED(ud); |
| 82 | u = luaM_new(L, Udata); | ||
| 83 | u->uv.len = 0; | ||
| 84 | u->uv.metatable = NULL; | ||
| 85 | g->firstudata = obj2gco(u); | ||
| 86 | luaC_link(L, obj2gco(u), LUA_TUSERDATA); | ||
| 87 | setbit(u->uv.marked, FIXEDBIT); | ||
| 88 | setbit(L->marked, FIXEDBIT); | ||
| 89 | stack_init(L, L); /* init stack */ | 81 | stack_init(L, L); /* init stack */ |
| 90 | sethvalue(L, gt(L), luaH_new(L, 0, 20)); /* table of globals */ | 82 | sethvalue(L, gt(L), luaH_new(L, 0, 20)); /* table of globals */ |
| 91 | hvalue(gt(L))->metatable = luaH_new(L, 0, 0); /* globals metatable */ | 83 | hvalue(gt(L))->metatable = luaH_new(L, 0, 0); /* globals metatable */ |
| @@ -100,8 +92,6 @@ static void f_luaopen (lua_State *L, void *ud) { | |||
| 100 | 92 | ||
| 101 | static void preinit_state (lua_State *L, global_State *g) { | 93 | static void preinit_state (lua_State *L, global_State *g) { |
| 102 | L->l_G = g; | 94 | L->l_G = g; |
| 103 | L->tt = LUA_TTHREAD; | ||
| 104 | L->marked = luaC_white(g); | ||
| 105 | L->stack = NULL; | 95 | L->stack = NULL; |
| 106 | L->stacksize = 0; | 96 | L->stacksize = 0; |
| 107 | L->errorJmp = NULL; | 97 | L->errorJmp = NULL; |
| @@ -136,8 +126,7 @@ static void close_state (lua_State *L) { | |||
| 136 | 126 | ||
| 137 | lua_State *luaE_newthread (lua_State *L) { | 127 | lua_State *luaE_newthread (lua_State *L) { |
| 138 | lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State))); | 128 | lua_State *L1 = tostate(luaM_malloc(L, state_size(lua_State))); |
| 139 | L1->next = L->next; /* link new thread after `L' */ | 129 | luaC_link(L, obj2gco(L1), LUA_TTHREAD); |
| 140 | L->next = obj2gco(L1); | ||
| 141 | preinit_state(L1, G(L)); | 130 | preinit_state(L1, G(L)); |
| 142 | stack_init(L1, L); /* init stack */ | 131 | stack_init(L1, L); /* init stack */ |
| 143 | setobj2n(L, gt(L1), gt(L)); /* share table of globals */ | 132 | setobj2n(L, gt(L1), gt(L)); /* share table of globals */ |
| @@ -166,11 +155,15 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { | |||
| 166 | L = tostate(l); | 155 | L = tostate(l); |
| 167 | g = &((LG *)L)->g; | 156 | g = &((LG *)L)->g; |
| 168 | L->next = NULL; | 157 | L->next = NULL; |
| 169 | g->currentwhite = bitmask(WHITE0BIT); | 158 | L->tt = LUA_TTHREAD; |
| 159 | L->marked = g->currentwhite = bitmask(WHITE0BIT); | ||
| 160 | setbit(L->marked, FIXEDBIT); | ||
| 170 | preinit_state(L, g); | 161 | preinit_state(L, g); |
| 171 | g->realloc = f; | 162 | g->realloc = f; |
| 172 | g->ud = ud; | 163 | g->ud = ud; |
| 173 | g->mainthread = L; | 164 | g->mainthread = L; |
| 165 | g->uvhead.u.l.prev = &g->uvhead; | ||
| 166 | g->uvhead.u.l.next = &g->uvhead; | ||
| 174 | g->GCthreshold = 0; /* mark it as unfinished state */ | 167 | g->GCthreshold = 0; /* mark it as unfinished state */ |
| 175 | g->strt.size = 0; | 168 | g->strt.size = 0; |
| 176 | g->strt.nuse = 0; | 169 | g->strt.nuse = 0; |
| @@ -182,7 +175,6 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { | |||
| 182 | g->rootgc = obj2gco(L); | 175 | g->rootgc = obj2gco(L); |
| 183 | g->sweepstrgc = 0; | 176 | g->sweepstrgc = 0; |
| 184 | g->sweepgc = &g->rootgc; | 177 | g->sweepgc = &g->rootgc; |
| 185 | g->firstudata = NULL; | ||
| 186 | g->gray = NULL; | 178 | g->gray = NULL; |
| 187 | g->grayagain = NULL; | 179 | g->grayagain = NULL; |
| 188 | g->weak = NULL; | 180 | g->weak = NULL; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstate.h,v 2.11 2005/01/05 18:20:51 roberto Exp roberto $ | 2 | ** $Id: lstate.h,v 2.12 2005/01/14 14:19:42 roberto Exp $ |
| 3 | ** Global State | 3 | ** Global State |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -72,7 +72,6 @@ typedef struct global_State { | |||
| 72 | lu_byte currentwhite; | 72 | lu_byte currentwhite; |
| 73 | lu_byte gcstate; /* state of garbage collector */ | 73 | lu_byte gcstate; /* state of garbage collector */ |
| 74 | GCObject *rootgc; /* list of all collectable objects */ | 74 | GCObject *rootgc; /* list of all collectable objects */ |
| 75 | GCObject *firstudata; /* udata go to the end of `rootgc' */ | ||
| 76 | GCObject **sweepgc; /* position of sweep in `rootgc' */ | 75 | GCObject **sweepgc; /* position of sweep in `rootgc' */ |
| 77 | int sweepstrgc; /* position of sweep in `strt' */ | 76 | int sweepstrgc; /* position of sweep in `strt' */ |
| 78 | GCObject *gray; /* list of gray objects */ | 77 | GCObject *gray; /* list of gray objects */ |
| @@ -89,6 +88,7 @@ typedef struct global_State { | |||
| 89 | lua_CFunction panic; /* to be called in unprotected errors */ | 88 | lua_CFunction panic; /* to be called in unprotected errors */ |
| 90 | TValue _registry; | 89 | TValue _registry; |
| 91 | struct lua_State *mainthread; | 90 | struct lua_State *mainthread; |
| 91 | UpVal uvhead; /* head of double-linked list of all open upvalues */ | ||
| 92 | TString *tmname[TM_N]; /* array with tag-method names */ | 92 | TString *tmname[TM_N]; /* array with tag-method names */ |
| 93 | } global_State; | 93 | } global_State; |
| 94 | 94 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lstring.c,v 2.4 2004/11/19 15:52:40 roberto Exp roberto $ | 2 | ** $Id: lstring.c,v 2.5 2004/11/24 19:16:03 roberto Exp $ |
| 3 | ** String table (keeps all strings handled by Lua) | 3 | ** String table (keeps all strings handled by Lua) |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -102,9 +102,9 @@ Udata *luaS_newudata (lua_State *L, size_t s) { | |||
| 102 | u->uv.tt = LUA_TUSERDATA; | 102 | u->uv.tt = LUA_TUSERDATA; |
| 103 | u->uv.len = s; | 103 | u->uv.len = s; |
| 104 | u->uv.metatable = NULL; | 104 | u->uv.metatable = NULL; |
| 105 | /* chain it on udata list */ | 105 | /* chain it on udata list (after main thread) */ |
| 106 | u->uv.next = G(L)->firstudata->uv.next; | 106 | u->uv.next = G(L)->mainthread->next; |
| 107 | G(L)->firstudata->uv.next = obj2gco(u); | 107 | G(L)->mainthread->next = obj2gco(u); |
| 108 | return u; | 108 | return u; |
| 109 | } | 109 | } |
| 110 | 110 | ||
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltests.c,v 2.16 2005/01/05 18:20:51 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 2.17 2005/01/14 14:19:42 roberto Exp $ |
| 3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -299,7 +299,7 @@ printf(">>> %d %s %02x\n", g->gcstate, luaT_typenames[o->gch.tt], o->gch.marke | |||
| 299 | switch (o->gch.tt) { | 299 | switch (o->gch.tt) { |
| 300 | case LUA_TUPVAL: { | 300 | case LUA_TUPVAL: { |
| 301 | UpVal *uv = gco2uv(o); | 301 | UpVal *uv = gco2uv(o); |
| 302 | lua_assert(uv->v == &uv->value); /* must be closed */ | 302 | lua_assert(uv->v == &uv->u.value); /* must be closed */ |
| 303 | checkvalref(g, o, uv->v); | 303 | checkvalref(g, o, uv->v); |
| 304 | break; | 304 | break; |
| 305 | } | 305 | } |
| @@ -334,14 +334,11 @@ int lua_checkmemory (lua_State *L) { | |||
| 334 | global_State *g = G(L); | 334 | global_State *g = G(L); |
| 335 | GCObject *o; | 335 | GCObject *o; |
| 336 | checkstack(g, g->mainthread); | 336 | checkstack(g, g->mainthread); |
| 337 | for (o = g->rootgc; o->gch.tt != LUA_TUSERDATA; o = o->gch.next) | 337 | for (o = g->rootgc; o != obj2gco(g->mainthread); o = o->gch.next) |
| 338 | checkobject(g, o); | 338 | checkobject(g, o); |
| 339 | lua_assert(o == g->firstudata); | 339 | checkobject(g, obj2gco(g->mainthread)); |
| 340 | for (; o->gch.tt != LUA_TTHREAD; o = o->gch.next) | 340 | for (o = g->mainthread->next; o != NULL; o = o->gch.next) { |
| 341 | checkobject(g, o); | 341 | lua_assert(o->gch.tt == LUA_TUSERDATA); |
| 342 | lua_assert(o == obj2gco(g->mainthread)); | ||
| 343 | for (; o; o = o->gch.next) { | ||
| 344 | lua_assert(o->gch.tt == LUA_TTHREAD); | ||
| 345 | checkobject(g, o); | 342 | checkobject(g, o); |
| 346 | } | 343 | } |
| 347 | return 0; | 344 | return 0; |
