diff options
author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-12-04 16:10:22 -0200 |
---|---|---|
committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2004-12-04 16:10:22 -0200 |
commit | 531874f6ce9f47f81294beeeba6cd0c15402411c (patch) | |
tree | 9a971f8ac5cb37ba7d09f4aa3a2f3daaecbf7e8b | |
parent | 61a888518f01f8cd34fb2246ccb9c1d65d0257e1 (diff) | |
download | lua-531874f6ce9f47f81294beeeba6cd0c15402411c.tar.gz lua-531874f6ce9f47f81294beeeba6cd0c15402411c.tar.bz2 lua-531874f6ce9f47f81294beeeba6cd0c15402411c.zip |
better (correct?) way to handle `next' over removed keys
-rw-r--r-- | lobject.h | 3 | ||||
-rw-r--r-- | ltable.c | 24 |
2 files changed, 18 insertions, 9 deletions
@@ -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 | /* |
@@ -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 | */ |
127 | static int findindex (lua_State *L, Table *t, StkId key) { | 127 | static 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 | ||