600-refcounting.patch 33 KB

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