123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156157158159160161162163164165166167168169170171172173174175176177178179180181182183184185186187188189190191192193194195196197198199200201202203204205206207208209210211212213214215216217218219220221222223224225226227228229230231232233234235236237238239240241242243244245246247248249250251252253254255256257258259260261262263264265266267268269270271272273274275276277278279280281282283284285286287288289290291292293294295296297298299300301302303304305306307308309310311312313314315316317318319320321322323324325326327328329330331332333334335336337338339340341342343344345346347348349350351352353354355356357358359360361362363364365366367368369370371372373374375376377378379380381382383384385386387388389390391392393394395396397398399400401402403404405406407408409410411412413414415416417418419420421422423424425426427428429430431432433434435436437438439440441442443444445446447448449450451452453454455456457458459460461462463464465466467468469470471472473474475476477478479480481482483484485486487488489490491492493494495496497498499500501502503504505506507508509510511512513514515516517518519520521522523524525526527528529530531532533534535536537538539540541542543544545546547548549550551552553554555556557558559560561562563564565566567568569570571572573574575576577578579580581582583584585586587588589590591592593594595596597598599600601602603604605606607608609610611612613614615616617618619620621622623624625626627628629630631632633634635636637638639640641642643644645646647648649650651652653654655656657658659660661662663664665666667668669670671672673674675676677678679680681682683684685686687688689690691692693694695696697698699700701702703704705706707708709710711712713714715716717718719720721722723724725726727728729730731732733734735736737738739740741742743744745746747748749750751752753754755756757758759760761762763764765766767768769770771772773774775776777778779780781782783784785786787788789790791792793794795796797798799800801802803804805806807808809810811812813814815816817818819820821822823824825826827828829830831832833834835836837838839840841842843844845846847848849850851852853854855856857858859860861862863864865866867868869870871872873874875876877878879880881882883884885886887888889890891892893894895896897898899900901902903904905906907908909910911912913914915916917918919920921922923924925926927928929930931932933934935936937938939940941942943944945946947948949950951952953954955956957958959960961962963964965966967968969970971972973974975976977978979980981982983984985986987988989990991992993994995996997998999100010011002100310041005100610071008100910101011101210131014101510161017101810191020102110221023102410251026102710281029103010311032103310341035103610371038103910401041104210431044104510461047104810491050105110521053105410551056105710581059106010611062106310641065106610671068106910701071107210731074107510761077107810791080108110821083108410851086108710881089109010911092109310941095109610971098109911001101110211031104110511061107110811091110111111121113111411151116111711181119112011211122112311241125112611271128 |
- --- a/src/lapi.c
- +++ b/src/lapi.c
- @@ -27,8 +27,8 @@
- #include "ltable.h"
- #include "ltm.h"
- #include "lundump.h"
- -#include "lvm.h"
- #include "lnum.h"
- +#include "lvm.h"
-
-
- const char lua_ident[] =
- @@ -117,6 +117,7 @@ LUA_API void lua_xmove (lua_State *from,
- from->top -= n;
- for (i = 0; i < n; i++) {
- setobj2s(to, to->top++, from->top + i);
- + setnilvalue(from, from->top + i);
- }
- lua_unlock(to);
- }
- @@ -166,12 +167,14 @@ LUA_API void lua_settop (lua_State *L, i
- if (idx >= 0) {
- api_check(L, idx <= L->stack_last - L->base);
- while (L->top < L->base + idx)
- - setnilvalue(L->top++);
- + setnilvalue(L, L->top++);
- L->top = L->base + idx;
- + setnilvalue(L, L->top);
- }
- else {
- + int i;
- api_check(L, -(idx+1) <= (L->top - L->base));
- - L->top += idx+1; /* `subtract' index (index is negative) */
- + setlvmtop(L, L->top + idx + 1); /* `subtract' index (index is negative) */
- }
- lua_unlock(L);
- }
- @@ -183,7 +186,7 @@ LUA_API void lua_remove (lua_State *L, i
- p = index2adr(L, idx);
- api_checkvalidindex(L, p);
- while (++p < L->top) setobjs2s(L, p-1, p);
- - L->top--;
- + setlvmtop(L, L->top - 1);
- lua_unlock(L);
- }
-
- @@ -196,6 +199,7 @@ LUA_API void lua_insert (lua_State *L, i
- api_checkvalidindex(L, p);
- for (q = L->top; q>p; q--) setobjs2s(L, q, q-1);
- setobjs2s(L, p, L->top);
- + setnilvalue(L, L->top);
- lua_unlock(L);
- }
-
- @@ -220,7 +224,7 @@ LUA_API void lua_replace (lua_State *L,
- if (idx < LUA_GLOBALSINDEX) /* function upvalue? */
- luaC_barrier(L, curr_func(L), L->top - 1);
- }
- - L->top--;
- + setlvmtop(L, L->top - 1);
- lua_unlock(L);
- }
-
- @@ -259,14 +263,14 @@ LUA_API int lua_iscfunction (lua_State *
-
-
- LUA_API int lua_isnumber (lua_State *L, int idx) {
- - TValue n;
- + TValue n = tvinit();
- const TValue *o = index2adr(L, idx);
- return tonumber(o, &n);
- }
-
-
- LUA_API int lua_isinteger (lua_State *L, int idx) {
- - TValue tmp;
- + TValue tmp = tvinit();
- lua_Integer dum;
- const TValue *o = index2adr(L, idx);
- return tonumber(o,&tmp) && (ttisint(o) || tt_integer_valued(o,&dum));
- @@ -319,7 +323,7 @@ LUA_API int lua_lessthan (lua_State *L,
-
-
- LUA_API lua_Number lua_tonumber (lua_State *L, int idx) {
- - TValue n;
- + TValue n = tvinit();
- const TValue *o = index2adr(L, idx);
- if (tonumber(o, &n)) {
- #ifdef LNUM_COMPLEX
- @@ -333,7 +337,7 @@ LUA_API lua_Number lua_tonumber (lua_Sta
-
-
- LUA_API lua_Integer lua_tointeger (lua_State *L, int idx) {
- - TValue n;
- + TValue n = tvinit();
- /* Lua 5.1 documented behaviour is to return nonzero for non-integer:
- * "If the number is not an integer, it is truncated in some non-specified way."
- * I would suggest to change this, to return 0 for anything that would
- @@ -369,7 +373,7 @@ LUA_API lua_Integer lua_tointeger (lua_S
-
- #ifdef LNUM_COMPLEX
- LUA_API lua_Complex lua_tocomplex (lua_State *L, int idx) {
- - TValue tmp;
- + TValue tmp = tvinit();
- const TValue *o = index2adr(L, idx);
- if (tonumber(o, &tmp))
- return nvalue_complex(o);
- @@ -465,7 +469,7 @@ LUA_API const void *lua_topointer (lua_S
-
- LUA_API void lua_pushnil (lua_State *L) {
- lua_lock(L);
- - setnilvalue(L->top);
- + setnilvalue(L, L->top);
- api_incr_top(L);
- lua_unlock(L);
- }
- @@ -548,8 +552,10 @@ LUA_API void lua_pushcclosure (lua_State
- cl = luaF_newCclosure(L, n, getcurrenv(L));
- cl->c.f = fn;
- L->top -= n;
- - while (n--)
- + while (n--) {
- setobj2n(L, &cl->c.upvalue[n], L->top+n);
- + setnilvalue(L, L->top + n);
- + }
- setclvalue(L, L->top, cl);
- lua_assert(iswhite(obj2gco(cl)));
- api_incr_top(L);
- @@ -600,7 +606,7 @@ LUA_API void lua_gettable (lua_State *L,
-
- LUA_API void lua_getfield (lua_State *L, int idx, const char *k) {
- StkId t;
- - TValue key;
- + TValue key = tvinit();
- lua_lock(L);
- t = index2adr(L, idx);
- api_checkvalidindex(L, t);
- @@ -689,7 +695,7 @@ LUA_API void lua_getfenv (lua_State *L,
- setobj2s(L, L->top, gt(thvalue(o)));
- break;
- default:
- - setnilvalue(L->top);
- + setnilvalue(L, L->top);
- break;
- }
- api_incr_top(L);
- @@ -709,21 +715,21 @@ LUA_API void lua_settable (lua_State *L,
- t = index2adr(L, idx);
- api_checkvalidindex(L, t);
- luaV_settable(L, t, L->top - 2, L->top - 1);
- - L->top -= 2; /* pop index and value */
- + setlvmtop(L, L->top - 2); /* pop index and value */
- lua_unlock(L);
- }
-
-
- LUA_API void lua_setfield (lua_State *L, int idx, const char *k) {
- StkId t;
- - TValue key;
- + TValue key = tvinit();
- lua_lock(L);
- api_checknelems(L, 1);
- t = index2adr(L, idx);
- api_checkvalidindex(L, t);
- setsvalue(L, &key, luaS_new(L, k));
- luaV_settable(L, t, &key, L->top - 1);
- - L->top--; /* pop value */
- + setlvmtop(L, L->top - 1); /* pop value */
- lua_unlock(L);
- }
-
- @@ -736,7 +742,7 @@ LUA_API void lua_rawset (lua_State *L, i
- api_check(L, ttistable(t));
- setobj2t(L, luaH_set(L, hvalue(t), L->top-2), L->top-1);
- luaC_barriert(L, hvalue(t), L->top-1);
- - L->top -= 2;
- + setlvmtop(L, L->top - 2);
- lua_unlock(L);
- }
-
- @@ -749,7 +755,7 @@ LUA_API void lua_rawseti (lua_State *L,
- api_check(L, ttistable(o));
- setobj2t(L, luaH_setint(L, hvalue(o), n), L->top-1);
- luaC_barriert(L, hvalue(o), L->top-1);
- - L->top--;
- + setlvmtop(L, L->top - 1);
- lua_unlock(L);
- }
-
- @@ -785,7 +791,7 @@ LUA_API int lua_setmetatable (lua_State
- break;
- }
- }
- - L->top--;
- + setlvmtop(L, L->top - 1);
- lua_unlock(L);
- return 1;
- }
- @@ -814,7 +820,7 @@ LUA_API int lua_setfenv (lua_State *L, i
- break;
- }
- if (res) luaC_objbarrier(L, gcvalue(o), hvalue(L->top - 1));
- - L->top--;
- + setlvmtop(L, L->top - 1);
- lua_unlock(L);
- return res;
- }
- @@ -1040,8 +1046,9 @@ LUA_API int lua_next (lua_State *L, int
- if (more) {
- api_incr_top(L);
- }
- - else /* no more elements */
- - L->top -= 1; /* remove key */
- + else { /* no more elements */
- + setlvmtop(L, L->top - 1); /* remove key */
- + }
- lua_unlock(L);
- return more;
- }
- @@ -1053,7 +1060,7 @@ LUA_API void lua_concat (lua_State *L, i
- if (n >= 2) {
- luaC_checkGC(L);
- luaV_concat(L, n, cast_int(L->top - L->base) - 1);
- - L->top -= (n-1);
- + setlvmtop(L, L->top - (n-1));
- }
- else if (n == 0) { /* push empty string */
- setsvalue2s(L, L->top, luaS_newlstr(L, "", 0));
- @@ -1139,6 +1146,7 @@ LUA_API const char *lua_setupvalue (lua_
- if (name) {
- L->top--;
- setobj(L, val, L->top);
- + setnilvalue(L, L->top);
- luaC_barrier(L, clvalue(fi), L->top);
- }
- lua_unlock(L);
- @@ -1160,7 +1168,7 @@ LUA_API const char *lua_setupvalue (lua_
- int lua_pushvalue_as_number (lua_State *L, int idx)
- {
- const TValue *o = index2adr(L, idx);
- - TValue tmp;
- + TValue tmp = tvinit();
- lua_Integer i;
- if (ttisnumber(o)) {
- if ( (!ttisint(o)) && tt_integer_valued(o,&i)) {
- --- a/src/lcode.c
- +++ b/src/lcode.c
- @@ -23,6 +23,7 @@
- #include "lparser.h"
- #include "ltable.h"
- #include "lnum.h"
- +#include "lvm.h"
-
-
- #define hasjumps(e) ((e)->t != (e)->f)
- @@ -248,7 +249,7 @@ static int addk (FuncState *fs, TValue *
- setivalue(idx, fs->nk);
- luaM_growvector(L, f->k, fs->nk, f->sizek, TValue,
- MAXARG_Bx, "constant table overflow");
- - while (oldsize < f->sizek) setnilvalue(&f->k[oldsize++]);
- + while (oldsize < f->sizek) setnilvalue(L, &f->k[oldsize++]);
- setobj(L, &f->k[fs->nk], v);
- luaC_barrier(L, f, v);
- return fs->nk++;
- @@ -257,21 +258,24 @@ static int addk (FuncState *fs, TValue *
-
-
- int luaK_stringK (FuncState *fs, TString *s) {
- - TValue o;
- + TValue o = tvinit();
- setsvalue(fs->L, &o, s);
- + luaV_unref(fs->L, &o);
- return addk(fs, &o, &o);
- }
-
-
- int luaK_numberK (FuncState *fs, lua_Number r) {
- - TValue o;
- + lua_State *L = fs->L;
- + TValue o = tvinit();
- setnvalue(&o, r);
- return addk(fs, &o, &o);
- }
-
-
- int luaK_integerK (FuncState *fs, lua_Integer r) {
- - TValue o;
- + lua_State *L = fs->L;
- + TValue o = tvinit();
- setivalue(&o, r);
- return addk(fs, &o, &o);
- }
- @@ -279,22 +283,24 @@ int luaK_integerK (FuncState *fs, lua_In
-
- #ifdef LNUM_COMPLEX
- static int luaK_imagK (FuncState *fs, lua_Number r) {
- - TValue o;
- + lua_State *L = fs->L;
- + TValue o = tvinit();
- setnvalue_complex(&o, r*I);
- return addk(fs, &o, &o);
- }
- #endif
-
- static int boolK (FuncState *fs, int b) {
- - TValue o;
- + lua_State *L = fs->L;
- + TValue o = tvinit();
- setbvalue(&o, b);
- return addk(fs, &o, &o);
- }
-
-
- static int nilK (FuncState *fs) {
- - TValue k, v;
- - setnilvalue(&v);
- + TValue k = tvinit(), v = tvinit();
- + setnilvalue(fs->L, &v);
- /* cannot use nil as key; instead use table itself to represent nil */
- sethvalue(fs->L, &k, fs->h);
- return addk(fs, &k, &v);
- --- a/src/ldebug.c
- +++ b/src/ldebug.c
- @@ -142,6 +142,7 @@ LUA_API const char *lua_setlocal (lua_St
- if (name)
- setobjs2s(L, ci->base + (n - 1), L->top - 1);
- L->top--; /* pop value */
- + setnilvalue(L, L->top);
- lua_unlock(L);
- return name;
- }
- @@ -176,7 +177,7 @@ static void info_tailcall (lua_Debug *ar
-
- static void collectvalidlines (lua_State *L, Closure *f) {
- if (f == NULL || f->c.isC) {
- - setnilvalue(L->top);
- + setnilvalue(L, L->top);
- }
- else {
- Table *t = luaH_new(L, 0, 0);
- @@ -248,7 +249,7 @@ LUA_API int lua_getinfo (lua_State *L, c
- }
- status = auxgetinfo(L, what, ar, f, ci);
- if (strchr(what, 'f')) {
- - if (f == NULL) setnilvalue(L->top);
- + if (f == NULL) setnilvalue(L, L->top);
- else setclvalue(L, L->top, f);
- incr_top(L);
- }
- @@ -586,7 +587,7 @@ void luaG_concaterror (lua_State *L, Stk
-
-
- void luaG_aritherror (lua_State *L, const TValue *p1, const TValue *p2) {
- - TValue temp;
- + TValue temp = tvinit();
- if (luaV_tonumber(p1, &temp) == NULL)
- p2 = p1; /* first operand is wrong */
- luaG_typeerror(L, p2, "perform arithmetic on");
- --- a/src/ldo.c
- +++ b/src/ldo.c
- @@ -211,7 +211,7 @@ static StkId adjust_varargs (lua_State *
- Table *htab = NULL;
- StkId base, fixed;
- for (; actual < nfixargs; ++actual)
- - setnilvalue(L->top++);
- + setnilvalue(L, L->top++);
- #if defined(LUA_COMPAT_VARARG)
- if (p->is_vararg & VARARG_NEEDSARG) { /* compat. with old-style vararg? */
- int nvar = actual - nfixargs; /* number of extra arguments */
- @@ -229,7 +229,7 @@ static StkId adjust_varargs (lua_State *
- base = L->top; /* final position of first argument */
- for (i=0; i<nfixargs; i++) {
- setobjs2s(L, L->top++, fixed+i);
- - setnilvalue(fixed+i);
- + setnilvalue(L, fixed+i);
- }
- /* add `arg' parameter */
- if (htab) {
- @@ -294,7 +294,7 @@ int luaD_precall (lua_State *L, StkId fu
- ci->tailcalls = 0;
- ci->nresults = nresults;
- for (st = L->top; st < ci->top; st++)
- - setnilvalue(st);
- + setnilvalue(L, st);
- L->top = ci->top;
- if (L->hookmask & LUA_MASKCALL) {
- L->savedpc++; /* hooks assume 'pc' is already incremented */
- @@ -354,8 +354,8 @@ int luaD_poscall (lua_State *L, StkId fi
- for (i = wanted; i != 0 && firstResult < L->top; i--)
- setobjs2s(L, res++, firstResult++);
- while (i-- > 0)
- - setnilvalue(res++);
- - L->top = res;
- + setnilvalue(L, res++);
- + setlvmtop(L, res);
- return (wanted - LUA_MULTRET); /* 0 iff wanted == LUA_MULTRET */
- }
-
- @@ -463,8 +463,12 @@ int luaD_pcall (lua_State *L, Pfunc func
- status = luaD_rawrunprotected(L, func, u);
- if (status != 0) { /* an error occurred? */
- StkId oldtop = restorestack(L, old_top);
- + StkId curtop = L->top;
- + int i;
- luaF_close(L, oldtop); /* close eventual pending closures */
- luaD_seterrorobj(L, status, oldtop);
- + for (i = (curtop - L->top); i-- > 0;)
- + setnilvalue(L, L->top + i);
- L->nCcalls = oldnCcalls;
- L->ci = restoreci(L, old_ci);
- L->base = L->ci->base;
- --- a/src/lfunc.c
- +++ b/src/lfunc.c
- @@ -17,7 +17,7 @@
- #include "lmem.h"
- #include "lobject.h"
- #include "lstate.h"
- -
- +#include "lvm.h"
-
-
- Closure *luaF_newCclosure (lua_State *L, int nelems, Table *e) {
- @@ -45,7 +45,7 @@ UpVal *luaF_newupval (lua_State *L) {
- UpVal *uv = luaM_new(L, UpVal);
- luaC_link(L, obj2gco(uv), LUA_TUPVAL);
- uv->v = &uv->u.value;
- - setnilvalue(uv->v);
- + setnilvalue(L, uv->v);
- return uv;
- }
-
- @@ -67,8 +67,14 @@ UpVal *luaF_findupval (lua_State *L, Stk
- uv = luaM_new(L, UpVal); /* not found: create a new one */
- uv->tt = LUA_TUPVAL;
- uv->marked = luaC_white(g);
- - uv->v = level; /* current value lives in the stack */
- + uv->v = luaV_ref(level); /* current value lives in the stack */
- uv->next = *pp; /* chain it in the proper position */
- + if (uv->next) {
- + uv->prev = uv->next->gch.prev;
- + uv->next->gch.prev = (GCObject *)uv;
- + } else {
- + uv->prev = NULL;
- + }
- *pp = obj2gco(uv);
- uv->u.l.prev = &g->uvhead; /* double link it in `uvhead' list */
- uv->u.l.next = g->uvhead.u.l.next;
- --- a/src/lgc.c
- +++ b/src/lgc.c
- @@ -21,6 +21,7 @@
- #include "lstring.h"
- #include "ltable.h"
- #include "ltm.h"
- +#include "lvm.h"
-
-
- #define GCSTEPSIZE 1024u
- @@ -265,7 +266,7 @@ static void traversestack (global_State
- for (o = l->stack; o < l->top; o++)
- markvalue(g, o);
- for (; o <= lim; o++)
- - setnilvalue(o);
- + setnilvalue(l, o);
- checkstacksizes(l, lim);
- }
-
- @@ -348,7 +349,7 @@ static int iscleared (const TValue *o, i
- /*
- ** clear collected entries from weaktables
- */
- -static void cleartable (GCObject *l) {
- +static void cleartable (lua_State *L, GCObject *l) {
- while (l) {
- Table *h = gco2h(l);
- int i = h->sizearray;
- @@ -358,7 +359,7 @@ static void cleartable (GCObject *l) {
- while (i--) {
- TValue *o = &h->array[i];
- if (iscleared(o, 0)) /* value was collected? */
- - setnilvalue(o); /* remove value */
- + setnilvalue(L, o); /* remove value */
- }
- }
- i = sizenode(h);
- @@ -366,7 +367,7 @@ static void cleartable (GCObject *l) {
- Node *n = gnode(h, i);
- if (!ttisnil(gval(n)) && /* non-empty entry? */
- (iscleared(key2tval(n), 1) || iscleared(gval(n), 0))) {
- - setnilvalue(gval(n)); /* remove value ... */
- + setnilvalue(L, gval(n)); /* remove value ... */
- removeentry(n); /* remove entry from table */
- }
- }
- @@ -375,7 +376,7 @@ static void cleartable (GCObject *l) {
- }
-
-
- -static void freeobj (lua_State *L, GCObject *o) {
- +void luaC_freeobj (lua_State *L, GCObject *o) {
- switch (o->gch.tt) {
- case LUA_TPROTO: luaF_freeproto(L, gco2p(o)); break;
- case LUA_TFUNCTION: luaF_freeclosure(L, gco2cl(o)); break;
- @@ -418,10 +419,12 @@ static GCObject **sweeplist (lua_State *
- }
- else { /* must erase `curr' */
- lua_assert(isdead(g, curr) || deadmask == bitmask(SFIXEDBIT));
- + if (curr->gch.next)
- + curr->gch.next->gch.prev = curr->gch.prev;
- *p = curr->gch.next;
- if (curr == g->rootgc) /* is the first element of the list? */
- g->rootgc = curr->gch.next; /* adjust first */
- - freeobj(L, curr);
- + luaC_freeobj(L, curr);
- }
- }
- return p;
- @@ -543,7 +546,7 @@ static void atomic (lua_State *L) {
- udsize = luaC_separateudata(L, 0); /* separate userdata to be finalized */
- marktmu(g); /* mark `preserved' userdata */
- udsize += propagateall(g); /* remark, to propagate `preserveness' */
- - cleartable(g->weak); /* remove collected objects from weak tables */
- + cleartable(L, g->weak); /* remove collected objects from weak tables */
- /* flip current white */
- g->currentwhite = cast_byte(otherwhite(g));
- g->sweepstrgc = 0;
- @@ -685,8 +688,11 @@ void luaC_barrierback (lua_State *L, Tab
-
- void luaC_link (lua_State *L, GCObject *o, lu_byte tt) {
- global_State *g = G(L);
- + o->gch.prev = (GCObject*)&g->rootgc;
- o->gch.next = g->rootgc;
- g->rootgc = o;
- + if (o->gch.next)
- + o->gch.next->gch.prev = o;
- o->gch.marked = luaC_white(g);
- o->gch.tt = tt;
- }
- --- a/src/lgc.h
- +++ b/src/lgc.h
- @@ -105,6 +105,6 @@ LUAI_FUNC void luaC_link (lua_State *L,
- LUAI_FUNC void luaC_linkupval (lua_State *L, UpVal *uv);
- LUAI_FUNC void luaC_barrierf (lua_State *L, GCObject *o, GCObject *v);
- LUAI_FUNC void luaC_barrierback (lua_State *L, Table *t);
- -
- +LUAI_FUNC void luaC_freeobj (lua_State *L, GCObject *o);
-
- #endif
- --- a/src/lmem.c
- +++ b/src/lmem.c
- @@ -6,6 +6,7 @@
-
-
- #include <stddef.h>
- +#include <string.h>
-
- #define lmem_c
- #define LUA_CORE
- @@ -80,6 +81,8 @@ void *luaM_realloc_ (lua_State *L, void
- if (block == NULL && nsize > 0)
- luaD_throw(L, LUA_ERRMEM);
- lua_assert((nsize == 0) == (block == NULL));
- + if (nsize > osize)
- + memset((char *)block + osize, 0, nsize - osize);
- g->totalbytes = (g->totalbytes - osize) + nsize;
- return block;
- }
- --- a/src/lobject.h
- +++ b/src/lobject.h
- @@ -44,7 +44,7 @@ typedef union GCObject GCObject;
- ** Common Header for all collectable objects (in macro form, to be
- ** included in other objects)
- */
- -#define CommonHeader GCObject *next; lu_byte tt; lu_byte marked
- +#define CommonHeader GCObject *next; GCObject *prev; lu_byte tt; lu_byte marked
-
-
- /*
- @@ -83,6 +83,7 @@ typedef struct lua_TValue {
- TValuefields;
- } TValue;
-
- +#define tvinit() { .value.b = 0, .tt = 0 }
-
- /* Macros to test type */
- #define ttisnil(o) (ttype(o) == LUA_TNIL)
- @@ -145,15 +146,15 @@ typedef struct lua_TValue {
-
-
- /* Macros to set values */
- -#define setnilvalue(obj) ((obj)->tt=LUA_TNIL)
- +#define setnilvalue(L, obj) (luaV_unref(L, (obj))->tt=LUA_TNIL)
-
- /* Must not have side effects, 'x' may be expression.
- */
- #define setivalue(obj,x) \
- - { TValue *i_o=(obj); i_o->value.i=(x); i_o->tt=LUA_TINT; }
- + { TValue *i_o=luaV_unref(L, (obj)); i_o->value.i=(x); i_o->tt=LUA_TINT; }
-
- # define setnvalue(obj,x) \
- - { TValue *i_o=(obj); i_o->value.n= (x); i_o->tt=LUA_TNUMBER; }
- + { TValue *i_o=luaV_unref(L, (obj)); i_o->value.n= (x); i_o->tt=LUA_TNUMBER; }
-
- /* Note: Complex always has "inline", both are C99.
- */
- @@ -170,45 +171,45 @@ typedef struct lua_TValue {
-
-
- #define setpvalue(obj,x) \
- - { TValue *i_o=(obj); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
- + { TValue *i_o=luaV_unref(L, (obj)); i_o->value.p=(x); i_o->tt=LUA_TLIGHTUSERDATA; }
-
- #define setbvalue(obj,x) \
- - { TValue *i_o=(obj); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; }
- + { TValue *i_o=luaV_unref(L, (obj)); i_o->value.b=(x); i_o->tt=LUA_TBOOLEAN; }
-
- #define setsvalue(L,obj,x) \
- - { TValue *i_o=(obj); \
- - i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TSTRING; \
- + { TValue *i_o=(obj); TString *val=(x); luaS_ref(val); luaV_unref(L, obj); \
- + i_o->value.gc=cast(GCObject *, (val)); i_o->tt=LUA_TSTRING; \
- checkliveness(G(L),i_o); }
-
- #define setuvalue(L,obj,x) \
- - { TValue *i_o=(obj); \
- + { TValue *i_o=luaV_unref(L, (obj)); \
- i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TUSERDATA; \
- checkliveness(G(L),i_o); }
-
- #define setthvalue(L,obj,x) \
- - { TValue *i_o=(obj); \
- + { TValue *i_o=luaV_unref(L, (obj)); \
- i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTHREAD; \
- checkliveness(G(L),i_o); }
-
- #define setclvalue(L,obj,x) \
- - { TValue *i_o=(obj); \
- + { TValue *i_o=luaV_unref(L, (obj)); \
- i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TFUNCTION; \
- checkliveness(G(L),i_o); }
-
- #define sethvalue(L,obj,x) \
- - { TValue *i_o=(obj); \
- + { TValue *i_o=luaV_unref(L, (obj)); \
- i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TTABLE; \
- checkliveness(G(L),i_o); }
-
- #define setptvalue(L,obj,x) \
- - { TValue *i_o=(obj); \
- + { TValue *i_o=luaV_unref(L, (obj)); \
- i_o->value.gc=cast(GCObject *, (x)); i_o->tt=LUA_TPROTO; \
- checkliveness(G(L),i_o); }
-
- #define setobj(L,obj1,obj2) \
- - { const TValue *o2=(obj2); TValue *o1=(obj1); \
- + do { const TValue *o2=luaV_ref((TValue *)(obj2)); TValue *o1=luaV_unref(L, (obj1)); \
- o1->value = o2->value; o1->tt=o2->tt; \
- - checkliveness(G(L),o1); }
- + checkliveness(G(L),o1); } while(0)
-
-
- /*
- @@ -253,6 +254,7 @@ typedef union TString {
- lu_byte reserved;
- unsigned int hash;
- size_t len;
- + int refcount;
- } tsv;
- } TString;
-
- @@ -409,6 +411,7 @@ typedef struct Table {
- #define twoto(x) (1<<(x))
- #define sizenode(t) (twoto((t)->lsizenode))
-
- +#include "lstring.h"
-
- #define luaO_nilobject (&luaO_nilobject_)
-
- --- a/src/lparser.c
- +++ b/src/lparser.c
- @@ -24,6 +24,7 @@
- #include "lstate.h"
- #include "lstring.h"
- #include "ltable.h"
- +#include "lvm.h"
-
-
-
- @@ -146,7 +147,7 @@ static int registerlocalvar (LexState *l
- luaM_growvector(ls->L, f->locvars, fs->nlocvars, f->sizelocvars,
- LocVar, SHRT_MAX, "too many local variables");
- while (oldsize < f->sizelocvars) f->locvars[oldsize++].varname = NULL;
- - f->locvars[fs->nlocvars].varname = varname;
- + f->locvars[fs->nlocvars].varname = luaS_ref(varname);
- luaC_objbarrier(ls->L, f, varname);
- return fs->nlocvars++;
- }
- @@ -194,7 +195,7 @@ static int indexupvalue (FuncState *fs,
- luaM_growvector(fs->L, f->upvalues, f->nups, f->sizeupvalues,
- TString *, MAX_INT, "");
- while (oldsize < f->sizeupvalues) f->upvalues[oldsize++] = NULL;
- - f->upvalues[f->nups] = name;
- + f->upvalues[f->nups] = luaS_ref(name);
- luaC_objbarrier(fs->L, f, name);
- lua_assert(v->k == VLOCAL || v->k == VUPVAL);
- fs->upvalues[f->nups].k = cast_byte(v->k);
- @@ -341,7 +342,7 @@ static void open_func (LexState *ls, Fun
- fs->nlocvars = 0;
- fs->nactvar = 0;
- fs->bl = NULL;
- - f->source = ls->source;
- + f->source = luaS_ref(ls->source);
- f->maxstacksize = 2; /* registers 0/1 are always valid */
- fs->h = luaH_new(L, 0, 0);
- /* anchor table of constants and prototype (to avoid being collected) */
- --- a/src/lstate.c
- +++ b/src/lstate.c
- @@ -22,6 +22,7 @@
- #include "lstring.h"
- #include "ltable.h"
- #include "ltm.h"
- +#include "lvm.h"
-
-
- #define state_size(x) (sizeof(x) + LUAI_EXTRASPACE)
- @@ -52,7 +53,7 @@ static void stack_init (lua_State *L1, l
- L1->stack_last = L1->stack+(L1->stacksize - EXTRA_STACK)-1;
- /* initialize first ci */
- L1->ci->func = L1->top;
- - setnilvalue(L1->top++); /* `function' entry for this `ci' */
- + setnilvalue(L1, L1->top++); /* `function' entry for this `ci' */
- L1->base = L1->ci->base = L1->top;
- L1->ci->top = L1->top + LUA_MINSTACK;
- }
- @@ -98,7 +99,7 @@ static void preinit_state (lua_State *L,
- L->base_ci = L->ci = NULL;
- L->savedpc = NULL;
- L->errfunc = 0;
- - setnilvalue(gt(L));
- + setnilvalue(L, gt(L));
- }
-
-
- @@ -163,7 +164,7 @@ LUA_API lua_State *lua_newstate (lua_All
- g->strt.size = 0;
- g->strt.nuse = 0;
- g->strt.hash = NULL;
- - setnilvalue(registry(L));
- + setnilvalue(L, registry(L));
- luaZ_initbuffer(L, &g->buff);
- g->panic = NULL;
- g->gcstate = GCSpause;
- --- a/src/lstring.c
- +++ b/src/lstring.c
- @@ -37,6 +37,9 @@ void luaS_resize (lua_State *L, int news
- int h1 = lmod(h, newsize); /* new position */
- lua_assert(cast_int(h%newsize) == lmod(h, newsize));
- p->gch.next = newhash[h1]; /* chain it */
- + if (p->gch.next)
- + p->gch.next->gch.prev = p;
- + p->gch.prev = NULL;
- newhash[h1] = p;
- p = next;
- }
- @@ -59,11 +62,15 @@ static TString *newlstr (lua_State *L, c
- ts->tsv.marked = luaC_white(G(L));
- ts->tsv.tt = LUA_TSTRING;
- ts->tsv.reserved = 0;
- + ts->tsv.refcount = 0;
- memcpy(ts+1, str, l*sizeof(char));
- ((char *)(ts+1))[l] = '\0'; /* ending 0 */
- tb = &G(L)->strt;
- h = lmod(h, tb->size);
- ts->tsv.next = tb->hash[h]; /* chain new entry */
- + if (ts->tsv.next)
- + ts->tsv.next->gch.prev = (GCObject *)ts;
- + ts->tsv.prev = NULL;
- tb->hash[h] = obj2gco(ts);
- tb->nuse++;
- if (tb->nuse > cast(lu_int32, tb->size) && tb->size <= MAX_INT/2)
- @@ -109,3 +116,29 @@ Udata *luaS_newudata (lua_State *L, size
- return u;
- }
-
- +void luaS_unref(lua_State *L, TString *ts) {
- + if (!L || !ts)
- + return;
- + if (testbit(ts->tsv.marked, FIXEDBIT))
- + return;
- + ts->tsv.refcount--;
- + if (ts->tsv.refcount < 0) {
- + fprintf(stderr, "REFCOUNT BUG, COUNT=%d, str=%s, len=%d\n", ts->tsv.refcount, (char *) (ts + 1), (int) ts->tsv.len);
- + } else if (ts->tsv.refcount)
- + return;
- +
- + if (ts->tsv.prev) {
- + ts->tsv.prev->gch.next = ts->tsv.next;
- + } else {
- + unsigned int idx = lmod(ts->tsv.hash, G(L)->strt.size);
- + lua_assert(G(L)->strt.hash[index] == (GCObject*)ts);
- + G(L)->strt.hash[idx] = ts->tsv.next;
- + }
- +
- + if (ts->tsv.next)
- + ts->tsv.next->gch.prev = ts->tsv.prev;
- +
- + luaC_freeobj(L, (GCObject *) ts);
- +}
- +
- +
- --- a/src/lstring.h
- +++ b/src/lstring.h
- @@ -7,7 +7,7 @@
- #ifndef lstring_h
- #define lstring_h
-
- -
- +#include <stdio.h>
- #include "lgc.h"
- #include "lobject.h"
- #include "lstate.h"
- @@ -23,6 +23,12 @@
-
- #define luaS_fix(s) l_setbit((s)->tsv.marked, FIXEDBIT)
-
- +static inline TString *luaS_ref(TString *ts) {
- + ts->tsv.refcount++;
- + return ts;
- +}
- +
- +LUA_API void luaS_unref(lua_State *L, TString *ts);
- LUAI_FUNC void luaS_resize (lua_State *L, int newsize);
- LUAI_FUNC Udata *luaS_newudata (lua_State *L, size_t s, Table *e);
- LUA_API TString *luaS_newlstr (lua_State *L, const char *str, size_t l);
- --- a/src/ltable.c
- +++ b/src/ltable.c
- @@ -34,6 +34,7 @@
- #include "lstate.h"
- #include "ltable.h"
- #include "lnum.h"
- +#include "lvm.h"
-
-
- /*
- @@ -278,7 +279,7 @@ static void setarrayvector (lua_State *L
- int i;
- luaM_reallocvector(L, t->array, t->sizearray, size, TValue);
- for (i=t->sizearray; i<size; i++)
- - setnilvalue(&t->array[i]);
- + setnilvalue(L, &t->array[i]);
- t->sizearray = size;
- }
-
- @@ -299,8 +300,8 @@ static void setnodevector (lua_State *L,
- for (i=0; i<size; i++) {
- Node *n = gnode(t, i);
- gnext(n) = NULL;
- - setnilvalue(gkey(n));
- - setnilvalue(gval(n));
- + setnilvalue(L, gkey(n));
- + setnilvalue(L, gval(n));
- }
- }
- t->lsizenode = cast_byte(lsize);
- @@ -427,9 +428,11 @@ static TValue *newkey (lua_State *L, Tab
- othern = gnext(othern); /* find previous */
- }
- gnext(othern) = n; /* redo the chain with `n' in place of `mp' */
- + luaV_ref((TValue *) gkey(mp));
- + luaV_ref(gval(mp));
- *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */
- gnext(mp) = NULL; /* now `mp' is free */
- - setnilvalue(gval(mp));
- + setnilvalue(L, gval(mp));
- }
- else { /* colliding node is in its own main position */
- /* new node will go into free position */
- @@ -438,6 +441,7 @@ static TValue *newkey (lua_State *L, Tab
- mp = n;
- }
- }
- + luaV_ref((TValue *) key);
- gkey(mp)->value = key->value; gkey(mp)->tt = key->tt;
- luaC_barriert(L, t, key);
- lua_assert(ttisnil(gval(mp)));
- @@ -530,7 +534,7 @@ TValue *luaH_setint (lua_State *L, Table
- if (p != luaO_nilobject)
- return cast(TValue *, p);
- else {
- - TValue k;
- + TValue k = tvinit();
- setivalue(&k, key);
- return newkey(L, t, &k);
- }
- @@ -542,7 +546,7 @@ TValue *luaH_setstr (lua_State *L, Table
- if (p != luaO_nilobject)
- return cast(TValue *, p);
- else {
- - TValue k;
- + TValue k = tvinit();
- setsvalue(L, &k, key);
- return newkey(L, t, &k);
- }
- --- a/src/luac.c
- +++ b/src/luac.c
- @@ -20,8 +20,9 @@
- #include "lmem.h"
- #include "lobject.h"
- #include "lopcodes.h"
- -#include "lstring.h"
- #include "lundump.h"
- +#include "lvm.h"
- +#include "lstring.h"
-
- #define PROGNAME "luac" /* default program name */
- #define OUTPUT PROGNAME ".out" /* default output file */
- --- a/src/lundump.c
- +++ b/src/lundump.c
- @@ -19,6 +19,7 @@
- #include "lstring.h"
- #include "lundump.h"
- #include "lzio.h"
- +#include "lvm.h"
-
- typedef struct {
- lua_State* L;
- @@ -133,7 +134,7 @@ static TString* LoadString(LoadState* S)
- {
- char* s=luaZ_openspace(S->L,S->b,size);
- LoadBlock(S,s,size);
- - return luaS_newlstr(S->L,s,size-1); /* remove trailing '\0' */
- + return luaS_ref(luaS_newlstr(S->L,s,size-1)); /* remove trailing '\0' */
- }
- }
-
- @@ -149,11 +150,12 @@ static Proto* LoadFunction(LoadState* S,
-
- static void LoadConstants(LoadState* S, Proto* f)
- {
- + lua_State *L = S->L;
- int i,n;
- n=LoadInt(S);
- f->k=luaM_newvector(S->L,n,TValue);
- f->sizek=n;
- - for (i=0; i<n; i++) setnilvalue(&f->k[i]);
- + for (i=0; i<n; i++) setnilvalue(L, &f->k[i]);
- for (i=0; i<n; i++)
- {
- TValue* o=&f->k[i];
- @@ -161,7 +163,7 @@ static void LoadConstants(LoadState* S,
- switch (t)
- {
- case LUA_TNIL:
- - setnilvalue(o);
- + setnilvalue(L, o);
- break;
- case LUA_TBOOLEAN:
- setbvalue(o,LoadChar(S)!=0);
- @@ -229,6 +231,7 @@ static Proto* LoadFunction(LoadState* S,
- LoadDebug(S,f);
- IF (!luaG_checkcode(f), "bad code");
- S->L->top--;
- + setnilvalue(S->L, S->L->top);
- S->L->nCcalls--;
- return f;
- }
- --- a/src/lvm.c
- +++ b/src/lvm.c
- @@ -39,6 +39,7 @@
- * If 'obj' is a string, it is tried to be interpreted as a number.
- */
- const TValue *luaV_tonumber ( const TValue *obj, TValue *n) {
- + lua_State *L = NULL; /* FIXME */
- lua_Number d;
- lua_Integer i;
-
- @@ -384,6 +385,7 @@ void luaV_concat (lua_State *L, int tota
- size_t l = tsvalue(top-i)->len;
- memcpy(buffer+tl, svalue(top-i), l);
- tl += l;
- + setnilvalue(L, top - i);
- }
- setsvalue2s(L, top-n, luaS_newlstr(L, buffer, tl));
- }
- @@ -420,7 +422,7 @@ void luaV_concat (lua_State *L, int tota
- */
- static void Arith (lua_State *L, StkId ra, const TValue *rb,
- const TValue *rc, TMS op) {
- - TValue tempb, tempc;
- + TValue tempb = tvinit(), tempc = tvinit();
- const TValue *b, *c;
- lua_Number nb,nc;
-
- @@ -663,7 +665,7 @@ void luaV_execute (lua_State *L, int nex
- OPCODE_TARGET(LOADNIL) {
- TValue *rb = RB(i);
- do {
- - setnilvalue(rb--);
- + setnilvalue(L, rb--);
- } while (rb >= ra);
- continue;
- }
- @@ -673,7 +675,7 @@ void luaV_execute (lua_State *L, int nex
- continue;
- }
- OPCODE_TARGET(GETGLOBAL) {
- - TValue g;
- + TValue g = tvinit();
- TValue *rb = KBx(i);
- sethvalue(L, &g, cl->env);
- lua_assert(ttisstring(rb));
- @@ -685,7 +687,7 @@ void luaV_execute (lua_State *L, int nex
- continue;
- }
- OPCODE_TARGET(SETGLOBAL) {
- - TValue g;
- + TValue g = tvinit();
- sethvalue(L, &g, cl->env);
- lua_assert(ttisstring(KBx(i)));
- Protect(luaV_settable(L, &g, KBx(i), ra));
- @@ -895,7 +897,7 @@ void luaV_execute (lua_State *L, int nex
- if (--nexeccalls == 0) /* was previous function running `here'? */
- return; /* no: return */
- else { /* yes: continue its execution */
- - if (b) L->top = L->ci->top;
- + if (b) setlvmtop(L, L->ci->top);
- lua_assert(isLua(L->ci));
- lua_assert(GET_OPCODE(*((L->ci)->savedpc - 1)) == OP_CALL);
- goto reentry;
- @@ -986,6 +988,7 @@ void luaV_execute (lua_State *L, int nex
- for (; n > 0; n--) {
- TValue *val = ra+n;
- setobj2t(L, luaH_setint(L, h, last--), val);
- + setnilvalue(L, val);
- luaC_barriert(L, h, val);
- }
- continue;
- @@ -1030,7 +1033,7 @@ void luaV_execute (lua_State *L, int nex
- setobjs2s(L, ra + j, ci->base - n + j);
- }
- else {
- - setnilvalue(ra + j);
- + setnilvalue(L, ra + j);
- }
- }
- continue;
- --- a/src/lvm.h
- +++ b/src/lvm.h
- @@ -11,6 +11,7 @@
- #include "ldo.h"
- #include "lobject.h"
- #include "ltm.h"
- +#include "lstring.h"
-
-
- #define tostring(L,o) ((ttype(o) == LUA_TSTRING) || (luaV_tostring(L, o)))
- @@ -19,6 +20,19 @@
-
- #define equalobj(L,o1,o2) (ttype_ext_same(o1,o2) && luaV_equalval(L, o1, o2))
-
- +static inline TValue *luaV_ref(TValue *tv)
- +{
- + if (ttisstring(tv))
- + luaS_ref(rawtsvalue(tv));
- + return tv;
- +}
- +
- +static inline TValue *luaV_unref(lua_State *L, TValue *tv)
- +{
- + if (ttisstring(tv))
- + luaS_unref(L, rawtsvalue(tv));
- + return tv;
- +}
-
- LUAI_FUNC int luaV_lessthan (lua_State *L, const TValue *l, const TValue *r);
- LUAI_FUNC int luaV_equalval (lua_State *L, const TValue *t1, const TValue *t2);
- --- a/src/llex.c
- +++ b/src/llex.c
- @@ -23,6 +23,7 @@
- #include "ltable.h"
- #include "lzio.h"
- #include "lnum.h"
- +#include "lvm.h"
-
-
-
- @@ -69,7 +70,7 @@ static void save (LexState *ls, int c) {
- void luaX_init (lua_State *L) {
- int i;
- for (i=0; i<NUM_RESERVED; i++) {
- - TString *ts = luaS_new(L, luaX_tokens[i]);
- + TString *ts = luaS_ref(luaS_new(L, luaX_tokens[i]));
- luaS_fix(ts); /* reserved words are never collected */
- lua_assert(strlen(luaX_tokens[i])+1 <= TOKEN_LEN);
- ts->tsv.reserved = cast_byte(i+1); /* reserved word */
- @@ -125,7 +126,7 @@ void luaX_syntaxerror (LexState *ls, con
-
- TString *luaX_newstring (LexState *ls, const char *str, size_t l) {
- lua_State *L = ls->L;
- - TString *ts = luaS_newlstr(L, str, l);
- + TString *ts = luaS_ref(luaS_newlstr(L, str, l));
- TValue *o = luaH_setstr(L, ls->fs->h, ts); /* entry for `str' */
- if (ttisnil(o))
- setbvalue(o, 1); /* make sure `str' will not be collected */
- @@ -152,7 +153,7 @@ void luaX_setinput (lua_State *L, LexSta
- ls->fs = NULL;
- ls->linenumber = 1;
- ls->lastline = 1;
- - ls->source = source;
- + ls->source = luaS_ref(source);
- luaZ_resizebuffer(ls->L, ls->buff, LUA_MINBUFFER); /* initialize buffer */
- next(ls); /* read first char */
- }
- --- a/src/lstate.h
- +++ b/src/lstate.h
- @@ -144,6 +144,13 @@ union GCObject {
- struct lua_State th; /* thread */
- };
-
- +#define setlvmtop(L, val) do { \
- + int __i; \
- + for (__i = L->top - val; __i-- > 0;) \
- + setnilvalue(L, val + __i); \
- + L->top = val; \
- +} while (0)
- +
-
- /* macros to convert a GCObject into a specific value */
- #define rawgco2ts(o) check_exp((o)->gch.tt == LUA_TSTRING, &((o)->ts))
|