瀏覽代碼

new `__newindex' eventfield

Roberto Ierusalimschy 23 年之前
父節點
當前提交
46c471d7e9
共有 8 個文件被更改,包括 57 次插入53 次删除
  1. 3 3
      lapi.c
  2. 2 4
      lcode.c
  3. 4 5
      ldo.c
  4. 23 20
      ltable.c
  5. 3 5
      ltable.h
  6. 2 2
      ltm.c
  7. 2 1
      ltm.h
  8. 18 13
      lvm.c

+ 3 - 3
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);
 }

+ 2 - 4
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++;
   }
 }

+ 4 - 5
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);

+ 23 - 20
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);
   }
 }
 

+ 3 - 5
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);

+ 2 - 2
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",

+ 2 - 1
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,

+ 18 - 13
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: {