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; |