600-refcounting.patch 33 KB

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