[kernel] add missing configuration symbols
[openwrt.git] / package / lua / patches / 600-refcounting.patch
1 --- a/src/lapi.c
2 +++ b/src/lapi.c
3 @@ -27,8 +27,8 @@
4  #include "ltable.h"
5  #include "ltm.h"
6  #include "lundump.h"
7 -#include "lvm.h"
8  #include "lnum.h"
9 +#include "lvm.h"
10  
11  
12  const char lua_ident[] =
13 @@ -117,6 +117,7 @@ LUA_API void lua_xmove (lua_State *from,
14    from->top -= n;
15    for (i = 0; i < n; i++) {
16      setobj2s(to, to->top++, from->top + i);
17 +    setnilvalue(from, from->top + i);
18    }
19    lua_unlock(to);
20  }
21 @@ -166,12 +167,16 @@ LUA_API void lua_settop (lua_State *L, i
22    if (idx >= 0) {
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);
29    }
30    else {
31 +    int i;
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);
36    }
37    lua_unlock(L);
38  }
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);
42    L->top--;
43 +  setnilvalue(L, L->top);
44    lua_unlock(L);
45  }
46  
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);
52    lua_unlock(L);
53  }
54  
55 @@ -221,6 +228,7 @@ LUA_API void lua_replace (lua_State *L, 
56        luaC_barrier(L, curr_func(L), L->top - 1);
57    }
58    L->top--;
59 +  setnilvalue(L, L->top);
60    lua_unlock(L);
61  }
62  
63 @@ -259,14 +267,14 @@ LUA_API int lua_iscfunction (lua_State *
64  
65  
66  LUA_API int lua_isnumber (lua_State *L, int idx) {
67 -  TValue n;
68 +  TValue n = tvinit();
69    const TValue *o = index2adr(L, idx);
70    return tonumber(o, &n);
71  }
72  
73  
74  LUA_API int lua_isinteger (lua_State *L, int idx) {
75 -  TValue tmp;
76 +  TValue tmp = tvinit();
77    lua_Integer dum;
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, 
81  
82  
83  LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
84 -  TValue n;
85 +  TValue n = tvinit();
86    const TValue *o = index2adr(L, idx);
87    if (tonumber(o, &n)) {
88  #ifdef LNUM_COMPLEX
89 @@ -333,7 +341,7 @@ LUA_API lua_Number lua_tonumber (lua_Sta
90  
91  
92  LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
93 -  TValue n;
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
99  
100  #ifdef LNUM_COMPLEX
101  LUA_API lua_Complex lua_tocomplex (lua_State *L, int idx) {
102 -  TValue tmp;
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
108  
109  LUA_API void lua_pushnil (lua_State *L) {
110    lua_lock(L);
111 -  setnilvalue(L->top);
112 +  setnilvalue(L, L->top);
113    api_incr_top(L);
114    lua_unlock(L);
115  }
116 @@ -548,8 +556,10 @@ LUA_API void lua_pushcclosure (lua_State
117    cl = luaF_newCclosure(L, n, getcurrenv(L));
118    cl->c.f = fn;
119    L->top -= n;
120 -  while (n--)
121 +  while (n--) {
122      setobj2n(L, &cl->c.upvalue[n], L->top+n);
123 +    setnilvalue(L, L->top + n);
124 +  }
125    setclvalue(L, L->top, cl);
126    lua_assert(iswhite(obj2gco(cl)));
127    api_incr_top(L);
128 @@ -600,7 +610,7 @@ LUA_API void lua_gettable (lua_State *L,
129  
130  LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
131    StkId t;
132 -  TValue key;
133 +  TValue key = tvinit();
134    lua_lock(L);
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)));
139        break;
140      default:
141 -      setnilvalue(L->top);
142 +      setnilvalue(L, L->top);
143        break;
144    }
145    api_incr_top(L);
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);
152    lua_unlock(L);
153  }
154  
155  
156  LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
157    StkId t;
158 -  TValue key;
159 +  TValue key = tvinit();
160    lua_lock(L);
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);
168    lua_unlock(L);
169  }
170  
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);
174    L->top -= 2;
175 +  setnilvalue(L, L->top);
176 +  setnilvalue(L, L->top + 1);
177    lua_unlock(L);
178  }
179  
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);
183    L->top--;
184 +  setnilvalue(L, L->top);
185    lua_unlock(L);
186  }
187  
188 @@ -786,6 +802,7 @@ LUA_API int lua_setmetatable (lua_State 
189      }
190    }
191    L->top--;
192 +  setnilvalue(L, L->top);
193    lua_unlock(L);
194    return 1;
195  }
196 @@ -815,6 +832,7 @@ LUA_API int lua_setfenv (lua_State *L, i
197    }
198    if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
199    L->top--;
200 +  setnilvalue(L, L->top);
201    lua_unlock(L);
202    return res;
203  }
204 @@ -1040,20 +1058,25 @@ LUA_API int lua_next (lua_State *L, int 
205    if (more) {
206      api_incr_top(L);
207    }
208 -  else  /* no more elements */
209 +  else {  /* no more elements */
210      L->top -= 1;  /* remove key */
211 +    setnilvalue(L, L->top);
212 +  }
213    lua_unlock(L);
214    return more;
215  }
216  
217  
218  LUA_API void lua_concat (lua_State *L, int n) {
219 +  int i;
220    lua_lock(L);
221    api_checknelems(L, n);
222    if (n >= 2) {
223      luaC_checkGC(L);
224      luaV_concat(L, n, cast_int(L->top - L->base) - 1);
225      L->top -= (n-1);
226 +    for (i = 0; i < n - 1; i++)
227 +      setnilvalue(L, L->top + i);
228    }
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_
232    if (name) {
233      L->top--;
234      setobj(L, val, L->top);
235 +    setnilvalue(L, L->top);
236      luaC_barrier(L, clvalue(fi), L->top);
237    }
238    lua_unlock(L);
239 @@ -1160,7 +1184,7 @@ LUA_API const char *lua_setupvalue (lua_
240  int lua_pushvalue_as_number (lua_State *L, int idx)
241  {
242    const TValue *o = index2adr(L, idx);
243 -  TValue tmp;
244 +  TValue tmp = tvinit();
245    lua_Integer i;
246    if (ttisnumber(o)) {
247      if ( (!ttisint(o)) && tt_integer_valued(o,&i)) {
248 --- a/src/lcode.c
249 +++ b/src/lcode.c
250 @@ -23,6 +23,7 @@
251  #include "lparser.h"
252  #include "ltable.h"
253  #include "lnum.h"
254 +#include "lvm.h"
255  
256  
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);
266      return fs->nk++;
267 @@ -257,21 +258,24 @@ static int addk (FuncState *fs, TValue *
268  
269  
270  int luaK_stringK (FuncState *fs, TString *s) {
271 -  TValue o;
272 +  TValue o = tvinit();
273    setsvalue(fs->L, &o, s);
274 +  luaV_unref(fs->L, &o);
275    return addk(fs, &o, &o);
276  }
277  
278  
279  int luaK_numberK (FuncState *fs, lua_Number r) {
280 -  TValue o;
281 +  lua_State *L = fs->L;
282 +  TValue o = tvinit();
283    setnvalue(&o, r);
284    return addk(fs, &o, &o);
285  }
286  
287  
288  int luaK_integerK (FuncState *fs, lua_Integer r) {
289 -  TValue o;
290 +  lua_State *L = fs->L;
291 +  TValue o = tvinit();
292    setivalue(&o, r);
293    return addk(fs, &o, &o);
294  }
295 @@ -279,22 +283,24 @@ int luaK_integerK (FuncState *fs, lua_In
296  
297  #ifdef LNUM_COMPLEX
298  static int luaK_imagK (FuncState *fs, lua_Number r) {
299 -  TValue o;
300 +  lua_State *L = fs->L;
301 +  TValue o = tvinit();
302    setnvalue_complex(&o, r*I);
303    return addk(fs, &o, &o);
304  }
305  #endif
306  
307  static int boolK (FuncState *fs, int b) {
308 -  TValue o;
309 +  lua_State *L = fs->L;
310 +  TValue o = tvinit();
311    setbvalue(&o, b);
312    return addk(fs, &o, &o);
313  }
314  
315  
316  static int nilK (FuncState *fs) {
317 -  TValue k, v;
318 -  setnilvalue(&v);
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);
324 --- a/src/ldebug.c
325 +++ b/src/ldebug.c
326 @@ -176,7 +176,7 @@ static void info_tailcall (lua_Debug *ar
327  
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);
332    }
333    else {
334      Table *t = luaH_new(L, 0, 0);
335 @@ -248,7 +248,7 @@ LUA_API int lua_getinfo (lua_State *L, c
336    }
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);
342      incr_top(L);
343    }
344 @@ -586,7 +586,7 @@ void luaG_concaterror (lua_State *L, Stk
345  
346  
347  void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
348 -  TValue temp;
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");
353 --- a/src/ldo.c
354 +++ b/src/ldo.c
355 @@ -211,7 +211,7 @@ static StkId adjust_varargs (lua_State *
356    Table *htab = NULL;
357    StkId base, fixed;
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);
369    }
370    /* add `arg' parameter */
371    if (htab) {
372 @@ -294,7 +293,7 @@ int luaD_precall (lua_State *L, StkId fu
373      ci->tailcalls = 0;
374      ci->nresults = nresults;
375      for (st = L->top; st < ci->top; st++)
376 -      setnilvalue(st);
377 +      setnilvalue(L, st);
378      L->top = ci->top;
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++);
384    while (i-- > 0)
385 -    setnilvalue(res++);
386 +    setnilvalue(L, res++);
387 +  for (i = (res - L->top); i-- > 0;)
388 +    setnilvalue(L, L->top + i);
389    L->top = res;
390    return (wanted - LUA_MULTRET);  /* 0 iff wanted == LUA_MULTRET */
391  }
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;
397 +    int i;
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;
405 --- a/src/lfunc.c
406 +++ b/src/lfunc.c
407 @@ -17,7 +17,7 @@
408  #include "lmem.h"
409  #include "lobject.h"
410  #include "lstate.h"
411 -
412 +#include "lvm.h"
413  
414  
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);
422    return uv;
423  }
424  
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 */
429 +  if (uv->next) {
430 +       uv->prev = uv->next->gch.prev;
431 +    uv->next->gch.prev = (GCObject *)uv;
432 +  } else {
433 +    uv->prev = NULL;
434 +  }
435    *pp = obj2gco(uv);
436    uv->u.l.prev = &g->uvhead;  /* double link it in `uvhead' list */
437    uv->u.l.next = g->uvhead.u.l.next;
438 --- a/src/lgc.c
439 +++ b/src/lgc.c
440 @@ -21,6 +21,7 @@
441  #include "lstring.h"
442  #include "ltable.h"
443  #include "ltm.h"
444 +#include "lvm.h"
445  
446  
447  #define GCSTEPSIZE     1024u
448 @@ -265,7 +266,7 @@ static void traversestack (global_State 
449    for (o = l->stack; o < l->top; o++)
450      markvalue(g, o);
451    for (; o <= lim; o++)
452 -    setnilvalue(o);
453 +    setnilvalue(l, o);
454    checkstacksizes(l, lim);
455  }
456  
457 @@ -348,7 +349,7 @@ static int iscleared (const TValue *o, i
458  /*
459  ** clear collected entries from weaktables
460  */
461 -static void cleartable (GCObject *l) {
462 +static void cleartable (lua_State *L, GCObject *l) {
463    while (l) {
464      Table *h = gco2h(l);
465      int i = h->sizearray;
466 @@ -358,7 +359,7 @@ static void cleartable (GCObject *l) {
467        while (i--) {
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 */
472        }
473      }
474      i = sizenode(h);
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 */
482        }
483      }
484 @@ -375,7 +376,7 @@ static void cleartable (GCObject *l) {
485  }
486  
487  
488 -static void freeobj (lua_State *L, GCObject *o) {
489 +void luaC_freeobj (lua_State *L, GCObject *o) {
490    switch (o->gch.tt) {
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 *
494      }
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;
501        *p = curr->gch.next;
502        if (curr == g->rootgc)  /* is the first element of the list? */
503          g->rootgc = curr->gch.next;  /* adjust first */
504 -      freeobj(L, curr);
505 +      luaC_freeobj(L, curr);
506      }
507    }
508    return p;
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));
517    g->sweepstrgc = 0;
518 @@ -685,8 +690,11 @@ void luaC_barrierback (lua_State *L, Tab
519  
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;
524    g->rootgc = o;
525 +  if (o->gch.next)
526 +    o->gch.next->gch.prev = o;
527    o->gch.marked = luaC_white(g);
528    o->gch.tt = tt;
529  }
530 --- a/src/lgc.h
531 +++ b/src/lgc.h
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);
536 -
537 +LUAI_FUNC void luaC_freeobj (lua_State *L, GCObject *o);
538  
539  #endif
540 --- a/src/lmem.c
541 +++ b/src/lmem.c
542 @@ -6,6 +6,7 @@
543  
544  
545  #include <stddef.h>
546 +#include <string.h>
547  
548  #define lmem_c
549  #define LUA_CORE
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));
554 +  if (nsize > osize)
555 +    memset((char *)block + osize, 0, nsize - osize);
556    g->totalbytes = (g->totalbytes - osize) + nsize;
557    return block;
558  }
559 --- a/src/lobject.h
560 +++ b/src/lobject.h
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)
564  */
565 -#define CommonHeader   GCObject *next; lu_byte tt; lu_byte marked
566 +#define CommonHeader   GCObject *next; GCObject *prev; lu_byte tt; lu_byte marked
567  
568  
569  /*
570 @@ -83,6 +83,7 @@ typedef struct lua_TValue {
571    TValuefields;
572  } TValue;
573  
574 +#define tvinit() { .value.b = 0, .tt = 0 }
575  
576  /* Macros to test type */
577  #define ttisnil(o)     (ttype(o) == LUA_TNIL)
578 @@ -145,15 +146,15 @@ typedef struct lua_TValue {
579  
580  
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)
584  
585  /* Must not have side effects, 'x' may be expression.
586  */
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; }
590  
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; }
594  
595  /* Note: Complex always has "inline", both are C99.
596  */
597 @@ -170,45 +171,45 @@ typedef struct lua_TValue {
598  
599  
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; }
603  
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; }
607  
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); }
614  
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); }
620  
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); }
626  
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); }
632  
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); }
638  
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); }
644  
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)
651  
652  
653  /*
654 @@ -253,6 +254,7 @@ typedef union TString {
655      lu_byte reserved;
656      unsigned int hash;
657      size_t len;
658 +    int refcount;
659    } tsv;
660  } TString;
661  
662 @@ -409,6 +411,7 @@ typedef struct Table {
663  #define twoto(x)       (1<<(x))
664  #define sizenode(t)    (twoto((t)->lsizenode))
665  
666 +#include "lstring.h"
667  
668  #define luaO_nilobject         (&luaO_nilobject_)
669  
670 --- a/src/lparser.c
671 +++ b/src/lparser.c
672 @@ -24,6 +24,7 @@
673  #include "lstate.h"
674  #include "lstring.h"
675  #include "ltable.h"
676 +#include "lvm.h"
677  
678  
679  
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++;
688  }
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
699    fs->nlocvars = 0;
700    fs->nactvar = 0;
701    fs->bl = NULL;
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) */
707 --- a/src/lstate.c
708 +++ b/src/lstate.c
709 @@ -22,6 +22,7 @@
710  #include "lstring.h"
711  #include "ltable.h"
712  #include "ltm.h"
713 +#include "lvm.h"
714  
715  
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;
725  }
726 @@ -98,7 +99,7 @@ static void preinit_state (lua_State *L,
727    L->base_ci = L->ci = NULL;
728    L->savedpc = NULL;
729    L->errfunc = 0;
730 -  setnilvalue(gt(L));
731 +  setnilvalue(L, gt(L));
732  }
733  
734  
735 @@ -163,7 +164,7 @@ LUA_API lua_State *lua_newstate (lua_All
736    g->strt.size = 0;
737    g->strt.nuse = 0;
738    g->strt.hash = NULL;
739 -  setnilvalue(registry(L));
740 +  setnilvalue(L, registry(L));
741    luaZ_initbuffer(L, &g->buff);
742    g->panic = NULL;
743    g->gcstate = GCSpause;
744 --- a/src/lstring.c
745 +++ b/src/lstring.c
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 */
750 +      if (p->gch.next)
751 +        p->gch.next->gch.prev = p;
752 +      p->gch.prev = NULL;
753        newhash[h1] = p;
754        p = next;
755      }
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 */
763    tb = &G(L)->strt;
764    h = lmod(h, tb->size);
765    ts->tsv.next = tb->hash[h];  /* chain new entry */
766 +  if (ts->tsv.next)
767 +    ts->tsv.next->gch.prev = (GCObject *)ts;
768 +  ts->tsv.prev = NULL;
769    tb->hash[h] = obj2gco(ts);
770    tb->nuse++;
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
773    return u;
774  }
775  
776 +void luaS_unref(lua_State *L, TString *ts) {
777 +  if (!L || !ts)
778 +    return;
779 +  if (testbit(ts->tsv.marked, FIXEDBIT))
780 +    return;
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)
785 +    return;
786 +
787 +  if (ts->tsv.prev) {
788 +    ts->tsv.prev->gch.next = ts->tsv.next;
789 +  } else {
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;
793 +  }
794 +
795 +  if (ts->tsv.next)
796 +    ts->tsv.next->gch.prev = ts->tsv.prev;
797 +
798 +  luaC_freeobj(L, (GCObject *) ts);
799 +}
800 +
801 +
802 --- a/src/lstring.h
803 +++ b/src/lstring.h
804 @@ -7,7 +7,7 @@
805  #ifndef lstring_h
806  #define lstring_h
807  
808 -
809 +#include <stdio.h>
810  #include "lgc.h"
811  #include "lobject.h"
812  #include "lstate.h"
813 @@ -23,6 +23,12 @@
814  
815  #define luaS_fix(s)    l_setbit((s)->tsv.marked, FIXEDBIT)
816  
817 +static inline TString *luaS_ref(TString *ts) {
818 +  ts->tsv.refcount++;
819 +  return ts;
820 +}
821 +
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);
826 --- a/src/ltable.c
827 +++ b/src/ltable.c
828 @@ -34,6 +34,7 @@
829  #include "lstate.h"
830  #include "ltable.h"
831  #include "lnum.h"
832 +#include "lvm.h"
833  
834  
835  /*
836 @@ -278,7 +279,7 @@ static void setarrayvector (lua_State *L
837    int i;
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]);
842    t->sizearray = size;
843  }
844  
845 @@ -299,8 +300,8 @@ static void setnodevector (lua_State *L,
846      for (i=0; i<size; i++) {
847        Node *n = gnode(t, i);
848        gnext(n) = NULL;
849 -      setnilvalue(gkey(n));
850 -      setnilvalue(gval(n));
851 +      setnilvalue(L, gkey(n));
852 +      setnilvalue(L, gval(n));
853      }
854    }
855    t->lsizenode = cast_byte(lsize);
856 @@ -427,9 +428,11 @@ static TValue *newkey (lua_State *L, Tab
857          othern = gnext(othern);  /* find previous */
858        }
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));
866      }
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
870        mp = n;
871      }
872    }
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);
880    else {
881 -    TValue k;
882 +    TValue k = tvinit();
883      setivalue(&k, key);
884      return newkey(L, t, &k);
885    }
886 @@ -542,7 +546,7 @@ TValue *luaH_setstr (lua_State *L, Table
887    if (p != luaO_nilobject)
888      return cast(TValue *, p);
889    else {
890 -    TValue k;
891 +    TValue k = tvinit();
892      setsvalue(L, &k, key);
893      return newkey(L, t, &k);
894    }
895 --- a/src/luac.c
896 +++ b/src/luac.c
897 @@ -20,8 +20,9 @@
898  #include "lmem.h"
899  #include "lobject.h"
900  #include "lopcodes.h"
901 -#include "lstring.h"
902  #include "lundump.h"
903 +#include "lvm.h"
904 +#include "lstring.h"
905  
906  #define PROGNAME       "luac"          /* default program name */
907  #define        OUTPUT          PROGNAME ".out" /* default output file */
908 --- a/src/lundump.c
909 +++ b/src/lundump.c
910 @@ -19,6 +19,7 @@
911  #include "lstring.h"
912  #include "lundump.h"
913  #include "lzio.h"
914 +#include "lvm.h"
915  
916  typedef struct {
917   lua_State* L;
918 @@ -133,7 +134,7 @@ static TString* LoadString(LoadState* S)
919   {
920    char* s=luaZ_openspace(S->L,S->b,size);
921    LoadBlock(S,s,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' */
924   }
925  }
926  
927 @@ -149,11 +150,12 @@ static Proto* LoadFunction(LoadState* S,
928  
929  static void LoadConstants(LoadState* S, Proto* f)
930  {
931 + lua_State *L = S->L;
932   int i,n;
933   n=LoadInt(S);
934   f->k=luaM_newvector(S->L,n,TValue);
935   f->sizek=n;
936 - for (i=0; i<n; i++) setnilvalue(&f->k[i]);
937 + for (i=0; i<n; i++) setnilvalue(L, &f->k[i]);
938   for (i=0; i<n; i++)
939   {
940    TValue* o=&f->k[i];
941 @@ -161,7 +163,7 @@ static void LoadConstants(LoadState* S, 
942    switch (t)
943    {
944     case LUA_TNIL:
945 -       setnilvalue(o);
946 +       setnilvalue(L, o);
947         break;
948     case LUA_TBOOLEAN:
949         setbvalue(o,LoadChar(S)!=0);
950 @@ -229,6 +231,7 @@ static Proto* LoadFunction(LoadState* S,
951   LoadDebug(S,f);
952   IF (!luaG_checkcode(f), "bad code");
953   S->L->top--;
954 + setnilvalue(S->L, S->L->top);
955   S->L->nCcalls--;
956   return f;
957  }
958 --- a/src/lvm.c
959 +++ b/src/lvm.c
960 @@ -39,6 +39,7 @@
961   * If 'obj' is a string, it is tried to be interpreted as a number.
962   */
963  const TValue *luaV_tonumber ( const TValue *obj, TValue *n) {
964 +  lua_State *L = NULL; /* FIXME */
965    lua_Number d;
966    lua_Integer i;
967    
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);
971          tl += l;
972 +               setnilvalue(L, top - i);
973        }
974        setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
975      }
976 @@ -420,7 +422,7 @@ void luaV_concat (lua_State *L, int tota
977   */
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();
982    const TValue *b, *c;
983    lua_Number nb,nc;
984  
985 @@ -663,7 +665,7 @@ void luaV_execute (lua_State *L, int nex
986        OPCODE_TARGET(LOADNIL) {
987          TValue *rb = RB(i);
988          do {
989 -          setnilvalue(rb--);
990 +          setnilvalue(L, rb--);
991          } while (rb >= ra);
992          continue;
993        }
994 @@ -673,7 +675,7 @@ void luaV_execute (lua_State *L, int nex
995          continue;
996        }
997        OPCODE_TARGET(GETGLOBAL) {
998 -        TValue g;
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
1004          continue;
1005        }
1006        OPCODE_TARGET(SETGLOBAL) {
1007 -        TValue g;
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
1013        }
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);
1019          continue;
1020        }
1021 @@ -1030,7 +1032,7 @@ void luaV_execute (lua_State *L, int nex
1022              setobjs2s(L, ra + j, ci->base - n + j);
1023            }
1024            else {
1025 -            setnilvalue(ra + j);
1026 +            setnilvalue(L, ra + j);
1027            }
1028          }
1029          continue;
1030 --- a/src/lvm.h
1031 +++ b/src/lvm.h
1032 @@ -11,6 +11,7 @@
1033  #include "ldo.h"
1034  #include "lobject.h"
1035  #include "ltm.h"
1036 +#include "lstring.h"
1037  
1038  
1039  #define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o)))
1040 @@ -19,6 +20,19 @@
1041  
1042  #define equalobj(L,o1,o2) (ttype_ext_same(o1,o2) && luaV_equalval(L, o1, o2))
1043  
1044 +static inline TValue *luaV_ref(TValue *tv)
1045 +{
1046 +  if (ttisstring(tv))
1047 +    luaS_ref(rawtsvalue(tv));
1048 +  return tv;
1049 +}
1050 +
1051 +static inline TValue *luaV_unref(lua_State *L, TValue *tv)
1052 +{
1053 +  if (ttisstring(tv))
1054 +    luaS_unref(L, rawtsvalue(tv));
1055 +  return tv;
1056 +}
1057  
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);
1060 --- a/src/llex.c
1061 +++ b/src/llex.c
1062 @@ -23,6 +23,7 @@
1063  #include "ltable.h"
1064  #include "lzio.h"
1065  #include "lnum.h"
1066 +#include "lvm.h"
1067  
1068  
1069  
1070 @@ -69,7 +70,7 @@ static void save (LexState *ls, int c) {
1071  void luaX_init (lua_State *L) {
1072    int i;
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
1080  
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' */
1086    if (ttisnil(o))
1087      setbvalue(o, 1);  /* make sure `str' will not be collected */
1088 @@ -152,7 +153,7 @@ void luaX_setinput (lua_State *L, LexSta
1089    ls->fs = NULL;
1090    ls->linenumber = 1;
1091    ls->lastline = 1;
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 */
1096  }