2b4f7890b45ff6f82318ef271e3965d471d08970
[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,14 @@ 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 +       setlvmtop(L, L->top + idx + 1); /* `subtract' index (index is negative) */
35    }
36    lua_unlock(L);
37  }
38 @@ -183,7 +186,7 @@ LUA_API void lua_remove (lua_State *L, i
39    p = index2adr(L, idx);
40    api_checkvalidindex(L, p);
41    while (++p < L->top) setobjs2s(L, p-1, p);
42 -  L->top--;
43 +  setlvmtop(L, L->top - 1);
44    lua_unlock(L);
45  }
46  
47 @@ -196,6 +199,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 @@ -220,7 +224,7 @@ LUA_API void lua_replace (lua_State *L, 
56      if (idx < LUA_GLOBALSINDEX)  /* function upvalue? */
57        luaC_barrier(L, curr_func(L), L->top - 1);
58    }
59 -  L->top--;
60 +  setlvmtop(L, L->top - 1);
61    lua_unlock(L);
62  }
63  
64 @@ -259,14 +263,14 @@ LUA_API int lua_iscfunction (lua_State *
65  
66  
67  LUA_API int lua_isnumber (lua_State *L, int idx) {
68 -  TValue n;
69 +  TValue n = tvinit();
70    const TValue *o = index2adr(L, idx);
71    return tonumber(o, &n);
72  }
73  
74  
75  LUA_API int lua_isinteger (lua_State *L, int idx) {
76 -  TValue tmp;
77 +  TValue tmp = tvinit();
78    lua_Integer dum;
79    const TValue *o = index2adr(L, idx);
80    return tonumber(o,&tmp) && (ttisint(o) || tt_integer_valued(o,&dum));
81 @@ -319,7 +323,7 @@ LUA_API int lua_lessthan (lua_State *L, 
82  
83  
84  LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
85 -  TValue n;
86 +  TValue n = tvinit();
87    const TValue *o = index2adr(L, idx);
88    if (tonumber(o, &n)) {
89  #ifdef LNUM_COMPLEX
90 @@ -333,7 +337,7 @@ LUA_API lua_Number lua_tonumber (lua_Sta
91  
92  
93  LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
94 -  TValue n;
95 +  TValue n = tvinit();
96      /* Lua 5.1 documented behaviour is to return nonzero for non-integer:
97       * "If the number is not an integer, it is truncated in some non-specified way." 
98       * I would suggest to change this, to return 0 for anything that would
99 @@ -369,7 +373,7 @@ LUA_API lua_Integer lua_tointeger (lua_S
100  
101  #ifdef LNUM_COMPLEX
102  LUA_API lua_Complex lua_tocomplex (lua_State *L, int idx) {
103 -  TValue tmp;
104 +  TValue tmp = tvinit();
105    const TValue *o = index2adr(L, idx);
106    if (tonumber(o, &tmp))
107      return nvalue_complex(o);
108 @@ -465,7 +469,7 @@ LUA_API const void *lua_topointer (lua_S
109  
110  LUA_API void lua_pushnil (lua_State *L) {
111    lua_lock(L);
112 -  setnilvalue(L->top);
113 +  setnilvalue(L, L->top);
114    api_incr_top(L);
115    lua_unlock(L);
116  }
117 @@ -548,8 +552,10 @@ LUA_API void lua_pushcclosure (lua_State
118    cl = luaF_newCclosure(L, n, getcurrenv(L));
119    cl->c.f = fn;
120    L->top -= n;
121 -  while (n--)
122 +  while (n--) {
123      setobj2n(L, &cl->c.upvalue[n], L->top+n);
124 +    setnilvalue(L, L->top + n);
125 +  }
126    setclvalue(L, L->top, cl);
127    lua_assert(iswhite(obj2gco(cl)));
128    api_incr_top(L);
129 @@ -600,7 +606,7 @@ LUA_API void lua_gettable (lua_State *L,
130  
131  LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
132    StkId t;
133 -  TValue key;
134 +  TValue key = tvinit();
135    lua_lock(L);
136    t = index2adr(L, idx);
137    api_checkvalidindex(L, t);
138 @@ -689,7 +695,7 @@ LUA_API void lua_getfenv (lua_State *L, 
139        setobj2s(L, L->top,  gt(thvalue(o)));
140        break;
141      default:
142 -      setnilvalue(L->top);
143 +      setnilvalue(L, L->top);
144        break;
145    }
146    api_incr_top(L);
147 @@ -709,21 +715,21 @@ LUA_API void lua_settable (lua_State *L,
148    t = index2adr(L, idx);
149    api_checkvalidindex(L, t);
150    luaV_settable(L, t, L->top - 2, L->top - 1);
151 -  L->top -= 2;  /* pop index and value */
152 +  setlvmtop(L, L->top - 2);  /* pop index and value */
153    lua_unlock(L);
154  }
155  
156  
157  LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
158    StkId t;
159 -  TValue key;
160 +  TValue key = tvinit();
161    lua_lock(L);
162    api_checknelems(L, 1);
163    t = index2adr(L, idx);
164    api_checkvalidindex(L, t);
165    setsvalue(L, &key, luaS_new(L, k));
166    luaV_settable(L, t, &key, L->top - 1);
167 -  L->top--;  /* pop value */
168 +  setlvmtop(L, L->top - 1);  /* pop value */
169    lua_unlock(L);
170  }
171  
172 @@ -736,7 +742,7 @@ LUA_API void lua_rawset (lua_State *L, i
173    api_check(L, ttistable(t));
174    setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
175    luaC_barriert(L, hvalue(t), L->top-1);
176 -  L->top -= 2;
177 +  setlvmtop(L, L->top - 2);
178    lua_unlock(L);
179  }
180  
181 @@ -749,7 +755,7 @@ LUA_API void lua_rawseti (lua_State *L, 
182    api_check(L, ttistable(o));
183    setobj2t(L, luaH_setint(L, hvalue(o), n), L->top-1);
184    luaC_barriert(L, hvalue(o), L->top-1);
185 -  L->top--;
186 +  setlvmtop(L, L->top - 1);
187    lua_unlock(L);
188  }
189  
190 @@ -785,7 +791,7 @@ LUA_API int lua_setmetatable (lua_State 
191        break;
192      }
193    }
194 -  L->top--;
195 +  setlvmtop(L, L->top - 1);
196    lua_unlock(L);
197    return 1;
198  }
199 @@ -814,7 +820,7 @@ LUA_API int lua_setfenv (lua_State *L, i
200        break;
201    }
202    if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
203 -  L->top--;
204 +  setlvmtop(L, L->top - 1);
205    lua_unlock(L);
206    return res;
207  }
208 @@ -1040,20 +1046,21 @@ LUA_API int lua_next (lua_State *L, int 
209    if (more) {
210      api_incr_top(L);
211    }
212 -  else  /* no more elements */
213 -    L->top -= 1;  /* remove key */
214 +  else {  /* no more elements */
215 +    setlvmtop(L, L->top - 1);  /* remove key */
216 +  }
217    lua_unlock(L);
218    return more;
219  }
220  
221  
222  LUA_API void lua_concat (lua_State *L, int n) {
223    lua_lock(L);
224    api_checknelems(L, n);
225    if (n >= 2) {
226      luaC_checkGC(L);
227      luaV_concat(L, n, cast_int(L->top - L->base) - 1);
228 -    L->top -= (n-1);
229 +    setlvmtop(L, L->top - (n-1));
230    }
231    else if (n == 0) {  /* push empty string */
232      setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
233 @@ -1139,6 +1147,7 @@ LUA_API const char *lua_setupvalue (lua_
234    if (name) {
235      L->top--;
236      setobj(L, val, L->top);
237 +    setnilvalue(L, L->top);
238      luaC_barrier(L, clvalue(fi), L->top);
239    }
240    lua_unlock(L);
241 @@ -1160,7 +1169,7 @@ LUA_API const char *lua_setupvalue (lua_
242  int lua_pushvalue_as_number (lua_State *L, int idx)
243  {
244    const TValue *o = index2adr(L, idx);
245 -  TValue tmp;
246 +  TValue tmp = tvinit();
247    lua_Integer i;
248    if (ttisnumber(o)) {
249      if ( (!ttisint(o)) && tt_integer_valued(o,&i)) {
250 --- a/src/lcode.c
251 +++ b/src/lcode.c
252 @@ -23,6 +23,7 @@
253  #include "lparser.h"
254  #include "ltable.h"
255  #include "lnum.h"
256 +#include "lvm.h"
257  
258  
259  #define hasjumps(e)    ((e)->t != (e)->f)
260 @@ -248,7 +249,7 @@ static int addk (FuncState *fs, TValue *
261      setivalue(idx, fs->nk);
262      luaM_growvector(L, f->k, fs->nk, f->sizek, TValue,
263                      MAXARG_Bx, "constant table overflow");
264 -    while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
265 +    while (oldsize < f->sizek) setnilvalue(L, &f->k[oldsize++]);
266      setobj(L, &f->k[fs->nk], v);
267      luaC_barrier(L, f, v);
268      return fs->nk++;
269 @@ -257,21 +258,24 @@ static int addk (FuncState *fs, TValue *
270  
271  
272  int luaK_stringK (FuncState *fs, TString *s) {
273 -  TValue o;
274 +  TValue o = tvinit();
275    setsvalue(fs->L, &o, s);
276 +  luaV_unref(fs->L, &o);
277    return addk(fs, &o, &o);
278  }
279  
280  
281  int luaK_numberK (FuncState *fs, lua_Number r) {
282 -  TValue o;
283 +  lua_State *L = fs->L;
284 +  TValue o = tvinit();
285    setnvalue(&o, r);
286    return addk(fs, &o, &o);
287  }
288  
289  
290  int luaK_integerK (FuncState *fs, lua_Integer r) {
291 -  TValue o;
292 +  lua_State *L = fs->L;
293 +  TValue o = tvinit();
294    setivalue(&o, r);
295    return addk(fs, &o, &o);
296  }
297 @@ -279,22 +283,24 @@ int luaK_integerK (FuncState *fs, lua_In
298  
299  #ifdef LNUM_COMPLEX
300  static int luaK_imagK (FuncState *fs, lua_Number r) {
301 -  TValue o;
302 +  lua_State *L = fs->L;
303 +  TValue o = tvinit();
304    setnvalue_complex(&o, r*I);
305    return addk(fs, &o, &o);
306  }
307  #endif
308  
309  static int boolK (FuncState *fs, int b) {
310 -  TValue o;
311 +  lua_State *L = fs->L;
312 +  TValue o = tvinit();
313    setbvalue(&o, b);
314    return addk(fs, &o, &o);
315  }
316  
317  
318  static int nilK (FuncState *fs) {
319 -  TValue k, v;
320 -  setnilvalue(&v);
321 +  TValue k = tvinit(), v = tvinit();
322 +  setnilvalue(fs->L, &v);
323    /* cannot use nil as key; instead use table itself to represent nil */
324    sethvalue(fs->L, &k, fs->h);
325    return addk(fs, &k, &v);
326 --- a/src/ldebug.c
327 +++ b/src/ldebug.c
328 @@ -142,6 +142,7 @@ LUA_API const char *lua_setlocal (lua_St
329    if (name)
330        setobjs2s(L, ci->base + (n - 1), L->top - 1);
331    L->top--;  /* pop value */
332 +  setnilvalue(L, L->top);
333    lua_unlock(L);
334    return name;
335  }
336 @@ -176,7 +177,7 @@ static void info_tailcall (lua_Debug *ar
337  
338  static void collectvalidlines (lua_State *L, Closure *f) {
339    if (f == NULL || f->c.isC) {
340 -    setnilvalue(L->top);
341 +    setnilvalue(L, L->top);
342    }
343    else {
344      Table *t = luaH_new(L, 0, 0);
345 @@ -248,7 +249,7 @@ LUA_API int lua_getinfo (lua_State *L, c
346    }
347    status = auxgetinfo(L, what, ar, f, ci);
348    if (strchr(what, 'f')) {
349 -    if (f == NULL) setnilvalue(L->top);
350 +    if (f == NULL) setnilvalue(L, L->top);
351      else setclvalue(L, L->top, f);
352      incr_top(L);
353    }
354 @@ -586,7 +587,7 @@ void luaG_concaterror (lua_State *L, Stk
355  
356  
357  void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
358 -  TValue temp;
359 +  TValue temp = tvinit();
360    if (luaV_tonumber(p1, &temp) == NULL)
361      p2 = p1;  /* first operand is wrong */
362    luaG_typeerror(L, p2, "perform arithmetic on");
363 --- a/src/ldo.c
364 +++ b/src/ldo.c
365 @@ -211,7 +211,7 @@ static StkId adjust_varargs (lua_State *
366    Table *htab = NULL;
367    StkId base, fixed;
368    for (; actual < nfixargs; ++actual)
369 -    setnilvalue(L->top++);
370 +    setnilvalue(L, L->top++);
371  #if defined(LUA_COMPAT_VARARG)
372    if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */
373      int nvar = actual - nfixargs;  /* number of extra arguments */
374 @@ -229,7 +229,7 @@ static StkId adjust_varargs (lua_State *
375    base = L->top;  /* final position of first argument */
376    for (i=0; i<nfixargs; i++) {
377      setobjs2s(L, L->top++, fixed+i);
378 -    setnilvalue(fixed+i);
379 +    setnilvalue(L, fixed+i);
380    }
381    /* add `arg' parameter */
382    if (htab) {
383 @@ -294,7 +294,7 @@ int luaD_precall (lua_State *L, StkId fu
384      ci->tailcalls = 0;
385      ci->nresults = nresults;
386      for (st = L->top; st < ci->top; st++)
387 -      setnilvalue(st);
388 +      setnilvalue(L, st);
389      L->top = ci->top;
390      if (L->hookmask & LUA_MASKCALL) {
391        L->savedpc++;  /* hooks assume 'pc' is already incremented */
392 @@ -354,8 +354,8 @@ int luaD_poscall (lua_State *L, StkId fi
393    for (i = wanted; i != 0 && firstResult < L->top; i--)
394      setobjs2s(L, res++, firstResult++);
395    while (i-- > 0)
396 -    setnilvalue(res++);
397 -  L->top = res;
398 +    setnilvalue(L, res++);
399 +  setlvmtop(L, res);
400    return (wanted - LUA_MULTRET);  /* 0 iff wanted == LUA_MULTRET */
401  }
402  
403 @@ -463,8 +463,12 @@ int luaD_pcall (lua_State *L, Pfunc func
404    status = luaD_rawrunprotected(L, func, u);
405    if (status != 0) {  /* an error occurred? */
406      StkId oldtop = restorestack(L, old_top);
407 +       StkId curtop = L->top;
408 +    int i;
409      luaF_close(L, oldtop);  /* close eventual pending closures */
410      luaD_seterrorobj(L, status, oldtop);
411 +    for (i = (curtop - L->top); i-- > 0;)
412 +      setnilvalue(L, L->top + i);
413      L->nCcalls = oldnCcalls;
414      L->ci = restoreci(L, old_ci);
415      L->base = L->ci->base;
416 --- a/src/lfunc.c
417 +++ b/src/lfunc.c
418 @@ -17,7 +17,7 @@
419  #include "lmem.h"
420  #include "lobject.h"
421  #include "lstate.h"
422 -
423 +#include "lvm.h"
424  
425  
426  Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) {
427 @@ -45,7 +45,7 @@ UpVal *luaF_newupval (lua_State *L) {
428    UpVal *uv = luaM_new(L, UpVal);
429    luaC_link(L, obj2gco(uv), LUA_TUPVAL);
430    uv->v = &uv->u.value;
431 -  setnilvalue(uv->v);
432 +  setnilvalue(L, uv->v);
433    return uv;
434  }
435  
436 @@ -67,8 +67,14 @@ UpVal *luaF_findupval (lua_State *L, Stk
437    uv = luaM_new(L, UpVal);  /* not found: create a new one */
438    uv->tt = LUA_TUPVAL;
439    uv->marked = luaC_white(g);
440 -  uv->v = level;  /* current value lives in the stack */
441 +  uv->v = luaV_ref(level);  /* current value lives in the stack */
442    uv->next = *pp;  /* chain it in the proper position */
443 +  if (uv->next) {
444 +       uv->prev = uv->next->gch.prev;
445 +    uv->next->gch.prev = (GCObject *)uv;
446 +  } else {
447 +    uv->prev = NULL;
448 +  }
449    *pp = obj2gco(uv);
450    uv->u.l.prev = &g->uvhead;  /* double link it in `uvhead' list */
451    uv->u.l.next = g->uvhead.u.l.next;
452 --- a/src/lgc.c
453 +++ b/src/lgc.c
454 @@ -21,6 +21,7 @@
455  #include "lstring.h"
456  #include "ltable.h"
457  #include "ltm.h"
458 +#include "lvm.h"
459  
460  
461  #define GCSTEPSIZE     1024u
462 @@ -265,7 +266,7 @@ static void traversestack (global_State 
463    for (o = l->stack; o < l->top; o++)
464      markvalue(g, o);
465    for (; o <= lim; o++)
466 -    setnilvalue(o);
467 +    setnilvalue(l, o);
468    checkstacksizes(l, lim);
469  }
470  
471 @@ -348,7 +349,7 @@ static int iscleared (const TValue *o, i
472  /*
473  ** clear collected entries from weaktables
474  */
475 -static void cleartable (GCObject *l) {
476 +static void cleartable (lua_State *L, GCObject *l) {
477    while (l) {
478      Table *h = gco2h(l);
479      int i = h->sizearray;
480 @@ -358,7 +359,7 @@ static void cleartable (GCObject *l) {
481        while (i--) {
482          TValue *o = &h->array[i];
483          if (iscleared(o, 0))  /* value was collected? */
484 -          setnilvalue(o);  /* remove value */
485 +          setnilvalue(L, o);  /* remove value */
486        }
487      }
488      i = sizenode(h);
489 @@ -366,7 +367,7 @@ static void cleartable (GCObject *l) {
490        Node *n = gnode(h, i);
491        if (!ttisnil(gval(n)) &&  /* non-empty entry? */
492            (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) {
493 -        setnilvalue(gval(n));  /* remove value ... */
494 +        setnilvalue(L, gval(n));  /* remove value ... */
495          removeentry(n);  /* remove entry from table */
496        }
497      }
498 @@ -375,7 +376,7 @@ static void cleartable (GCObject *l) {
499  }
500  
501  
502 -static void freeobj (lua_State *L, GCObject *o) {
503 +void luaC_freeobj (lua_State *L, GCObject *o) {
504    switch (o->gch.tt) {
505      case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
506      case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break;
507 @@ -418,10 +419,12 @@ static GCObject **sweeplist (lua_State *
508      }
509      else {  /* must erase `curr' */
510        lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT));
511 +      if (curr->gch.next)
512 +        curr->gch.next->gch.prev = curr->gch.prev;
513        *p = curr->gch.next;
514        if (curr == g->rootgc)  /* is the first element of the list? */
515          g->rootgc = curr->gch.next;  /* adjust first */
516 -      freeobj(L, curr);
517 +      luaC_freeobj(L, curr);
518      }
519    }
520    return p;
521 @@ -543,7 +551,7 @@ static void atomic (lua_State *L) {
522    udsize = luaC_separateudata(L, 0);  /* separate userdata to be finalized */
523    marktmu(g);  /* mark `preserved' userdata */
524    udsize += propagateall(g);  /* remark, to propagate `preserveness' */
525 -  cleartable(g->weak);  /* remove collected objects from weak tables */
526 +  cleartable(L, g->weak);  /* remove collected objects from weak tables */
527    /* flip current white */
528    g->currentwhite = cast_byte(otherwhite(g));
529    g->sweepstrgc = 0;
530 @@ -685,8 +693,11 @@ void luaC_barrierback (lua_State *L, Tab
531  
532  void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {
533    global_State *g = G(L);
534 +  o->gch.prev = (GCObject*)&g->rootgc;
535    o->gch.next = g->rootgc;
536    g->rootgc = o;
537 +  if (o->gch.next)
538 +    o->gch.next->gch.prev = o;
539    o->gch.marked = luaC_white(g);
540    o->gch.tt = tt;
541  }
542 --- a/src/lgc.h
543 +++ b/src/lgc.h
544 @@ -105,6 +105,6 @@ LUAI_FUNC void luaC_link (lua_State *L, 
545  LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv);
546  LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v);
547  LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t);
548 -
549 +LUAI_FUNC void luaC_freeobj (lua_State *L, GCObject *o);
550  
551  #endif
552 --- a/src/lmem.c
553 +++ b/src/lmem.c
554 @@ -6,6 +6,7 @@
555  
556  
557  #include <stddef.h>
558 +#include <string.h>
559  
560  #define lmem_c
561  #define LUA_CORE
562 @@ -80,6 +81,8 @@ void *luaM_realloc_ (lua_State *L, void 
563    if (block == NULL && nsize > 0)
564      luaD_throw(L, LUA_ERRMEM);
565    lua_assert((nsize == 0) == (block == NULL));
566 +  if (nsize > osize)
567 +    memset((char *)block + osize, 0, nsize - osize);
568    g->totalbytes = (g->totalbytes - osize) + nsize;
569    return block;
570  }
571 --- a/src/lobject.h
572 +++ b/src/lobject.h
573 @@ -44,7 +44,7 @@ typedef union GCObject GCObject;
574  ** Common Header for all collectable objects (in macro form, to be
575  ** included in other objects)
576  */
577 -#define CommonHeader   GCObject *next; lu_byte tt; lu_byte marked
578 +#define CommonHeader   GCObject *next; GCObject *prev; lu_byte tt; lu_byte marked
579  
580  
581  /*
582 @@ -83,6 +83,7 @@ typedef struct lua_TValue {
583    TValuefields;
584  } TValue;
585  
586 +#define tvinit() { .value.b = 0, .tt = 0 }
587  
588  /* Macros to test type */
589  #define ttisnil(o)     (ttype(o) == LUA_TNIL)
590 @@ -145,15 +146,15 @@ typedef struct lua_TValue {
591  
592  
593  /* Macros to set values */
594 -#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
595 +#define setnilvalue(L, obj) (luaV_unref(L, (obj))->tt=LUA_TNIL)
596  
597  /* Must not have side effects, 'x' may be expression.
598  */
599  #define setivalue(obj,x) \
600 -    { TValue *i_o=(obj); i_o->value.i=(x); i_o->tt=LUA_TINT; }
601 +    { TValue *i_o=luaV_unref(L, (obj)); i_o->value.i=(x); i_o->tt=LUA_TINT; }
602  
603  # define setnvalue(obj,x) \
604 -    { TValue *i_o=(obj); i_o->value.n= (x); i_o->tt=LUA_TNUMBER; }
605 +    { TValue *i_o=luaV_unref(L, (obj)); i_o->value.n= (x); i_o->tt=LUA_TNUMBER; }
606  
607  /* Note: Complex always has "inline", both are C99.
608  */
609 @@ -170,45 +171,45 @@ typedef struct lua_TValue {
610  
611  
612  #define setpvalue(obj,x) \
613 -  { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
614 +  { TValue *i_o=luaV_unref(L, (obj)); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
615  
616  #define setbvalue(obj,x) \
617 -  { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; }
618 +  { TValue *i_o=luaV_unref(L, (obj)); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; }
619  
620  #define setsvalue(L,obj,x) \
621 -  { TValue *i_o=(obj); \
622 -    i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \
623 +  { TValue *i_o=(obj); TString *val=(x); luaS_ref(val); luaV_unref(L, obj); \
624 +    i_o->value.gc=cast(GCObject *, (val)); i_o->tt=LUA_TSTRING; \
625      checkliveness(G(L),i_o); }
626  
627  #define setuvalue(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_TUSERDATA; \
631      checkliveness(G(L),i_o); }
632  
633  #define setthvalue(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_TTHREAD; \
637      checkliveness(G(L),i_o); }
638  
639  #define setclvalue(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_TFUNCTION; \
643      checkliveness(G(L),i_o); }
644  
645  #define sethvalue(L,obj,x) \
646 -  { TValue *i_o=(obj); \
647 +  { TValue *i_o=luaV_unref(L, (obj)); \
648      i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \
649      checkliveness(G(L),i_o); }
650  
651  #define setptvalue(L,obj,x) \
652 -  { TValue *i_o=(obj); \
653 +  { TValue *i_o=luaV_unref(L, (obj)); \
654      i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \
655      checkliveness(G(L),i_o); }
656  
657  #define setobj(L,obj1,obj2) \
658 -  { const TValue *o2=(obj2); TValue *o1=(obj1); \
659 +  do { const TValue *o2=luaV_ref((TValue *)(obj2)); TValue *o1=luaV_unref(L, (obj1)); \
660      o1->value = o2->value; o1->tt=o2->tt; \
661 -    checkliveness(G(L),o1); }
662 +    checkliveness(G(L),o1); } while(0)
663  
664  
665  /*
666 @@ -253,6 +254,7 @@ typedef union TString {
667      lu_byte reserved;
668      unsigned int hash;
669      size_t len;
670 +    int refcount;
671    } tsv;
672  } TString;
673  
674 @@ -409,6 +411,7 @@ typedef struct Table {
675  #define twoto(x)       (1<<(x))
676  #define sizenode(t)    (twoto((t)->lsizenode))
677  
678 +#include "lstring.h"
679  
680  #define luaO_nilobject         (&luaO_nilobject_)
681  
682 --- a/src/lparser.c
683 +++ b/src/lparser.c
684 @@ -24,6 +24,7 @@
685  #include "lstate.h"
686  #include "lstring.h"
687  #include "ltable.h"
688 +#include "lvm.h"
689  
690  
691  
692 @@ -146,7 +147,7 @@ static int registerlocalvar (LexState *l
693    luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
694                    LocVar, SHRT_MAX, "too many local variables");
695    while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
696 -  f->locvars[fs->nlocvars].varname = varname;
697 +  f->locvars[fs->nlocvars].varname = luaS_ref(varname);
698    luaC_objbarrier(ls->L, f, varname);
699    return fs->nlocvars++;
700  }
701 @@ -194,7 +195,7 @@ static int indexupvalue (FuncState *fs, 
702    luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues,
703                    TString *, MAX_INT, "");
704    while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL;
705 -  f->upvalues[f->nups] = name;
706 +  f->upvalues[f->nups] = luaS_ref(name);
707    luaC_objbarrier(fs->L, f, name);
708    lua_assert(v->k == VLOCAL || v->k == VUPVAL);
709    fs->upvalues[f->nups].k = cast_byte(v->k);
710 @@ -341,7 +342,7 @@ static void open_func (LexState *ls, Fun
711    fs->nlocvars = 0;
712    fs->nactvar = 0;
713    fs->bl = NULL;
714 -  f->source = ls->source;
715 +  f->source = luaS_ref(ls->source);
716    f->maxstacksize = 2;  /* registers 0/1 are always valid */
717    fs->h = luaH_new(L, 0, 0);
718    /* anchor table of constants and prototype (to avoid being collected) */
719 --- a/src/lstate.c
720 +++ b/src/lstate.c
721 @@ -22,6 +22,7 @@
722  #include "lstring.h"
723  #include "ltable.h"
724  #include "ltm.h"
725 +#include "lvm.h"
726  
727  
728  #define state_size(x)  (sizeof(x) + LUAI_EXTRASPACE)
729 @@ -52,7 +53,7 @@ static void stack_init (lua_State *L1, l
730    L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
731    /* initialize first ci */
732    L1->ci->func = L1->top;
733 -  setnilvalue(L1->top++);  /* `function' entry for this `ci' */
734 +  setnilvalue(L1, L1->top++);  /* `function' entry for this `ci' */
735    L1->base = L1->ci->base = L1->top;
736    L1->ci->top = L1->top + LUA_MINSTACK;
737  }
738 @@ -98,7 +99,7 @@ static void preinit_state (lua_State *L,
739    L->base_ci = L->ci = NULL;
740    L->savedpc = NULL;
741    L->errfunc = 0;
742 -  setnilvalue(gt(L));
743 +  setnilvalue(L, gt(L));
744  }
745  
746  
747 @@ -163,7 +164,7 @@ LUA_API lua_State *lua_newstate (lua_All
748    g->strt.size = 0;
749    g->strt.nuse = 0;
750    g->strt.hash = NULL;
751 -  setnilvalue(registry(L));
752 +  setnilvalue(L, registry(L));
753    luaZ_initbuffer(L, &g->buff);
754    g->panic = NULL;
755    g->gcstate = GCSpause;
756 --- a/src/lstring.c
757 +++ b/src/lstring.c
758 @@ -37,6 +37,9 @@ void luaS_resize (lua_State *L, int news
759        int h1 = lmod(h, newsize);  /* new position */
760        lua_assert(cast_int(h%newsize) == lmod(h, newsize));
761        p->gch.next = newhash[h1];  /* chain it */
762 +      if (p->gch.next)
763 +        p->gch.next->gch.prev = p;
764 +      p->gch.prev = NULL;
765        newhash[h1] = p;
766        p = next;
767      }
768 @@ -59,11 +62,15 @@ static TString *newlstr (lua_State *L, c
769    ts->tsv.marked = luaC_white(G(L));
770    ts->tsv.tt = LUA_TSTRING;
771    ts->tsv.reserved = 0;
772 +  ts->tsv.refcount = 0;
773    memcpy(ts+1, str, l*sizeof(char));
774    ((char *)(ts+1))[l] = '\0';  /* ending 0 */
775    tb = &G(L)->strt;
776    h = lmod(h, tb->size);
777    ts->tsv.next = tb->hash[h];  /* chain new entry */
778 +  if (ts->tsv.next)
779 +    ts->tsv.next->gch.prev = (GCObject *)ts;
780 +  ts->tsv.prev = NULL;
781    tb->hash[h] = obj2gco(ts);
782    tb->nuse++;
783    if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
784 @@ -109,3 +116,29 @@ Udata *luaS_newudata (lua_State *L, size
785    return u;
786  }
787  
788 +void luaS_unref(lua_State *L, TString *ts) {
789 +  if (!L || !ts)
790 +    return;
791 +  if (testbit(ts->tsv.marked, FIXEDBIT))
792 +    return;
793 +  ts->tsv.refcount--;
794 +  if (ts->tsv.refcount < 0) {
795 +    fprintf(stderr, "REFCOUNT BUG, COUNT=%d, str=%s, len=%d\n", ts->tsv.refcount, (char *) (ts + 1), (int) ts->tsv.len);
796 +  } else if (ts->tsv.refcount)
797 +    return;
798 +
799 +  if (ts->tsv.prev) {
800 +    ts->tsv.prev->gch.next = ts->tsv.next;
801 +  } else {
802 +    unsigned int idx = lmod(ts->tsv.hash, G(L)->strt.size);
803 +    lua_assert(G(L)->strt.hash[index] == (GCObject*)ts);
804 +    G(L)->strt.hash[idx] = ts->tsv.next;
805 +  }
806 +
807 +  if (ts->tsv.next)
808 +    ts->tsv.next->gch.prev = ts->tsv.prev;
809 +
810 +  luaC_freeobj(L, (GCObject *) ts);
811 +}
812 +
813 +
814 --- a/src/lstring.h
815 +++ b/src/lstring.h
816 @@ -7,7 +7,7 @@
817  #ifndef lstring_h
818  #define lstring_h
819  
820 -
821 +#include <stdio.h>
822  #include "lgc.h"
823  #include "lobject.h"
824  #include "lstate.h"
825 @@ -23,6 +23,12 @@
826  
827  #define luaS_fix(s)    l_setbit((s)->tsv.marked, FIXEDBIT)
828  
829 +static inline TString *luaS_ref(TString *ts) {
830 +  ts->tsv.refcount++;
831 +  return ts;
832 +}
833 +
834 +LUA_API void luaS_unref(lua_State *L, TString *ts);
835  LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
836  LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
837  LUA_API TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
838 --- a/src/ltable.c
839 +++ b/src/ltable.c
840 @@ -34,6 +34,7 @@
841  #include "lstate.h"
842  #include "ltable.h"
843  #include "lnum.h"
844 +#include "lvm.h"
845  
846  
847  /*
848 @@ -278,7 +279,7 @@ static void setarrayvector (lua_State *L
849    int i;
850    luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
851    for (i=t->sizearray; i<size; i++)
852 -     setnilvalue(&t->array[i]);
853 +     setnilvalue(L, &t->array[i]);
854    t->sizearray = size;
855  }
856  
857 @@ -299,8 +300,8 @@ static void setnodevector (lua_State *L,
858      for (i=0; i<size; i++) {
859        Node *n = gnode(t, i);
860        gnext(n) = NULL;
861 -      setnilvalue(gkey(n));
862 -      setnilvalue(gval(n));
863 +      setnilvalue(L, gkey(n));
864 +      setnilvalue(L, gval(n));
865      }
866    }
867    t->lsizenode = cast_byte(lsize);
868 @@ -427,9 +428,11 @@ static TValue *newkey (lua_State *L, Tab
869          othern = gnext(othern);  /* find previous */
870        }
871        gnext(othern) = n;  /* redo the chain with `n' in place of `mp' */
872 +      luaV_ref((TValue *) gkey(mp));
873 +      luaV_ref(gval(mp));
874        *n = *mp;  /* copy colliding node into free pos. (mp->next also goes) */
875        gnext(mp) = NULL;  /* now `mp' is free */
876 -      setnilvalue(gval(mp));
877 +      setnilvalue(L, gval(mp));
878      }
879      else {  /* colliding node is in its own main position */
880        /* new node will go into free position */
881 @@ -438,6 +441,7 @@ static TValue *newkey (lua_State *L, Tab
882        mp = n;
883      }
884    }
885 +  luaV_ref((TValue *) key);
886    gkey(mp)->value = key->value; gkey(mp)->tt = key->tt;
887    luaC_barriert(L, t, key);
888    lua_assert(ttisnil(gval(mp)));
889 @@ -530,7 +534,7 @@ TValue *luaH_setint (lua_State *L, Table
890    if (p != luaO_nilobject)
891      return cast(TValue *, p);
892    else {
893 -    TValue k;
894 +    TValue k = tvinit();
895      setivalue(&k, key);
896      return newkey(L, t, &k);
897    }
898 @@ -542,7 +546,7 @@ TValue *luaH_setstr (lua_State *L, Table
899    if (p != luaO_nilobject)
900      return cast(TValue *, p);
901    else {
902 -    TValue k;
903 +    TValue k = tvinit();
904      setsvalue(L, &k, key);
905      return newkey(L, t, &k);
906    }
907 --- a/src/luac.c
908 +++ b/src/luac.c
909 @@ -20,8 +20,9 @@
910  #include "lmem.h"
911  #include "lobject.h"
912  #include "lopcodes.h"
913 -#include "lstring.h"
914  #include "lundump.h"
915 +#include "lvm.h"
916 +#include "lstring.h"
917  
918  #define PROGNAME       "luac"          /* default program name */
919  #define        OUTPUT          PROGNAME ".out" /* default output file */
920 --- a/src/lundump.c
921 +++ b/src/lundump.c
922 @@ -19,6 +19,7 @@
923  #include "lstring.h"
924  #include "lundump.h"
925  #include "lzio.h"
926 +#include "lvm.h"
927  
928  typedef struct {
929   lua_State* L;
930 @@ -133,7 +134,7 @@ static TString* LoadString(LoadState* S)
931   {
932    char* s=luaZ_openspace(S->L,S->b,size);
933    LoadBlock(S,s,size);
934 -  return luaS_newlstr(S->L,s,size-1);          /* remove trailing '\0' */
935 +  return luaS_ref(luaS_newlstr(S->L,s,size-1));                /* remove trailing '\0' */
936   }
937  }
938  
939 @@ -149,11 +150,12 @@ static Proto* LoadFunction(LoadState* S,
940  
941  static void LoadConstants(LoadState* S, Proto* f)
942  {
943 + lua_State *L = S->L;
944   int i,n;
945   n=LoadInt(S);
946   f->k=luaM_newvector(S->L,n,TValue);
947   f->sizek=n;
948 - for (i=0; i<n; i++) setnilvalue(&f->k[i]);
949 + for (i=0; i<n; i++) setnilvalue(L, &f->k[i]);
950   for (i=0; i<n; i++)
951   {
952    TValue* o=&f->k[i];
953 @@ -161,7 +163,7 @@ static void LoadConstants(LoadState* S, 
954    switch (t)
955    {
956     case LUA_TNIL:
957 -       setnilvalue(o);
958 +       setnilvalue(L, o);
959         break;
960     case LUA_TBOOLEAN:
961         setbvalue(o,LoadChar(S)!=0);
962 @@ -229,6 +231,7 @@ static Proto* LoadFunction(LoadState* S,
963   LoadDebug(S,f);
964   IF (!luaG_checkcode(f), "bad code");
965   S->L->top--;
966 + setnilvalue(S->L, S->L->top);
967   S->L->nCcalls--;
968   return f;
969  }
970 --- a/src/lvm.c
971 +++ b/src/lvm.c
972 @@ -39,6 +39,7 @@
973   * If 'obj' is a string, it is tried to be interpreted as a number.
974   */
975  const TValue *luaV_tonumber ( const TValue *obj, TValue *n) {
976 +  lua_State *L = NULL; /* FIXME */
977    lua_Number d;
978    lua_Integer i;
979    
980 @@ -384,6 +386,7 @@ void luaV_concat (lua_State *L, int tota
981          size_t l = tsvalue(top-i)->len;
982          memcpy(buffer+tl, svalue(top-i), l);
983          tl += l;
984 +               setnilvalue(L, top - i);
985        }
986        setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
987      }
988 @@ -420,7 +423,7 @@ void luaV_concat (lua_State *L, int tota
989   */
990  static void Arith (lua_State *L, StkId ra, const TValue *rb,
991                     const TValue *rc, TMS op) {
992 -  TValue tempb, tempc;
993 +  TValue tempb = tvinit(), tempc = tvinit();
994    const TValue *b, *c;
995    lua_Number nb,nc;
996  
997 @@ -663,7 +666,7 @@ void luaV_execute (lua_State *L, int nex
998        OPCODE_TARGET(LOADNIL) {
999          TValue *rb = RB(i);
1000          do {
1001 -          setnilvalue(rb--);
1002 +          setnilvalue(L, rb--);
1003          } while (rb >= ra);
1004          continue;
1005        }
1006 @@ -673,7 +676,7 @@ void luaV_execute (lua_State *L, int nex
1007          continue;
1008        }
1009        OPCODE_TARGET(GETGLOBAL) {
1010 -        TValue g;
1011 +        TValue g = tvinit();
1012          TValue *rb = KBx(i);
1013          sethvalue(L, &g, cl->env);
1014          lua_assert(ttisstring(rb));
1015 @@ -685,7 +688,7 @@ void luaV_execute (lua_State *L, int nex
1016          continue;
1017        }
1018        OPCODE_TARGET(SETGLOBAL) {
1019 -        TValue g;
1020 +        TValue g = tvinit();
1021          sethvalue(L, &g, cl->env);
1022          lua_assert(ttisstring(KBx(i)));
1023          Protect(luaV_settable(L, &g, KBx(i), ra));
1024 @@ -895,7 +900,7 @@ void luaV_execute (lua_State *L, int nex
1025          if (--nexeccalls == 0)  /* was previous function running `here'? */
1026            return;  /* no: return */
1027          else {  /* yes: continue its execution */
1028 -          if (b) L->top = L->ci->top;
1029 +          if (b) setlvmtop(L, L->ci->top);
1030            lua_assert(isLua(L->ci));
1031            lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL);
1032            goto reentry;
1033 @@ -986,6 +991,7 @@ void luaV_execute (lua_State *L, int nex
1034          for (; n > 0; n--) {
1035            TValue *val = ra+n;
1036            setobj2t(L, luaH_setint(L, h, last--), val);
1037 +          setnilvalue(L, val);
1038            luaC_barriert(L, h, val);
1039          }
1040          continue;
1041 @@ -1030,7 +1036,7 @@ void luaV_execute (lua_State *L, int nex
1042              setobjs2s(L, ra + j, ci->base - n + j);
1043            }
1044            else {
1045 -            setnilvalue(ra + j);
1046 +            setnilvalue(L, ra + j);
1047            }
1048          }
1049          continue;
1050 --- a/src/lvm.h
1051 +++ b/src/lvm.h
1052 @@ -11,6 +11,7 @@
1053  #include "ldo.h"
1054  #include "lobject.h"
1055  #include "ltm.h"
1056 +#include "lstring.h"
1057  
1058  
1059  #define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o)))
1060 @@ -19,6 +20,19 @@
1061  
1062  #define equalobj(L,o1,o2) (ttype_ext_same(o1,o2) && luaV_equalval(L, o1, o2))
1063  
1064 +static inline TValue *luaV_ref(TValue *tv)
1065 +{
1066 +  if (ttisstring(tv))
1067 +    luaS_ref(rawtsvalue(tv));
1068 +  return tv;
1069 +}
1070 +
1071 +static inline TValue *luaV_unref(lua_State *L, TValue *tv)
1072 +{
1073 +  if (ttisstring(tv))
1074 +    luaS_unref(L, rawtsvalue(tv));
1075 +  return tv;
1076 +}
1077  
1078  LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
1079  LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
1080 --- a/src/llex.c
1081 +++ b/src/llex.c
1082 @@ -23,6 +23,7 @@
1083  #include "ltable.h"
1084  #include "lzio.h"
1085  #include "lnum.h"
1086 +#include "lvm.h"
1087  
1088  
1089  
1090 @@ -69,7 +70,7 @@ static void save (LexState *ls, int c) {
1091  void luaX_init (lua_State *L) {
1092    int i;
1093    for (i=0; i<NUM_RESERVED; i++) {
1094 -    TString *ts = luaS_new(L, luaX_tokens[i]);
1095 +    TString *ts = luaS_ref(luaS_new(L, luaX_tokens[i]));
1096      luaS_fix(ts);  /* reserved words are never collected */
1097      lua_assert(strlen(luaX_tokens[i])+1 <= TOKEN_LEN);
1098      ts->tsv.reserved = cast_byte(i+1);  /* reserved word */
1099 @@ -125,7 +126,7 @@ void luaX_syntaxerror (LexState *ls, con
1100  
1101  TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
1102    lua_State *L = ls->L;
1103 -  TString *ts = luaS_newlstr(L, str, l);
1104 +  TString *ts = luaS_ref(luaS_newlstr(L, str, l));
1105    TValue *o = luaH_setstr(L, ls->fs->h, ts);  /* entry for `str' */
1106    if (ttisnil(o))
1107      setbvalue(o, 1);  /* make sure `str' will not be collected */
1108 @@ -152,7 +153,7 @@ void luaX_setinput (lua_State *L, LexSta
1109    ls->fs = NULL;
1110    ls->linenumber = 1;
1111    ls->lastline = 1;
1112 -  ls->source = source;
1113 +  ls->source = luaS_ref(source);
1114    luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER);  /* initialize buffer */
1115    next(ls);  /* read first char */
1116  }
1117 --- a/src/lstate.h
1118 +++ b/src/lstate.h
1119 @@ -144,6 +144,13 @@ union GCObject {
1120    struct lua_State th;  /* thread */
1121  };
1122  
1123 +#define setlvmtop(L, val) do { \
1124 +       int __i; \
1125 +       for (__i = L->top - val; __i-- > 0;) \
1126 +               setnilvalue(L, val + __i); \
1127 +       L->top = val; \
1128 +} while (0)
1129 +
1130  
1131  /* macros to convert a GCObject into a specific value */
1132  #define rawgco2ts(o)   check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts))