12 const char lua_ident[] =
13 @@ -117,6 +117,7 @@ LUA_API void lua_xmove (lua_State *from,
15 for (i = 0; i < n; i++) {
16 setobj2s(to, to->top++, from->top + i);
17 + setnilvalue(from, from->top + i);
21 @@ -166,12 +167,16 @@ LUA_API void lua_settop (lua_State *L, i
23 api_check(L, idx <= L->stack_last - L->base);
24 while (L->top < L->base + idx)
25 - setnilvalue(L->top++);
26 + setnilvalue(L, L->top++);
27 L->top = L->base + idx;
28 + setnilvalue(L, L->top);
32 api_check(L, -(idx+1) <= (L->top - L->base));
33 L->top += idx+1; /* `subtract' index (index is negative) */
34 + for (i = 0; i < -(idx+1); i++)
35 + setnilvalue(L, L->top + i);
39 @@ -184,6 +189,7 @@ LUA_API void lua_remove (lua_State *L, i
40 api_checkvalidindex(L, p);
41 while (++p < L->top) setobjs2s(L, p-1, p);
43 + setnilvalue(L, L->top);
47 @@ -196,6 +202,7 @@ LUA_API void lua_insert (lua_State *L, i
48 api_checkvalidindex(L, p);
49 for (q = L->top; q>p; q--) setobjs2s(L, q, q-1);
50 setobjs2s(L, p, L->top);
51 + setnilvalue(L, L->top);
55 @@ -221,6 +228,7 @@ LUA_API void lua_replace (lua_State *L,
56 luaC_barrier(L, curr_func(L), L->top - 1);
59 + setnilvalue(L, L->top);
63 @@ -259,14 +267,14 @@ LUA_API int lua_iscfunction (lua_State *
66 LUA_API int lua_isnumber (lua_State *L, int idx) {
68 + TValue n = tvinit();
69 const TValue *o = index2adr(L, idx);
70 return tonumber(o, &n);
74 LUA_API int lua_isinteger (lua_State *L, int idx) {
76 + TValue tmp = tvinit();
78 const TValue *o = index2adr(L, idx);
79 return tonumber(o,&tmp) && (ttisint(o) || tt_integer_valued(o,&dum));
80 @@ -319,7 +327,7 @@ LUA_API int lua_lessthan (lua_State *L,
83 LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
85 + TValue n = tvinit();
86 const TValue *o = index2adr(L, idx);
87 if (tonumber(o, &n)) {
89 @@ -333,7 +341,7 @@ LUA_API lua_Number lua_tonumber (lua_Sta
92 LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
94 + TValue n = tvinit();
95 /* Lua 5.1 documented behaviour is to return nonzero for non-integer:
96 * "If the number is not an integer, it is truncated in some non-specified way."
97 * I would suggest to change this, to return 0 for anything that would
98 @@ -369,7 +377,7 @@ LUA_API lua_Integer lua_tointeger (lua_S
101 LUA_API lua_Complex lua_tocomplex (lua_State *L, int idx) {
103 + TValue tmp = tvinit();
104 const TValue *o = index2adr(L, idx);
105 if (tonumber(o, &tmp))
106 return nvalue_complex(o);
107 @@ -465,7 +473,7 @@ LUA_API const void *lua_topointer (lua_S
109 LUA_API void lua_pushnil (lua_State *L) {
111 - setnilvalue(L->top);
112 + setnilvalue(L, L->top);
116 @@ -548,8 +556,10 @@ LUA_API void lua_pushcclosure (lua_State
117 cl = luaF_newCclosure(L, n, getcurrenv(L));
122 setobj2n(L, &cl->c.upvalue[n], L->top+n);
123 + setnilvalue(L, L->top + n);
125 setclvalue(L, L->top, cl);
126 lua_assert(iswhite(obj2gco(cl)));
128 @@ -600,7 +610,7 @@ LUA_API void lua_gettable (lua_State *L,
130 LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
133 + TValue key = tvinit();
135 t = index2adr(L, idx);
136 api_checkvalidindex(L, t);
137 @@ -689,7 +699,7 @@ LUA_API void lua_getfenv (lua_State *L,
138 setobj2s(L, L->top, gt(thvalue(o)));
141 - setnilvalue(L->top);
142 + setnilvalue(L, L->top);
146 @@ -710,13 +720,15 @@ LUA_API void lua_settable (lua_State *L,
147 api_checkvalidindex(L, t);
148 luaV_settable(L, t, L->top - 2, L->top - 1);
149 L->top -= 2; /* pop index and value */
150 + setnilvalue(L, L->top);
151 + setnilvalue(L, L->top + 1);
156 LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
159 + TValue key = tvinit();
161 api_checknelems(L, 1);
162 t = index2adr(L, idx);
163 @@ -724,6 +736,7 @@ LUA_API void lua_setfield (lua_State *L,
164 setsvalue(L, &key, luaS_new(L, k));
165 luaV_settable(L, t, &key, L->top - 1);
166 L->top--; /* pop value */
167 + setnilvalue(L, L->top);
171 @@ -737,6 +750,8 @@ LUA_API void lua_rawset (lua_State *L, i
172 setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
173 luaC_barriert(L, hvalue(t), L->top-1);
175 + setnilvalue(L, L->top);
176 + setnilvalue(L, L->top + 1);
180 @@ -750,6 +765,7 @@ LUA_API void lua_rawseti (lua_State *L,
181 setobj2t(L, luaH_setint(L, hvalue(o), n), L->top-1);
182 luaC_barriert(L, hvalue(o), L->top-1);
184 + setnilvalue(L, L->top);
188 @@ -786,6 +802,7 @@ LUA_API int lua_setmetatable (lua_State
192 + setnilvalue(L, L->top);
196 @@ -815,6 +832,7 @@ LUA_API int lua_setfenv (lua_State *L, i
198 if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
200 + setnilvalue(L, L->top);
204 @@ -1040,20 +1058,25 @@ LUA_API int lua_next (lua_State *L, int
208 - else /* no more elements */
209 + else { /* no more elements */
210 L->top -= 1; /* remove key */
211 + setnilvalue(L, L->top);
218 LUA_API void lua_concat (lua_State *L, int n) {
221 api_checknelems(L, n);
224 luaV_concat(L, n, cast_int(L->top - L->base) - 1);
226 + for (i = 0; i < n - 1; i++)
227 + setnilvalue(L, L->top + i);
229 else if (n == 0) { /* push empty string */
230 setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
231 @@ -1139,6 +1162,7 @@ LUA_API const char *lua_setupvalue (lua_
234 setobj(L, val, L->top);
235 + setnilvalue(L, L->top);
236 luaC_barrier(L, clvalue(fi), L->top);
239 @@ -1160,7 +1184,7 @@ LUA_API const char *lua_setupvalue (lua_
240 int lua_pushvalue_as_number (lua_State *L, int idx)
242 const TValue *o = index2adr(L, idx);
244 + TValue tmp = tvinit();
247 if ( (!ttisint(o)) && tt_integer_valued(o,&i)) {
257 #define hasjumps(e) ((e)->t != (e)->f)
258 @@ -248,7 +249,7 @@ static int addk (FuncState *fs, TValue *
259 setivalue(idx, fs->nk);
260 luaM_growvector(L, f->k, fs->nk, f->sizek, TValue,
261 MAXARG_Bx, "constant table overflow");
262 - while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
263 + while (oldsize < f->sizek) setnilvalue(L, &f->k[oldsize++]);
264 setobj(L, &f->k[fs->nk], v);
265 luaC_barrier(L, f, v);
267 @@ -257,21 +258,24 @@ static int addk (FuncState *fs, TValue *
270 int luaK_stringK (FuncState *fs, TString *s) {
272 + TValue o = tvinit();
273 setsvalue(fs->L, &o, s);
274 + luaV_unref(fs->L, &o);
275 return addk(fs, &o, &o);
279 int luaK_numberK (FuncState *fs, lua_Number r) {
281 + lua_State *L = fs->L;
282 + TValue o = tvinit();
284 return addk(fs, &o, &o);
288 int luaK_integerK (FuncState *fs, lua_Integer r) {
290 + lua_State *L = fs->L;
291 + TValue o = tvinit();
293 return addk(fs, &o, &o);
295 @@ -279,22 +283,24 @@ int luaK_integerK (FuncState *fs, lua_In
298 static int luaK_imagK (FuncState *fs, lua_Number r) {
300 + lua_State *L = fs->L;
301 + TValue o = tvinit();
302 setnvalue_complex(&o, r*I);
303 return addk(fs, &o, &o);
307 static int boolK (FuncState *fs, int b) {
309 + lua_State *L = fs->L;
310 + TValue o = tvinit();
312 return addk(fs, &o, &o);
316 static int nilK (FuncState *fs) {
319 + TValue k = tvinit(), v = tvinit();
320 + setnilvalue(fs->L, &v);
321 /* cannot use nil as key; instead use table itself to represent nil */
322 sethvalue(fs->L, &k, fs->h);
323 return addk(fs, &k, &v);
326 @@ -176,7 +176,7 @@ static void info_tailcall (lua_Debug *ar
328 static void collectvalidlines (lua_State *L, Closure *f) {
329 if (f == NULL || f->c.isC) {
330 - setnilvalue(L->top);
331 + setnilvalue(L, L->top);
334 Table *t = luaH_new(L, 0, 0);
335 @@ -248,7 +248,7 @@ LUA_API int lua_getinfo (lua_State *L, c
337 status = auxgetinfo(L, what, ar, f, ci);
338 if (strchr(what, 'f')) {
339 - if (f == NULL) setnilvalue(L->top);
340 + if (f == NULL) setnilvalue(L, L->top);
341 else setclvalue(L, L->top, f);
344 @@ -586,7 +586,7 @@ void luaG_concaterror (lua_State *L, Stk
347 void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
349 + TValue temp = tvinit();
350 if (luaV_tonumber(p1, &temp) == NULL)
351 p2 = p1; /* first operand is wrong */
352 luaG_typeerror(L, p2, "perform arithmetic on");
355 @@ -211,7 +211,7 @@ static StkId adjust_varargs (lua_State *
358 for (; actual < nfixargs; ++actual)
359 - setnilvalue(L->top++);
360 + setnilvalue(L, L->top++);
361 #if defined(LUA_COMPAT_VARARG)
362 if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */
363 int nvar = actual - nfixargs; /* number of extra arguments */
364 @@ -229,7 +229,6 @@ static StkId adjust_varargs (lua_State *
365 base = L->top; /* final position of first argument */
366 for (i=0; i<nfixargs; i++) {
367 setobjs2s(L, L->top++, fixed+i);
368 - setnilvalue(fixed+i);
370 /* add `arg' parameter */
372 @@ -294,7 +293,7 @@ int luaD_precall (lua_State *L, StkId fu
374 ci->nresults = nresults;
375 for (st = L->top; st < ci->top; st++)
377 + setnilvalue(L, st);
379 if (L->hookmask & LUA_MASKCALL) {
380 L->savedpc++; /* hooks assume 'pc' is already incremented */
381 @@ -354,7 +353,9 @@ int luaD_poscall (lua_State *L, StkId fi
382 for (i = wanted; i != 0 && firstResult < L->top; i--)
383 setobjs2s(L, res++, firstResult++);
385 - setnilvalue(res++);
386 + setnilvalue(L, res++);
387 + for (i = (res - L->top); i-- > 0;)
388 + setnilvalue(L, L->top + i);
390 return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */
392 @@ -463,8 +464,12 @@ int luaD_pcall (lua_State *L, Pfunc func
393 status = luaD_rawrunprotected(L, func, u);
394 if (status != 0) { /* an error occurred? */
395 StkId oldtop = restorestack(L, old_top);
396 + StkId curtop = L->top;
398 luaF_close(L, oldtop); /* close eventual pending closures */
399 luaD_seterrorobj(L, status, oldtop);
400 + for (i = (curtop - L->top); i-- > 0;)
401 + setnilvalue(L, L->top + i);
402 L->nCcalls = oldnCcalls;
403 L->ci = restoreci(L, old_ci);
404 L->base = L->ci->base;
415 Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) {
416 @@ -45,7 +45,7 @@ UpVal *luaF_newupval (lua_State *L) {
417 UpVal *uv = luaM_new(L, UpVal);
418 luaC_link(L, obj2gco(uv), LUA_TUPVAL);
419 uv->v = &uv->u.value;
420 - setnilvalue(uv->v);
421 + setnilvalue(L, uv->v);
425 @@ -69,6 +69,12 @@ UpVal *luaF_findupval (lua_State *L, Stk
426 uv->marked = luaC_white(g);
427 uv->v = level; /* current value lives in the stack */
428 uv->next = *pp; /* chain it in the proper position */
430 + uv->prev = uv->next->gch.prev;
431 + uv->next->gch.prev = (GCObject *)uv;
436 uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */
437 uv->u.l.next = g->uvhead.u.l.next;
447 #define GCSTEPSIZE 1024u
448 @@ -265,7 +266,7 @@ static void traversestack (global_State
449 for (o = l->stack; o < l->top; o++)
451 for (; o <= lim; o++)
454 checkstacksizes(l, lim);
457 @@ -348,7 +349,7 @@ static int iscleared (const TValue *o, i
459 ** clear collected entries from weaktables
461 -static void cleartable (GCObject *l) {
462 +static void cleartable (lua_State *L, GCObject *l) {
465 int i = h->sizearray;
466 @@ -358,7 +359,7 @@ static void cleartable (GCObject *l) {
468 TValue *o = &h->array[i];
469 if (iscleared(o, 0)) /* value was collected? */
470 - setnilvalue(o); /* remove value */
471 + setnilvalue(L, o); /* remove value */
475 @@ -366,7 +367,7 @@ static void cleartable (GCObject *l) {
476 Node *n = gnode(h, i);
477 if (!ttisnil(gval(n)) && /* non-empty entry? */
478 (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) {
479 - setnilvalue(gval(n)); /* remove value ... */
480 + setnilvalue(L, gval(n)); /* remove value ... */
481 removeentry(n); /* remove entry from table */
484 @@ -375,7 +376,7 @@ static void cleartable (GCObject *l) {
488 -static void freeobj (lua_State *L, GCObject *o) {
489 +void luaC_freeobj (lua_State *L, GCObject *o) {
491 case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
492 case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break;
493 @@ -418,10 +419,14 @@ static GCObject **sweeplist (lua_State *
495 else { /* must erase `curr' */
496 lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT));
497 + if (curr->gch.prev)
498 + curr->gch.prev->gch.next = curr->gch.next;
499 + if (curr->gch.next)
500 + curr->gch.next->gch.prev = (GCObject*)p;
502 if (curr == g->rootgc) /* is the first element of the list? */
503 g->rootgc = curr->gch.next; /* adjust first */
505 + luaC_freeobj(L, curr);
509 @@ -543,7 +548,7 @@ static void atomic (lua_State *L) {
510 udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */
511 marktmu(g); /* mark `preserved' userdata */
512 udsize += propagateall(g); /* remark, to propagate `preserveness' */
513 - cleartable(g->weak); /* remove collected objects from weak tables */
514 + cleartable(L, g->weak); /* remove collected objects from weak tables */
515 /* flip current white */
516 g->currentwhite = cast_byte(otherwhite(g));
518 @@ -685,8 +690,11 @@ void luaC_barrierback (lua_State *L, Tab
520 void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {
521 global_State *g = G(L);
522 + o->gch.prev = (GCObject*)&g->rootgc;
523 o->gch.next = g->rootgc;
526 + o->gch.next->gch.prev = o;
527 o->gch.marked = luaC_white(g);
532 @@ -105,6 +105,6 @@ LUAI_FUNC void luaC_link (lua_State *L,
533 LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv);
534 LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v);
535 LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t);
537 +LUAI_FUNC void luaC_freeobj (lua_State *L, GCObject *o);
550 @@ -80,6 +81,8 @@ void *luaM_realloc_ (lua_State *L, void
551 if (block == NULL && nsize > 0)
552 luaD_throw(L, LUA_ERRMEM);
553 lua_assert((nsize == 0) == (block == NULL));
555 + memset((char *)block + osize, 0, nsize - osize);
556 g->totalbytes = (g->totalbytes - osize) + nsize;
561 @@ -44,7 +44,7 @@ typedef union GCObject GCObject;
562 ** Common Header for all collectable objects (in macro form, to be
563 ** included in other objects)
565 -#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
566 +#define CommonHeader GCObject *next; GCObject *prev; lu_byte tt; lu_byte marked
570 @@ -83,6 +83,7 @@ typedef struct lua_TValue {
574 +#define tvinit() { .value.b = 0, .tt = 0 }
576 /* Macros to test type */
577 #define ttisnil(o) (ttype(o) == LUA_TNIL)
578 @@ -145,15 +146,15 @@ typedef struct lua_TValue {
581 /* Macros to set values */
582 -#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
583 +#define setnilvalue(L, obj) (luaV_unref(L, (obj))->tt=LUA_TNIL)
585 /* Must not have side effects, 'x' may be expression.
587 #define setivalue(obj,x) \
588 - { TValue *i_o=(obj); i_o->value.i=(x); i_o->tt=LUA_TINT; }
589 + { TValue *i_o=luaV_unref(L, (obj)); i_o->value.i=(x); i_o->tt=LUA_TINT; }
591 # define setnvalue(obj,x) \
592 - { TValue *i_o=(obj); i_o->value.n= (x); i_o->tt=LUA_TNUMBER; }
593 + { TValue *i_o=luaV_unref(L, (obj)); i_o->value.n= (x); i_o->tt=LUA_TNUMBER; }
595 /* Note: Complex always has "inline", both are C99.
597 @@ -170,45 +171,45 @@ typedef struct lua_TValue {
600 #define setpvalue(obj,x) \
601 - { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
602 + { TValue *i_o=luaV_unref(L, (obj)); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
604 #define setbvalue(obj,x) \
605 - { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; }
606 + { TValue *i_o=luaV_unref(L, (obj)); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; }
608 #define setsvalue(L,obj,x) \
609 - { TValue *i_o=(obj); \
610 - i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \
611 + { TValue *i_o=(obj); TString *val=(x); luaS_ref(val); luaV_unref(L, obj); \
612 + i_o->value.gc=cast(GCObject *, (val)); i_o->tt=LUA_TSTRING; \
613 checkliveness(G(L),i_o); }
615 #define setuvalue(L,obj,x) \
616 - { TValue *i_o=(obj); \
617 + { TValue *i_o=luaV_unref(L, (obj)); \
618 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \
619 checkliveness(G(L),i_o); }
621 #define setthvalue(L,obj,x) \
622 - { TValue *i_o=(obj); \
623 + { TValue *i_o=luaV_unref(L, (obj)); \
624 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \
625 checkliveness(G(L),i_o); }
627 #define setclvalue(L,obj,x) \
628 - { TValue *i_o=(obj); \
629 + { TValue *i_o=luaV_unref(L, (obj)); \
630 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \
631 checkliveness(G(L),i_o); }
633 #define sethvalue(L,obj,x) \
634 - { TValue *i_o=(obj); \
635 + { TValue *i_o=luaV_unref(L, (obj)); \
636 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \
637 checkliveness(G(L),i_o); }
639 #define setptvalue(L,obj,x) \
640 - { TValue *i_o=(obj); \
641 + { TValue *i_o=luaV_unref(L, (obj)); \
642 i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \
643 checkliveness(G(L),i_o); }
645 #define setobj(L,obj1,obj2) \
646 - { const TValue *o2=(obj2); TValue *o1=(obj1); \
647 + do { const TValue *o2=luaV_ref((TValue *)(obj2)); TValue *o1=luaV_unref(L, (obj1)); \
648 o1->value = o2->value; o1->tt=o2->tt; \
649 - checkliveness(G(L),o1); }
650 + checkliveness(G(L),o1); } while(0)
654 @@ -253,6 +254,7 @@ typedef union TString {
662 @@ -409,6 +411,7 @@ typedef struct Table {
663 #define twoto(x) (1<<(x))
664 #define sizenode(t) (twoto((t)->lsizenode))
666 +#include "lstring.h"
668 #define luaO_nilobject (&luaO_nilobject_)
680 @@ -146,7 +147,7 @@ static int registerlocalvar (LexState *l
681 luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
682 LocVar, SHRT_MAX, "too many local variables");
683 while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
684 - f->locvars[fs->nlocvars].varname = varname;
685 + f->locvars[fs->nlocvars].varname = luaS_ref(varname);
686 luaC_objbarrier(ls->L, f, varname);
687 return fs->nlocvars++;
689 @@ -194,7 +195,7 @@ static int indexupvalue (FuncState *fs,
690 luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues,
691 TString *, MAX_INT, "");
692 while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL;
693 - f->upvalues[f->nups] = name;
694 + f->upvalues[f->nups] = luaS_ref(name);
695 luaC_objbarrier(fs->L, f, name);
696 lua_assert(v->k == VLOCAL || v->k == VUPVAL);
697 fs->upvalues[f->nups].k = cast_byte(v->k);
698 @@ -341,7 +342,7 @@ static void open_func (LexState *ls, Fun
702 - f->source = ls->source;
703 + f->source = luaS_ref(ls->source);
704 f->maxstacksize = 2; /* registers 0/1 are always valid */
705 fs->h = luaH_new(L, 0, 0);
706 /* anchor table of constants and prototype (to avoid being collected) */
716 #define state_size(x) (sizeof(x) + LUAI_EXTRASPACE)
717 @@ -52,7 +53,7 @@ static void stack_init (lua_State *L1, l
718 L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
719 /* initialize first ci */
720 L1->ci->func = L1->top;
721 - setnilvalue(L1->top++); /* `function' entry for this `ci' */
722 + setnilvalue(L1, L1->top++); /* `function' entry for this `ci' */
723 L1->base = L1->ci->base = L1->top;
724 L1->ci->top = L1->top + LUA_MINSTACK;
726 @@ -98,7 +99,7 @@ static void preinit_state (lua_State *L,
727 L->base_ci = L->ci = NULL;
730 - setnilvalue(gt(L));
731 + setnilvalue(L, gt(L));
735 @@ -163,7 +164,7 @@ LUA_API lua_State *lua_newstate (lua_All
739 - setnilvalue(registry(L));
740 + setnilvalue(L, registry(L));
741 luaZ_initbuffer(L, &g->buff);
743 g->gcstate = GCSpause;
746 @@ -37,6 +37,9 @@ void luaS_resize (lua_State *L, int news
747 int h1 = lmod(h, newsize); /* new position */
748 lua_assert(cast_int(h%newsize) == lmod(h, newsize));
749 p->gch.next = newhash[h1]; /* chain it */
751 + p->gch.next->gch.prev = p;
752 + p->gch.prev = NULL;
756 @@ -59,11 +62,15 @@ static TString *newlstr (lua_State *L, c
757 ts->tsv.marked = luaC_white(G(L));
758 ts->tsv.tt = LUA_TSTRING;
759 ts->tsv.reserved = 0;
760 + ts->tsv.refcount = 0;
761 memcpy(ts+1, str, l*sizeof(char));
762 ((char *)(ts+1))[l] = '\0'; /* ending 0 */
764 h = lmod(h, tb->size);
765 ts->tsv.next = tb->hash[h]; /* chain new entry */
767 + ts->tsv.next->gch.prev = (GCObject *)ts;
768 + ts->tsv.prev = NULL;
769 tb->hash[h] = obj2gco(ts);
771 if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
772 @@ -109,3 +116,29 @@ Udata *luaS_newudata (lua_State *L, size
776 +void luaS_unref(lua_State *L, TString *ts) {
779 + if (testbit(ts->tsv.marked, FIXEDBIT))
781 + ts->tsv.refcount--;
782 + if (ts->tsv.refcount < 0) {
783 + fprintf(stderr, "REFCOUNT BUG, COUNT=%d, str=%s, len=%d\n", ts->tsv.refcount, (char *) (ts + 1), (int) ts->tsv.len);
784 + } else if (ts->tsv.refcount)
787 + if (ts->tsv.prev) {
788 + ts->tsv.prev->gch.next = ts->tsv.next;
790 + unsigned int idx = lmod(ts->tsv.hash, G(L)->strt.size);
791 + lua_assert(G(L)->strt.hash[index] == (GCObject*)ts);
792 + G(L)->strt.hash[idx] = ts->tsv.next;
796 + ts->tsv.next->gch.prev = ts->tsv.prev;
798 + luaC_freeobj(L, (GCObject *) ts);
815 #define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
817 +static inline TString *luaS_ref(TString *ts) {
818 + ts->tsv.refcount++;
822 +LUA_API void luaS_unref(lua_State *L, TString *ts);
823 LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
824 LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
825 LUA_API TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
836 @@ -278,7 +279,7 @@ static void setarrayvector (lua_State *L
838 luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
839 for (i=t->sizearray; i<size; i++)
840 - setnilvalue(&t->array[i]);
841 + setnilvalue(L, &t->array[i]);
845 @@ -299,8 +300,8 @@ static void setnodevector (lua_State *L,
846 for (i=0; i<size; i++) {
847 Node *n = gnode(t, i);
849 - setnilvalue(gkey(n));
850 - setnilvalue(gval(n));
851 + setnilvalue(L, gkey(n));
852 + setnilvalue(L, gval(n));
855 t->lsizenode = cast_byte(lsize);
856 @@ -427,9 +428,11 @@ static TValue *newkey (lua_State *L, Tab
857 othern = gnext(othern); /* find previous */
859 gnext(othern) = n; /* redo the chain with `n' in place of `mp' */
860 + luaV_ref((TValue *) gkey(mp));
861 + luaV_ref(gval(mp));
862 *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
863 gnext(mp) = NULL; /* now `mp' is free */
864 - setnilvalue(gval(mp));
865 + setnilvalue(L, gval(mp));
867 else { /* colliding node is in its own main position */
868 /* new node will go into free position */
869 @@ -438,6 +441,7 @@ static TValue *newkey (lua_State *L, Tab
873 + luaV_ref((TValue *) key);
874 gkey(mp)->value = key->value; gkey(mp)->tt = key->tt;
875 luaC_barriert(L, t, key);
876 lua_assert(ttisnil(gval(mp)));
877 @@ -530,7 +534,7 @@ TValue *luaH_setint (lua_State *L, Table
878 if (p != luaO_nilobject)
879 return cast(TValue *, p);
882 + TValue k = tvinit();
884 return newkey(L, t, &k);
886 @@ -542,7 +546,7 @@ TValue *luaH_setstr (lua_State *L, Table
887 if (p != luaO_nilobject)
888 return cast(TValue *, p);
891 + TValue k = tvinit();
892 setsvalue(L, &k, key);
893 return newkey(L, t, &k);
900 #include "lopcodes.h"
901 -#include "lstring.h"
904 +#include "lstring.h"
906 #define PROGNAME "luac" /* default program name */
907 #define OUTPUT PROGNAME ".out" /* default output file */
918 @@ -133,7 +134,7 @@ static TString* LoadString(LoadState* S)
920 char* s=luaZ_openspace(S->L,S->b,size);
922 - return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
923 + return luaS_ref(luaS_newlstr(S->L,s,size-1)); /* remove trailing '\0' */
927 @@ -149,11 +150,12 @@ static Proto* LoadFunction(LoadState* S,
929 static void LoadConstants(LoadState* S, Proto* f)
931 + lua_State *L = S->L;
934 f->k=luaM_newvector(S->L,n,TValue);
936 - for (i=0; i<n; i++) setnilvalue(&f->k[i]);
937 + for (i=0; i<n; i++) setnilvalue(L, &f->k[i]);
941 @@ -161,7 +163,7 @@ static void LoadConstants(LoadState* S,
949 setbvalue(o,LoadChar(S)!=0);
950 @@ -229,6 +231,7 @@ static Proto* LoadFunction(LoadState* S,
952 IF (!luaG_checkcode(f), "bad code");
954 + setnilvalue(S->L, S->L->top);
961 * If 'obj' is a string, it is tried to be interpreted as a number.
963 const TValue *luaV_tonumber ( const TValue *obj, TValue *n) {
964 + lua_State *L = NULL; /* FIXME */
968 @@ -384,6 +385,7 @@ void luaV_concat (lua_State *L, int tota
969 size_t l = tsvalue(top-i)->len;
970 memcpy(buffer+tl, svalue(top-i), l);
972 + setnilvalue(L, top - i);
974 setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
976 @@ -420,7 +422,7 @@ void luaV_concat (lua_State *L, int tota
978 static void Arith (lua_State *L, StkId ra, const TValue *rb,
979 const TValue *rc, TMS op) {
980 - TValue tempb, tempc;
981 + TValue tempb = tvinit(), tempc = tvinit();
985 @@ -663,7 +665,7 @@ void luaV_execute (lua_State *L, int nex
986 OPCODE_TARGET(LOADNIL) {
990 + setnilvalue(L, rb--);
994 @@ -673,7 +675,7 @@ void luaV_execute (lua_State *L, int nex
997 OPCODE_TARGET(GETGLOBAL) {
999 + TValue g = tvinit();
1000 TValue *rb = KBx(i);
1001 sethvalue(L, &g, cl->env);
1002 lua_assert(ttisstring(rb));
1003 @@ -685,7 +687,7 @@ void luaV_execute (lua_State *L, int nex
1006 OPCODE_TARGET(SETGLOBAL) {
1008 + TValue g = tvinit();
1009 sethvalue(L, &g, cl->env);
1010 lua_assert(ttisstring(KBx(i)));
1011 Protect(luaV_settable(L, &g, KBx(i), ra));
1012 @@ -693,7 +695,7 @@ void luaV_execute (lua_State *L, int nex
1014 OPCODE_TARGET(SETUPVAL) {
1015 UpVal *uv = cl->upvals[GETARG_B(i)];
1016 - setobj(L, uv->v, ra);
1017 + setobj(L, uv->v, luaV_ref(ra));
1018 luaC_barrier(L, uv, ra);
1021 @@ -1030,7 +1032,7 @@ void luaV_execute (lua_State *L, int nex
1022 setobjs2s(L, ra + j, ci->base - n + j);
1025 - setnilvalue(ra + j);
1026 + setnilvalue(L, ra + j);
1034 #include "lobject.h"
1036 +#include "lstring.h"
1039 #define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o)))
1042 #define equalobj(L,o1,o2) (ttype_ext_same(o1,o2) && luaV_equalval(L, o1, o2))
1044 +static inline TValue *luaV_ref(TValue *tv)
1046 + if (ttisstring(tv))
1047 + luaS_ref(rawtsvalue(tv));
1051 +static inline TValue *luaV_unref(lua_State *L, TValue *tv)
1053 + if (ttisstring(tv))
1054 + luaS_unref(L, rawtsvalue(tv));
1058 LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
1059 LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
1070 @@ -69,7 +70,7 @@ static void save (LexState *ls, int c) {
1071 void luaX_init (lua_State *L) {
1073 for (i=0; i<NUM_RESERVED; i++) {
1074 - TString *ts = luaS_new(L, luaX_tokens[i]);
1075 + TString *ts = luaS_ref(luaS_new(L, luaX_tokens[i]));
1076 luaS_fix(ts); /* reserved words are never collected */
1077 lua_assert(strlen(luaX_tokens[i])+1 <= TOKEN_LEN);
1078 ts->tsv.reserved = cast_byte(i+1); /* reserved word */
1079 @@ -125,7 +126,7 @@ void luaX_syntaxerror (LexState *ls, con
1081 TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
1082 lua_State *L = ls->L;
1083 - TString *ts = luaS_newlstr(L, str, l);
1084 + TString *ts = luaS_ref(luaS_newlstr(L, str, l));
1085 TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */
1087 setbvalue(o, 1); /* make sure `str' will not be collected */
1088 @@ -152,7 +153,7 @@ void luaX_setinput (lua_State *L, LexSta
1092 - ls->source = source;
1093 + ls->source = luaS_ref(source);
1094 luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
1095 next(ls); /* read first char */