674272feed104554a2090edf4c0eabc186b4e621
[openwrt/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))