summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--lapi.c8
-rw-r--r--lfunc.c4
-rw-r--r--lgc.c26
-rw-r--r--lgc.h20
-rw-r--r--lparser.c3
-rw-r--r--lstate.c17
-rw-r--r--lstring.h4
-rw-r--r--ltests.c57
-rw-r--r--lundump.c7
-rw-r--r--lvm.c3
10 files changed, 96 insertions, 53 deletions
diff --git a/lapi.c b/lapi.c
index 7c7b6a10..62b5f1a3 100644
--- a/lapi.c
+++ b/lapi.c
@@ -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 }
diff --git a/lfunc.c b/lfunc.c
index 82d05656..cb0b4ef6 100644
--- a/lfunc.c
+++ b/lfunc.c
@@ -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
89Proto *luaF_newproto (lua_State *L) { 90Proto *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;
diff --git a/lgc.c b/lgc.c
index 75daf796..e4d6b6c1 100644
--- a/lgc.c
+++ b/lgc.c
@@ -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
83static void reallymarkobject (global_State *g, GCObject *o); 91static 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) {
486static lu_mem traverseCclosure (global_State *g, CClosure *cl) { 494static 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 */
diff --git a/lgc.h b/lgc.h
index 4e38c0fc..846d40d8 100644
--- a/lgc.h
+++ b/lgc.h
@@ -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
126LUAI_FUNC void luaC_freeallobjects (lua_State *L); 134LUAI_FUNC void luaC_freeallobjects (lua_State *L);
127LUAI_FUNC void luaC_step (lua_State *L); 135LUAI_FUNC void luaC_step (lua_State *L);
diff --git a/lparser.c b/lparser.c
index 2cc226d4..c2386b82 100644
--- a/lparser.c
+++ b/lparser.c
@@ -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;
diff --git a/lstate.c b/lstate.c
index 9c4130a8..a9c321d5 100644
--- a/lstate.c
+++ b/lstate.c
@@ -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*/
161static void init_registry (lua_State *L, global_State *g) { 161static 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;
diff --git a/lstring.h b/lstring.h
index b52a9356..644b5aae 100644
--- a/lstring.h
+++ b/lstring.h
@@ -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/*
diff --git a/ltests.c b/ltests.c
index e45a82cf..4e087435 100644
--- a/ltests.c
+++ b/ltests.c
@@ -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*/
194static 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
191static void printobj (global_State *g, GCObject *o) { 210static 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
206static int testobjref (global_State *g, GCObject *f, GCObject *t) { 227static 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
221static void checkvalref (global_State *g, GCObject *f, const TValue *t) { 246static 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
diff --git a/lundump.c b/lundump.c
index 0a8db845..be77d98e 100644
--- a/lundump.c
+++ b/lundump.c
@@ -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
diff --git a/lvm.c b/lvm.c
index 67aa58f8..7f86a16c 100644
--- a/lvm.c
+++ b/lvm.c
@@ -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 */