aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-12-04 16:10:22 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2004-12-04 16:10:22 -0200
commit531874f6ce9f47f81294beeeba6cd0c15402411c (patch)
tree9a971f8ac5cb37ba7d09f4aa3a2f3daaecbf7e8b
parent61a888518f01f8cd34fb2246ccb9c1d65d0257e1 (diff)
downloadlua-531874f6ce9f47f81294beeeba6cd0c15402411c.tar.gz
lua-531874f6ce9f47f81294beeeba6cd0c15402411c.tar.bz2
lua-531874f6ce9f47f81294beeeba6cd0c15402411c.zip
better (correct?) way to handle `next' over removed keys
-rw-r--r--lobject.h3
-rw-r--r--ltable.c24
2 files changed, 18 insertions, 9 deletions
diff --git a/lobject.h b/lobject.h
index fb54c3d8..259bdac5 100644
--- a/lobject.h
+++ b/lobject.h
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: lobject.h,v 2.6 2004/10/06 18:34:16 roberto Exp $ 2** $Id: lobject.h,v 2.7 2004/11/01 15:06:50 roberto Exp roberto $
3** Type definitions for Lua objects 3** Type definitions for Lua objects
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -25,6 +25,7 @@
25*/ 25*/
26#define LUA_TPROTO (NUM_TAGS+1) 26#define LUA_TPROTO (NUM_TAGS+1)
27#define LUA_TUPVAL (NUM_TAGS+2) 27#define LUA_TUPVAL (NUM_TAGS+2)
28#define LUA_TDEADKEY (NUM_TAGS+3)
28 29
29 30
30/* 31/*
diff --git a/ltable.c b/ltable.c
index 49f0f572..58d7f001 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 2.10 2004/11/24 19:20:21 roberto Exp roberto $ 2** $Id: ltable.c,v 2.11 2004/12/03 20:50:25 roberto Exp roberto $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -122,7 +122,7 @@ static int arrayindex (const TValue *key) {
122/* 122/*
123** returns the index of a `key' for table traversals. First goes all 123** returns the index of a `key' for table traversals. First goes all
124** elements in the array part, then elements in the hash part. The 124** elements in the array part, then elements in the hash part. The
125** beginning and end of a traversal are signalled by -1. 125** beginning of a traversal is signalled by -1.
126*/ 126*/
127static int findindex (lua_State *L, Table *t, StkId key) { 127static int findindex (lua_State *L, Table *t, StkId key) {
128 int i; 128 int i;
@@ -131,12 +131,20 @@ static int findindex (lua_State *L, Table *t, StkId key) {
131 if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ 131 if (0 < i && i <= t->sizearray) /* is `key' inside array part? */
132 return i-1; /* yes; that's the index (corrected to C) */ 132 return i-1; /* yes; that's the index (corrected to C) */
133 else { 133 else {
134 const TValue *v = luaH_get(t, key); 134 Node *n = luaH_mainposition(t, key);
135 if (v == &luaO_nilobject) 135 do { /* check whether `key' is somewhere in the chain */
136 luaG_runerror(L, "invalid key for `next'"); 136 /* key may be dead already, but it is ok to use it in `next' */
137 i = cast(int, (cast(const lu_byte *, v) - 137 if (luaO_rawequalObj(key2tval(n), key) ||
138 cast(const lu_byte *, gval(gnode(t, 0)))) / sizeof(Node)); 138 (ttype(gkey(n)) == LUA_TDEADKEY && iscollectable(key) &&
139 return i + t->sizearray; /* hash elements are numbered after array ones */ 139 gcvalue(gkey(n)) == gcvalue(key))) {
140 i = n - gnode(t, 0); /* key index in hash table */
141 /* hash elements are numbered after array ones */
142 return i + t->sizearray;
143 }
144 else n = gnext(n);
145 } while (n);
146 luaG_runerror(L, "invalid key for `next'"); /* key not found */
147 return 0; /* to avoid warnings */
140 } 148 }
141} 149}
142 150