commit 46c471d7e97292d923721655683affd7e8b314de
parent 859ecf36b6f96a5a0961f09c00cd98088081384c
Author: Roberto Ierusalimschy <roberto@inf.puc-rio.br>
Date: Mon, 27 May 2002 17:35:18 -0300
new `__newindex' eventfield
Diffstat:
8 files changed, 57 insertions(+), 53 deletions(-)
diff --git 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
@@ -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
@@ -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; i<actual; i++) /* put extra arguments into `arg' table */
- luaH_setnum(L, htab, i+1, L->top - 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
@@ -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; i<oldasize; i++) {
if (ttype(&t->array[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
@@ -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
@@ -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
@@ -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
@@ -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: {