diff options
-rw-r--r-- | lapi.c | 8 | ||||
-rw-r--r-- | lfunc.c | 4 | ||||
-rw-r--r-- | lgc.c | 26 | ||||
-rw-r--r-- | lgc.h | 20 | ||||
-rw-r--r-- | lparser.c | 3 | ||||
-rw-r--r-- | lstate.c | 17 | ||||
-rw-r--r-- | lstring.h | 4 | ||||
-rw-r--r-- | ltests.c | 57 | ||||
-rw-r--r-- | lundump.c | 7 | ||||
-rw-r--r-- | lvm.c | 3 |
10 files changed, 96 insertions, 53 deletions
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lapi.c,v 2.185 2013/07/05 14:29:51 roberto Exp roberto $ | 2 | ** $Id: lapi.c,v 2.186 2013/08/05 16:58:28 roberto Exp roberto $ |
3 | ** Lua API | 3 | ** Lua API |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -586,8 +586,11 @@ LUA_API void lua_pushcclosure (lua_State *L, lua_CFunction fn, int n) { | |||
586 | cl = luaF_newCclosure(L, n); | 586 | cl = luaF_newCclosure(L, n); |
587 | cl->c.f = fn; | 587 | cl->c.f = fn; |
588 | L->top -= n; | 588 | L->top -= n; |
589 | while (n--) | 589 | while (n--) { |
590 | setobj2n(L, &cl->c.upvalue[n], L->top + n); | 590 | setobj2n(L, &cl->c.upvalue[n], L->top + n); |
591 | /* does not need barrier because closure is white */ | ||
592 | valnolocal(L->top + n); /* but needs 'local barrier' */ | ||
593 | } | ||
591 | setclCvalue(L, L->top, cl); | 594 | setclCvalue(L, L->top, cl); |
592 | } | 595 | } |
593 | api_incr_top(L); | 596 | api_incr_top(L); |
@@ -861,6 +864,7 @@ LUA_API int lua_setmetatable (lua_State *L, int objindex) { | |||
861 | } | 864 | } |
862 | default: { | 865 | default: { |
863 | G(L)->mt[ttnov(obj)] = mt; | 866 | G(L)->mt[ttnov(obj)] = mt; |
867 | if (mt) nolocal(obj2gco(mt)); | ||
864 | break; | 868 | break; |
865 | } | 869 | } |
866 | } | 870 | } |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lfunc.c,v 2.31 2013/08/05 16:58:28 roberto Exp roberto $ | 2 | ** $Id: lfunc.c,v 2.32 2013/08/07 12:18:11 roberto Exp roberto $ |
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 | */ |
@@ -80,6 +80,7 @@ void luaF_close (lua_State *L, StkId level) { | |||
80 | uv->v = &uv->value; /* now current value lives here */ | 80 | uv->v = &uv->value; /* now current value lives here */ |
81 | gch(o)->next = g->allgc; /* link upvalue into 'allgc' list */ | 81 | gch(o)->next = g->allgc; /* link upvalue into 'allgc' list */ |
82 | g->allgc = o; | 82 | g->allgc = o; |
83 | valnolocal(uv->v); /* keep local invariant */ | ||
83 | luaC_checkupvalcolor(g, uv); | 84 | luaC_checkupvalcolor(g, uv); |
84 | } | 85 | } |
85 | } | 86 | } |
@@ -88,6 +89,7 @@ void luaF_close (lua_State *L, StkId level) { | |||
88 | 89 | ||
89 | Proto *luaF_newproto (lua_State *L) { | 90 | Proto *luaF_newproto (lua_State *L) { |
90 | Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto), NULL, 0)->p; | 91 | Proto *f = &luaC_newobj(L, LUA_TPROTO, sizeof(Proto), NULL, 0)->p; |
92 | nolocal(obj2gco(f)); /* prototypes are never local */ | ||
91 | f->k = NULL; | 93 | f->k = NULL; |
92 | f->sizek = 0; | 94 | f->sizek = 0; |
93 | f->p = NULL; | 95 | f->p = NULL; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.c,v 2.144 2013/08/07 15:39:09 roberto Exp roberto $ | 2 | ** $Id: lgc.c,v 2.145 2013/08/13 17:36:44 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 | */ |
@@ -74,11 +74,19 @@ | |||
74 | lua_longassert(!iscollectable(obj) || righttt(obj)) | 74 | lua_longassert(!iscollectable(obj) || righttt(obj)) |
75 | 75 | ||
76 | 76 | ||
77 | #define markvalue(g,o) { checkconsistency(o); \ | 77 | #define marklocalvalue(g,o) { checkconsistency(o); \ |
78 | if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } | 78 | if (valiswhite(o)) reallymarkobject(g,gcvalue(o)); } |
79 | 79 | ||
80 | #define markobject(g,t) { if ((t) && iswhite(obj2gco(t))) \ | 80 | #define markvalue(g,o) { \ |
81 | reallymarkobject(g, obj2gco(t)); } | 81 | lua_longassert(!(iscollectable(o) && islocal(gcvalue(o)))); \ |
82 | marklocalvalue(g,o); } | ||
83 | |||
84 | #define marklocalobject(g,t) { \ | ||
85 | if ((t) && iswhite(obj2gco(t))) \ | ||
86 | reallymarkobject(g, obj2gco(t)); } | ||
87 | |||
88 | #define markobject(g,t) \ | ||
89 | { lua_assert((t) == NULL || !islocal(obj2gco(t))); marklocalobject(g,t); } | ||
82 | 90 | ||
83 | static void reallymarkobject (global_State *g, GCObject *o); | 91 | static void reallymarkobject (global_State *g, GCObject *o); |
84 | 92 | ||
@@ -259,7 +267,7 @@ static void reallymarkobject (global_State *g, GCObject *o) { | |||
259 | } | 267 | } |
260 | case LUA_TUPVAL: { | 268 | case LUA_TUPVAL: { |
261 | UpVal *uv = gco2uv(o); | 269 | UpVal *uv = gco2uv(o); |
262 | markvalue(g, uv->v); | 270 | marklocalvalue(g, uv->v); |
263 | if (uv->v != &uv->value) /* open? */ | 271 | if (uv->v != &uv->value) /* open? */ |
264 | return; /* open upvalues remain gray */ | 272 | return; /* open upvalues remain gray */ |
265 | size = sizeof(UpVal); | 273 | size = sizeof(UpVal); |
@@ -331,7 +339,7 @@ static void remarkupvals (global_State *g) { | |||
331 | GCObject *uv = gco2th(thread)->openupval; | 339 | GCObject *uv = gco2th(thread)->openupval; |
332 | for (; uv != NULL; uv = gch(uv)->next) { | 340 | for (; uv != NULL; uv = gch(uv)->next) { |
333 | if (isgray(uv)) /* marked? */ | 341 | if (isgray(uv)) /* marked? */ |
334 | markvalue(g, gco2uv(uv)->v); /* remark upvalue's value */ | 342 | marklocalvalue(g, gco2uv(uv)->v); /* remark upvalue's value */ |
335 | } | 343 | } |
336 | } | 344 | } |
337 | } | 345 | } |
@@ -486,7 +494,7 @@ static int traverseproto (global_State *g, Proto *f) { | |||
486 | static lu_mem traverseCclosure (global_State *g, CClosure *cl) { | 494 | static lu_mem traverseCclosure (global_State *g, CClosure *cl) { |
487 | int i; | 495 | int i; |
488 | for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ | 496 | for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ |
489 | markvalue(g, &cl->upvalue[i]); | 497 | marklocalvalue(g, &cl->upvalue[i]); |
490 | return sizeCclosure(cl->nupvalues); | 498 | return sizeCclosure(cl->nupvalues); |
491 | } | 499 | } |
492 | 500 | ||
@@ -494,7 +502,7 @@ static lu_mem traverseLclosure (global_State *g, LClosure *cl) { | |||
494 | int i; | 502 | int i; |
495 | markobject(g, cl->p); /* mark its prototype */ | 503 | markobject(g, cl->p); /* mark its prototype */ |
496 | for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ | 504 | for (i = 0; i < cl->nupvalues; i++) /* mark its upvalues */ |
497 | markobject(g, cl->upvals[i]); | 505 | marklocalobject(g, cl->upvals[i]); |
498 | return sizeLclosure(cl->nupvalues); | 506 | return sizeLclosure(cl->nupvalues); |
499 | } | 507 | } |
500 | 508 | ||
@@ -505,7 +513,7 @@ static lu_mem traversestack (global_State *g, lua_State *th) { | |||
505 | if (o == NULL) | 513 | if (o == NULL) |
506 | return 1; /* stack not completely built yet */ | 514 | return 1; /* stack not completely built yet */ |
507 | for (; o < th->top; o++) /* mark live elements in the stack */ | 515 | for (; o < th->top; o++) /* mark live elements in the stack */ |
508 | markvalue(g, o); | 516 | marklocalvalue(g, o); |
509 | if (g->gcstate == GCSatomic) { /* final traversal? */ | 517 | if (g->gcstate == GCSatomic) { /* final traversal? */ |
510 | StkId lim = th->stack + th->stacksize; /* real end of stack */ | 518 | StkId lim = th->stack + th->stacksize; /* real end of stack */ |
511 | for (; o < lim; o++) /* clear not-marked stack slice */ | 519 | for (; o < lim; o++) /* clear not-marked stack slice */ |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lgc.h,v 2.59 2013/08/05 16:58:28 roberto Exp roberto $ | 2 | ** $Id: lgc.h,v 2.60 2013/08/13 17:36:44 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 | */ |
@@ -79,6 +79,7 @@ | |||
79 | #define FINALIZEDBIT 3 /* object has been separated for finalization */ | 79 | #define FINALIZEDBIT 3 /* object has been separated for finalization */ |
80 | #define SEPARATED 4 /* object is in 'finobj' list or in 'tobefnz' */ | 80 | #define SEPARATED 4 /* object is in 'finobj' list or in 'tobefnz' */ |
81 | #define FIXEDBIT 5 /* object is fixed (should not be collected) */ | 81 | #define FIXEDBIT 5 /* object is fixed (should not be collected) */ |
82 | #define LOCALBIT 6 /* object is not local */ | ||
82 | /* bit 7 is currently used by tests (luaL_checkmemory) */ | 83 | /* bit 7 is currently used by tests (luaL_checkmemory) */ |
83 | 84 | ||
84 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) | 85 | #define WHITEBITS bit2mask(WHITE0BIT, WHITE1BIT) |
@@ -88,6 +89,7 @@ | |||
88 | #define isblack(x) testbit((x)->gch.marked, BLACKBIT) | 89 | #define isblack(x) testbit((x)->gch.marked, BLACKBIT) |
89 | #define isgray(x) /* neither white nor black */ \ | 90 | #define isgray(x) /* neither white nor black */ \ |
90 | (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT))) | 91 | (!testbits((x)->gch.marked, WHITEBITS | bitmask(BLACKBIT))) |
92 | #define islocal(x) (!testbit((x)->gch.marked, LOCALBIT)) | ||
91 | 93 | ||
92 | 94 | ||
93 | #define otherwhite(g) (g->currentwhite ^ WHITEBITS) | 95 | #define otherwhite(g) (g->currentwhite ^ WHITEBITS) |
@@ -97,6 +99,9 @@ | |||
97 | #define changewhite(x) ((x)->gch.marked ^= WHITEBITS) | 99 | #define changewhite(x) ((x)->gch.marked ^= WHITEBITS) |
98 | #define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) | 100 | #define gray2black(x) l_setbit((x)->gch.marked, BLACKBIT) |
99 | 101 | ||
102 | #define nolocal(x) l_setbit((x)->gch.marked, LOCALBIT) | ||
103 | #define valnolocal(v) { if (iscollectable(v)) nolocal(gcvalue(v)); } | ||
104 | |||
100 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) | 105 | #define luaC_white(g) cast(lu_byte, (g)->currentwhite & WHITEBITS) |
101 | 106 | ||
102 | 107 | ||
@@ -106,22 +111,25 @@ | |||
106 | 111 | ||
107 | 112 | ||
108 | #define luaC_barrier(L,p,v) { \ | 113 | #define luaC_barrier(L,p,v) { \ |
109 | if (iscollectable(v) && isblack(obj2gco(p)) && iswhite(gcvalue(v))) \ | 114 | if (iscollectable(v) && \ |
115 | (nolocal(gcvalue(v)), isblack(obj2gco(p)) && iswhite(gcvalue(v)))) \ | ||
110 | luaC_barrier_(L,obj2gco(p),gcvalue(v)); } | 116 | luaC_barrier_(L,obj2gco(p),gcvalue(v)); } |
111 | 117 | ||
112 | #define luaC_barrierback(L,p,v) { \ | 118 | #define luaC_barrierback(L,p,v) { \ |
113 | if (iscollectable(v) && isblack(obj2gco(p)) && iswhite(gcvalue(v))) \ | 119 | if (iscollectable(v) && \ |
120 | (nolocal(gcvalue(v)), isblack(obj2gco(p)) && iswhite(gcvalue(v)))) \ | ||
114 | luaC_barrierback_(L,p); } | 121 | luaC_barrierback_(L,p); } |
115 | 122 | ||
116 | #define luaC_objbarrier(L,p,o) { \ | 123 | #define luaC_objbarrier(L,p,o) { \ |
117 | if (isblack(obj2gco(p)) && iswhite(obj2gco(o))) \ | 124 | if (nolocal(obj2gco(o)), isblack(obj2gco(p)) && iswhite(obj2gco(o))) \ |
118 | luaC_barrier_(L,obj2gco(p),obj2gco(o)); } | 125 | luaC_barrier_(L,obj2gco(p),obj2gco(o)); } |
119 | 126 | ||
120 | #define luaC_objbarrierback(L,p,o) \ | 127 | #define luaC_objbarrierback(L,p,o) \ |
121 | { if (isblack(obj2gco(p)) && iswhite(obj2gco(o))) luaC_barrierback_(L,p); } | 128 | { if (nolocal(obj2gco(o)), isblack(obj2gco(p)) && iswhite(obj2gco(o))) \ |
129 | luaC_barrierback_(L,p); } | ||
122 | 130 | ||
123 | #define luaC_barrierproto(L,p,c) \ | 131 | #define luaC_barrierproto(L,p,c) \ |
124 | { if (isblack(obj2gco(p))) luaC_barrierproto_(L,p,c); } | 132 | { if (nolocal(obj2gco(c)), isblack(obj2gco(p))) luaC_barrierproto_(L,p,c); } |
125 | 133 | ||
126 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); | 134 | LUAI_FUNC void luaC_freeallobjects (lua_State *L); |
127 | LUAI_FUNC void luaC_step (lua_State *L); | 135 | LUAI_FUNC void luaC_step (lua_State *L); |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lparser.c,v 2.132 2013/04/25 19:35:19 roberto Exp roberto $ | 2 | ** $Id: lparser.c,v 2.133 2013/04/26 13:07:53 roberto Exp roberto $ |
3 | ** Lua Parser | 3 | ** Lua Parser |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -1632,6 +1632,7 @@ Closure *luaY_parser (lua_State *L, ZIO *z, Mbuffer *buff, | |||
1632 | incr_top(L); | 1632 | incr_top(L); |
1633 | funcstate.f = cl->l.p = luaF_newproto(L); | 1633 | funcstate.f = cl->l.p = luaF_newproto(L); |
1634 | funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ | 1634 | funcstate.f->source = luaS_new(L, name); /* create and anchor TString */ |
1635 | luaC_objbarrier(L, funcstate.f, funcstate.f->source); | ||
1635 | lexstate.buff = buff; | 1636 | lexstate.buff = buff; |
1636 | lexstate.dyd = dyd; | 1637 | lexstate.dyd = dyd; |
1637 | dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; | 1638 | dyd->actvar.n = dyd->gt.n = dyd->label.n = 0; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstate.c,v 2.100 2013/08/05 16:58:28 roberto Exp roberto $ | 2 | ** $Id: lstate.c,v 2.101 2013/08/07 12:18:11 roberto Exp roberto $ |
3 | ** Global State | 3 | ** Global State |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -159,17 +159,19 @@ static void freestack (lua_State *L) { | |||
159 | ** Create registry table and its predefined values | 159 | ** Create registry table and its predefined values |
160 | */ | 160 | */ |
161 | static void init_registry (lua_State *L, global_State *g) { | 161 | static void init_registry (lua_State *L, global_State *g) { |
162 | TValue mt; | 162 | TValue temp; |
163 | /* create registry */ | 163 | /* create registry */ |
164 | Table *registry = luaH_new(L); | 164 | Table *registry = luaH_new(L); |
165 | sethvalue(L, &g->l_registry, registry); | 165 | sethvalue(L, &g->l_registry, registry); |
166 | luaH_resize(L, registry, LUA_RIDX_LAST, 0); | 166 | luaH_resize(L, registry, LUA_RIDX_LAST, 0); |
167 | nolocal(obj2gco(registry)); | ||
167 | /* registry[LUA_RIDX_MAINTHREAD] = L */ | 168 | /* registry[LUA_RIDX_MAINTHREAD] = L */ |
168 | setthvalue(L, &mt, L); | 169 | setthvalue(L, &temp, L); /* temp = L */ |
169 | luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &mt); | 170 | luaH_setint(L, registry, LUA_RIDX_MAINTHREAD, &temp); |
170 | /* registry[LUA_RIDX_GLOBALS] = table of globals */ | 171 | /* registry[LUA_RIDX_GLOBALS] = table of globals */ |
171 | sethvalue(L, &mt, luaH_new(L)); | 172 | sethvalue(L, &temp, luaH_new(L)); /* temp = new table (global table) */ |
172 | luaH_setint(L, registry, LUA_RIDX_GLOBALS, &mt); | 173 | luaH_setint(L, registry, LUA_RIDX_GLOBALS, &temp); |
174 | valnolocal(&temp); /* keep local invariant */ | ||
173 | } | 175 | } |
174 | 176 | ||
175 | 177 | ||
@@ -236,6 +238,7 @@ LUA_API lua_State *lua_newthread (lua_State *L) { | |||
236 | setthvalue(L, L->top, L1); | 238 | setthvalue(L, L->top, L1); |
237 | api_incr_top(L); | 239 | api_incr_top(L); |
238 | preinit_state(L1, G(L)); | 240 | preinit_state(L1, G(L)); |
241 | nolocal(obj2gco(L1)); /* threads are never local */ | ||
239 | L1->hookmask = L->hookmask; | 242 | L1->hookmask = L->hookmask; |
240 | L1->basehookcount = L->basehookcount; | 243 | L1->basehookcount = L->basehookcount; |
241 | L1->hook = L->hook; | 244 | L1->hook = L->hook; |
@@ -268,7 +271,7 @@ LUA_API lua_State *lua_newstate (lua_Alloc f, void *ud) { | |||
268 | L->next = NULL; | 271 | L->next = NULL; |
269 | L->tt = LUA_TTHREAD; | 272 | L->tt = LUA_TTHREAD; |
270 | g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); | 273 | g->currentwhite = bit2mask(WHITE0BIT, FIXEDBIT); |
271 | L->marked = luaC_white(g); | 274 | L->marked = luaC_white(g) | bitmask(LOCALBIT); |
272 | g->gckind = KGC_NORMAL; | 275 | g->gckind = KGC_NORMAL; |
273 | preinit_state(L, g); | 276 | preinit_state(L, g); |
274 | g->frealloc = f; | 277 | g->frealloc = f; |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lstring.h,v 1.48 2012/01/25 21:05:40 roberto Exp roberto $ | 2 | ** $Id: lstring.h,v 1.49 2012/02/01 21:57:15 roberto Exp roberto $ |
3 | ** String table (keep all strings handled by Lua) | 3 | ** String table (keep all strings handled by Lua) |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -19,7 +19,7 @@ | |||
19 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ | 19 | #define luaS_newliteral(L, s) (luaS_newlstr(L, "" s, \ |
20 | (sizeof(s)/sizeof(char))-1)) | 20 | (sizeof(s)/sizeof(char))-1)) |
21 | 21 | ||
22 | #define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT) | 22 | #define luaS_fix(s) setbits((s)->tsv.marked, bit2mask(FIXEDBIT, LOCALBIT)) |
23 | 23 | ||
24 | 24 | ||
25 | /* | 25 | /* |
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: ltests.c,v 2.140 2013/08/05 16:58:28 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 2.141 2013/08/07 12:18:11 roberto Exp roberto $ |
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 | */ |
@@ -188,6 +188,25 @@ static int testobjref1 (global_State *g, GCObject *f, GCObject *t) { | |||
188 | } | 188 | } |
189 | 189 | ||
190 | 190 | ||
191 | /* | ||
192 | ** Check locality | ||
193 | */ | ||
194 | static int testobjref2 (GCObject *f, GCObject *t) { | ||
195 | /* not a local or pointed by a thread? */ | ||
196 | if (!islocal(t) || gch(f)->tt == LUA_TTHREAD) | ||
197 | return 1; /* ok */ | ||
198 | if (gch(t)->tt == LUA_TUPVAL) { | ||
199 | lua_assert(gch(f)->tt == LUA_TLCL); | ||
200 | return 1; /* upvalue pointed by a closure */ | ||
201 | } | ||
202 | if (gch(f)->tt == LUA_TUPVAL) { | ||
203 | UpVal *uv = gco2uv(f); | ||
204 | return (uv->v != &uv->value); /* open upvalue can point to local stuff */ | ||
205 | } | ||
206 | return 0; | ||
207 | } | ||
208 | |||
209 | |||
191 | static void printobj (global_State *g, GCObject *o) { | 210 | static void printobj (global_State *g, GCObject *o) { |
192 | int i = 1; | 211 | int i = 1; |
193 | GCObject *p; | 212 | GCObject *p; |
@@ -198,24 +217,30 @@ static void printobj (global_State *g, GCObject *o) { | |||
198 | if (p == NULL) i = 0; /* zero means 'not found' */ | 217 | if (p == NULL) i = 0; /* zero means 'not found' */ |
199 | else i = -i; /* negative means 'found in findobj list */ | 218 | else i = -i; /* negative means 'found in findobj list */ |
200 | } | 219 | } |
201 | printf("||%d:%s(%p)-%c(%02X)||", i, ttypename(gch(o)->tt), (void *)o, | 220 | printf("||%d:%s(%p)-%s-%c(%02X)||", |
221 | i, ttypename(novariant(gch(o)->tt)), (void *)o, | ||
222 | islocal(o)?"L":"NL", | ||
202 | isdead(g,o)?'d':isblack(o)?'b':iswhite(o)?'w':'g', gch(o)->marked); | 223 | isdead(g,o)?'d':isblack(o)?'b':iswhite(o)?'w':'g', gch(o)->marked); |
203 | } | 224 | } |
204 | 225 | ||
205 | 226 | ||
206 | static int testobjref (global_State *g, GCObject *f, GCObject *t) { | 227 | static int testobjref (global_State *g, GCObject *f, GCObject *t) { |
207 | int r = testobjref1(g,f,t); | 228 | int r1 = testobjref1(g,f,t); |
208 | if (!r) { | 229 | int r2 = testobjref2(f,t); |
209 | printf("%d(%02X) - ", g->gcstate, g->currentwhite); | 230 | if (!r1 || !r2) { |
231 | if (!r1) | ||
232 | printf("%d(%02X) - ", g->gcstate, g->currentwhite); | ||
233 | else | ||
234 | printf("local violation - "); | ||
210 | printobj(g, f); | 235 | printobj(g, f); |
211 | printf("\t-> "); | 236 | printf(" -> "); |
212 | printobj(g, t); | 237 | printobj(g, t); |
213 | printf("\n"); | 238 | printf("\n"); |
214 | } | 239 | } |
215 | return r; | 240 | return r1 && r2; |
216 | } | 241 | } |
217 | 242 | ||
218 | #define checkobjref(g,f,t) lua_assert(testobjref(g,f,obj2gco(t))) | 243 | #define checkobjref(g,f,t) lua_assert(testobjref(g,f,obj2gco(t))) |
219 | 244 | ||
220 | 245 | ||
221 | static void checkvalref (global_State *g, GCObject *f, const TValue *t) { | 246 | static void checkvalref (global_State *g, GCObject *f, const TValue *t) { |
@@ -349,6 +374,7 @@ static void checkobject (global_State *g, GCObject *o, int maybedead) { | |||
349 | break; | 374 | break; |
350 | } | 375 | } |
351 | case LUA_TTHREAD: { | 376 | case LUA_TTHREAD: { |
377 | lua_assert(!islocal(o)); | ||
352 | checkstack(g, gco2th(o)); | 378 | checkstack(g, gco2th(o)); |
353 | break; | 379 | break; |
354 | } | 380 | } |
@@ -617,22 +643,9 @@ static int get_gccolor (lua_State *L) { | |||
617 | o = obj_at(L, 1); | 643 | o = obj_at(L, 1); |
618 | if (!iscollectable(o)) | 644 | if (!iscollectable(o)) |
619 | lua_pushstring(L, "no collectable"); | 645 | lua_pushstring(L, "no collectable"); |
620 | else { | 646 | else |
621 | int marked = gcvalue(o)->gch.marked; | ||
622 | int n = 1; | ||
623 | lua_pushstring(L, iswhite(gcvalue(o)) ? "white" : | 647 | lua_pushstring(L, iswhite(gcvalue(o)) ? "white" : |
624 | isblack(gcvalue(o)) ? "black" : "grey"); | 648 | isblack(gcvalue(o)) ? "black" : "grey"); |
625 | if (testbit(marked, FINALIZEDBIT)) { | ||
626 | lua_pushliteral(L, "/finalized"); n++; | ||
627 | } | ||
628 | if (testbit(marked, SEPARATED)) { | ||
629 | lua_pushliteral(L, "/separated"); n++; | ||
630 | } | ||
631 | if (testbit(marked, FIXEDBIT)) { | ||
632 | lua_pushliteral(L, "/fixed"); n++; | ||
633 | } | ||
634 | lua_concat(L, n); | ||
635 | } | ||
636 | return 1; | 649 | return 1; |
637 | } | 650 | } |
638 | 651 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lundump.c,v 2.22 2012/05/08 13:53:33 roberto Exp roberto $ | 2 | ** $Id: lundump.c,v 2.23 2013/04/26 18:48:35 roberto Exp roberto $ |
3 | ** load precompiled Lua chunks | 3 | ** load precompiled Lua chunks |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -84,9 +84,12 @@ static TString* LoadString(LoadState* S) | |||
84 | return NULL; | 84 | return NULL; |
85 | else | 85 | else |
86 | { | 86 | { |
87 | TString* ts; | ||
87 | char* s=luaZ_openspace(S->L,S->b,size); | 88 | char* s=luaZ_openspace(S->L,S->b,size); |
88 | LoadBlock(S,s,size*sizeof(char)); | 89 | LoadBlock(S,s,size*sizeof(char)); |
89 | return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ | 90 | ts = luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */ |
91 | nolocal(obj2gco(ts)); /* all strings here anchored in non-thread objects */ | ||
92 | return ts; | ||
90 | } | 93 | } |
91 | } | 94 | } |
92 | 95 | ||
@@ -1,5 +1,5 @@ | |||
1 | /* | 1 | /* |
2 | ** $Id: lvm.c,v 2.175 2013/06/20 15:02:49 roberto Exp roberto $ | 2 | ** $Id: lvm.c,v 2.176 2013/07/10 17:15:12 roberto Exp roberto $ |
3 | ** Lua virtual machine | 3 | ** Lua virtual machine |
4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
5 | */ | 5 | */ |
@@ -416,6 +416,7 @@ static void pushclosure (lua_State *L, Proto *p, UpVal **encup, StkId base, | |||
416 | ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx); | 416 | ncl->l.upvals[i] = luaF_findupval(L, base + uv[i].idx); |
417 | else /* get upvalue from enclosing function */ | 417 | else /* get upvalue from enclosing function */ |
418 | ncl->l.upvals[i] = encup[uv[i].idx]; | 418 | ncl->l.upvals[i] = encup[uv[i].idx]; |
419 | /* new closure is white and local, so we do not need a barrier here */ | ||
419 | } | 420 | } |
420 | luaC_barrierproto(L, p, ncl); | 421 | luaC_barrierproto(L, p, ncl); |
421 | p->cache = ncl; /* save it on cache for reuse */ | 422 | p->cache = ncl; /* save it on cache for reuse */ |