diff --git a/lapi.c b/lapi.c index 5421cdf4..9ad290f7 100644 --- a/lapi.c +++ b/lapi.c @@ -1,5 +1,5 @@ /* -** $Id: lapi.c,v 1.191 2002/05/15 18:57:44 roberto Exp roberto $ +** $Id: lapi.c,v 1.192 2002/05/16 18:39:46 roberto Exp roberto $ ** Lua API ** See Copyright Notice in lua.h */ @@ -500,7 +500,7 @@ LUA_API void lua_rawset (lua_State *L, int index) { api_checknelems(L, 2); t = luaA_index(L, index); api_check(L, ttype(t) == LUA_TTABLE); - luaH_set(L, hvalue(t), L->top-2, L->top-1); + setobj(luaH_set(L, hvalue(t), L->top-2), L->top-1); L->top -= 2; lua_unlock(L); } @@ -512,7 +512,7 @@ LUA_API void lua_rawseti (lua_State *L, int index, int n) { api_checknelems(L, 1); o = luaA_index(L, index); api_check(L, ttype(o) == LUA_TTABLE); - luaH_setnum(L, hvalue(o), n, L->top-1); + setobj(luaH_setnum(L, hvalue(o), n), L->top-1); L->top--; lua_unlock(L); } diff --git a/lcode.c b/lcode.c index 8a0ef0d9..2bf050dc 100644 --- a/lcode.c +++ b/lcode.c @@ -1,5 +1,5 @@ /* -** $Id: lcode.c,v 1.103 2002/05/13 13:07:48 roberto Exp roberto $ +** $Id: lcode.c,v 1.104 2002/05/14 17:52:22 roberto Exp roberto $ ** Code generator for Lua ** See Copyright Notice in lua.h */ @@ -211,13 +211,11 @@ static int addk (FuncState *fs, TObject *k, TObject *v) { return cast(int, nvalue(index)); } else { /* constant not found; create a new entry */ - TObject o; Proto *f = fs->f; luaM_growvector(fs->L, f->k, fs->nk, f->sizek, TObject, MAXARG_Bx, "constant table overflow"); setobj(&f->k[fs->nk], v); - setnvalue(&o, fs->nk); - luaH_set(fs->L, fs->h, k, &o); + setnvalue(luaH_set(fs->L, fs->h, k), fs->nk); return fs->nk++; } } diff --git a/ldo.c b/ldo.c index 34914923..c11c5639 100644 --- a/ldo.c +++ b/ldo.c @@ -1,5 +1,5 @@ /* -** $Id: ldo.c,v 1.175 2002/05/15 18:57:44 roberto Exp roberto $ +** $Id: ldo.c,v 1.176 2002/05/16 18:39:46 roberto Exp roberto $ ** Stack and Call structure of Lua ** See Copyright Notice in lua.h */ @@ -171,7 +171,7 @@ static void luaD_callHook (lua_State *L, lua_Hook callhook, const char *event) { static void adjust_varargs (lua_State *L, int nfixargs) { int i; Table *htab; - TObject n, nname; + TObject nname; int actual = L->top - L->ci->base; /* actual number of arguments */ if (actual < nfixargs) { luaD_checkstack(L, nfixargs - actual); @@ -181,11 +181,10 @@ static void adjust_varargs (lua_State *L, int nfixargs) { actual -= nfixargs; /* number of extra arguments */ htab = luaH_new(L, 0, 0); /* create `arg' table */ for (i=0; itop - actual + i); + setobj(luaH_setnum(L, htab, i+1), L->top - actual + i); /* store counter in field `n' */ - setnvalue(&n, actual); setsvalue(&nname, luaS_newliteral(L, "n")); - luaH_set(L, htab, &nname, &n); + setnvalue(luaH_set(L, htab, &nname), actual); L->top -= actual; /* remove extra elements from the stack */ sethvalue(L->top, htab); incr_top(L); diff --git a/ltable.c b/ltable.c index fdd15b66..deb853d6 100644 --- a/ltable.c +++ b/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 1.107 2002/05/13 13:38:59 roberto Exp roberto $ +** $Id: ltable.c,v 1.108 2002/05/15 18:57:44 roberto Exp roberto $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -56,7 +56,7 @@ #define hashboolean(t,p) (node(t, lmod(p, sizenode(t)))) /* -** for pointers, avoid modulus by power of 2, as they tend to have many +** avoid modulus by power of 2 for pointers, as they tend to have many ** 2 factors. */ #define hashpointer(t,p) (node(t, (IntPoint(p) % ((sizenode(t)-1)|1)))) @@ -261,7 +261,7 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) { /* re-insert elements from vanishing slice */ for (i=nasize; iarray[i]) != LUA_TNIL) - luaH_setnum(L, t, i+1, &t->array[i]); + setobj(luaH_setnum(L, t, i+1), &t->array[i]); } /* shrink array */ luaM_reallocvector(L, t->array, oldasize, nasize, TObject); @@ -270,7 +270,7 @@ static void resize (lua_State *L, Table *t, int nasize, int nhsize) { for (i = twoto(oldhsize) - 1; i >= 0; i--) { Node *old = nold+i; if (ttype(val(old)) != LUA_TNIL) - luaH_set(L, t, key(old), val(old)); + setobj(luaH_set(L, t, key(old)), val(old)); } if (oldhsize) luaM_freearray(L, nold, twoto(oldhsize), Node); /* free old array */ @@ -344,8 +344,8 @@ void luaH_remove (Table *t, Node *e) { ** put new key in its main position; otherwise (colliding node is in its main ** position), new key goes to an empty position. */ -static void newkey (lua_State *L, Table *t, const TObject *key, - const TObject *val) { +static TObject *newkey (lua_State *L, Table *t, const TObject *key) { + TObject *val; Node *mp = luaH_mainposition(t, key); if (ttype(val(mp)) != LUA_TNIL) { /* main position is not free? */ Node *othern = luaH_mainposition(t, key(mp)); /* `mp' of colliding node */ @@ -367,14 +367,19 @@ static void newkey (lua_State *L, Table *t, const TObject *key, } setobj(key(mp), key); lua_assert(ttype(val(mp)) == LUA_TNIL); - settableval(val(mp), val); for (;;) { /* correct `firstfree' */ if (ttype(key(t->firstfree)) == LUA_TNIL) - return; /* OK; table still has a free place */ + return val(mp); /* OK; table still has a free place */ else if (t->firstfree == t->node) break; /* cannot decrement from here */ else (t->firstfree)--; } - rehash(L, t); /* no more free places; must create one */ + /* no more free places; must create one */ + setbvalue(val(mp), 0); /* avoid new key being removed */ + rehash(L, t); /* grow table */ + val = cast(TObject *, luaH_get(t, key)); /* get new position */ + lua_assert(ttype(val) == LUA_TBOOLEAN); + setnilvalue(val); + return val; } @@ -444,28 +449,26 @@ const TObject *luaH_get (Table *t, const TObject *key) { } -void luaH_set (lua_State *L, Table *t, const TObject *key, const TObject *val) { +TObject *luaH_set (lua_State *L, Table *t, const TObject *key) { const TObject *p = luaH_get(t, key); - if (p != &luaO_nilobject) { - settableval(p, val); - } + t->flags = 0; + if (p != &luaO_nilobject) + return cast(TObject *, p); else { if (ttype(key) == LUA_TNIL) luaG_runerror(L, "table index is nil"); - newkey(L, t, key, val); + return newkey(L, t, key); } - t->flags = 0; } -void luaH_setnum (lua_State *L, Table *t, int key, const TObject *val) { +TObject *luaH_setnum (lua_State *L, Table *t, int key) { const TObject *p = luaH_getnum(t, key); - if (p != &luaO_nilobject) { - settableval(p, val); - } + if (p != &luaO_nilobject) + return cast(TObject *, p); else { TObject k; setnvalue(&k, key); - newkey(L, t, &k, val); + return newkey(L, t, &k); } } diff --git a/ltable.h b/ltable.h index c42f1059..54fba106 100644 --- a/ltable.h +++ b/ltable.h @@ -1,5 +1,5 @@ /* -** $Id: ltable.h,v 1.40 2002/02/14 21:41:08 roberto Exp roberto $ +** $Id: ltable.h,v 1.41 2002/03/11 12:45:00 roberto Exp roberto $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -14,14 +14,12 @@ #define key(n) (&(n)->i_key) #define val(n) (&(n)->i_val) -#define settableval(p,v) setobj(cast(TObject *, p), v) - const TObject *luaH_getnum (Table *t, int key); -void luaH_setnum (lua_State *L, Table *t, int key, const TObject *val); +TObject *luaH_setnum (lua_State *L, Table *t, int key); const TObject *luaH_getstr (Table *t, TString *key); const TObject *luaH_get (Table *t, const TObject *key); -void luaH_set (lua_State *L, Table *t, const TObject *key, const TObject *val); +TObject *luaH_set (lua_State *L, Table *t, const TObject *key); Table *luaH_new (lua_State *L, int narray, int lnhash); void luaH_free (lua_State *L, Table *t); int luaH_next (lua_State *L, Table *t, TObject *key); diff --git a/ltm.c b/ltm.c index aaba8943..7b7b64a2 100644 --- a/ltm.c +++ b/ltm.c @@ -1,5 +1,5 @@ /* -** $Id: ltm.c,v 1.90 2002/04/30 13:01:48 roberto Exp roberto $ +** $Id: ltm.c,v 1.91 2002/05/20 19:51:06 roberto Exp roberto $ ** Tag methods ** See Copyright Notice in lua.h */ @@ -26,7 +26,7 @@ const char *const luaT_typenames[] = { void luaT_init (lua_State *L) { static const char *const luaT_eventname[] = { /* ORDER TM */ - "__gettable", "__settable", "__index", + "__gettable", "__settable", "__index", "__newindex", "__gc", "__weakmode", "__add", "__sub", "__mul", "__div", "__pow", "__unm", "__lt", "__concat", diff --git a/ltm.h b/ltm.h index ab6c375a..e6718492 100644 --- a/ltm.h +++ b/ltm.h @@ -1,5 +1,5 @@ /* -** $Id: ltm.h,v 1.31 2002/01/09 21:50:35 roberto Exp roberto $ +** $Id: ltm.h,v 1.32 2002/05/20 19:51:06 roberto Exp roberto $ ** Tag methods ** See Copyright Notice in lua.h */ @@ -18,6 +18,7 @@ typedef enum { TM_GETTABLE = 0, TM_SETTABLE, TM_INDEX, + TM_NEWINDEX, TM_GC, TM_WEAKMODE, TM_ADD, diff --git a/lvm.c b/lvm.c index c5f3e88d..7815db6c 100644 --- a/lvm.c +++ b/lvm.c @@ -1,5 +1,5 @@ /* -** $Id: lvm.c,v 1.231 2002/05/13 13:09:00 roberto Exp roberto $ +** $Id: lvm.c,v 1.232 2002/05/15 18:57:44 roberto Exp roberto $ ** Lua virtual machine ** See Copyright Notice in lua.h */ @@ -114,13 +114,13 @@ void luaV_gettable (lua_State *L, const TObject *t, TObject *key, StkId res) { int loop = 0; init: if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */ - Table *et = hvalue(t)->metatable; + Table *h = hvalue(t); + Table *et = h->metatable; if ((tm = fasttm(L, et, TM_GETTABLE)) == NULL) { /* no gettable TM? */ - const TObject *h = luaH_get(hvalue(t), key); /* do a primitive get */ - /* result is no nil or there is no `index' tag method? */ - if (ttype(h) != LUA_TNIL || /* no nil? */ - (tm = fasttm(L, et, TM_INDEX)) == NULL) { /* or no index TM? */ - setobj(res, h); /* default get */ + const TObject *v = luaH_get(h, key); /* do a primitive get */ + if (ttype(v) != LUA_TNIL || /* result is no nil ... */ + (tm = fasttm(L, et, TM_INDEX)) == NULL) { /* ... or no index TM? */ + setobj(res, v); /* default get */ return; } } @@ -149,13 +149,18 @@ void luaV_settable (lua_State *L, const TObject *t, TObject *key, StkId val) { int loop = 0; init: if (ttype(t) == LUA_TTABLE) { /* `t' is a table? */ - Table *et = hvalue(t)->metatable; - if ((tm = fasttm(L, et, TM_SETTABLE)) == NULL) { /* no TM? */ - luaH_set(L, hvalue(t), key, val); /* do a primitive set */ - return; + Table *h = hvalue(t); + Table *et = h->metatable; + if ((tm = fasttm(L, et, TM_SETTABLE)) == NULL) { /* no settable TM? */ + TObject *oldval = luaH_set(L, h, key); /* do a primitive set */ + if (ttype(oldval) != LUA_TNIL || /* result is no nil ... */ + (tm = fasttm(L, et, TM_NEWINDEX)) == NULL) { /* ... or no TM? */ + setobj(oldval, val); + return; + } } /* else will try the tag method */ - } else { /* not a table; try a `settable' tag method */ + } else { /* `t' is not a table; try a `settable' tag method */ if (ttype(tm = luaT_gettmbyobj(L, t, TM_SETTABLE)) == LUA_TNIL) { luaG_typeerror(L, t, "index"); return; /* to avoid warnings */ @@ -577,7 +582,7 @@ StkId luaV_execute (lua_State *L) { } bc &= ~(LFIELDS_PER_FLUSH-1); /* bc = bc - bc%FPF */ for (; n > 0; n--) - luaH_setnum(L, h, bc+n, ra+n); + setobj(luaH_setnum(L, h, bc+n), ra+n); break; } case OP_CLOSE: {