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