summaryrefslogtreecommitdiff
path: root/ltable.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-11-03 13:47:30 -0200
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2015-11-03 13:47:30 -0200
commit46de77b219e381ff8553fdba0f52b319c00ea1e1 (patch)
tree3b703e4df3dd2b69f0f768153fc75d2336d98bdb /ltable.c
parentd356183402e214f4859cd6508964d4b5e781c598 (diff)
downloadlua-github-46de77b219e381ff8553fdba0f52b319c00ea1e1.tar.gz
bug: despite its name, 'luaH_getstr' did not work for strings in
general, but only for short strings
Diffstat (limited to 'ltable.c')
-rw-r--r--ltable.c51
1 files changed, 35 insertions, 16 deletions
diff --git a/ltable.c b/ltable.c
index 8a345062..e47b81f7 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
/*
-** $Id: ltable.c,v 2.112 2015/07/01 17:46:55 roberto Exp roberto $
+** $Id: ltable.c,v 2.113 2015/07/04 16:32:34 roberto Exp roberto $
** Lua tables (hash)
** See Copyright Notice in lua.h
*/
@@ -124,14 +124,8 @@ static Node *mainposition (const Table *t, const TValue *key) {
return hashmod(t, l_hashfloat(fltvalue(key)));
case LUA_TSHRSTR:
return hashstr(t, tsvalue(key));
- case LUA_TLNGSTR: {
- TString *s = tsvalue(key);
- if (s->extra == 0) { /* no hash? */
- s->hash = luaS_hash(getstr(s), s->u.lnglen, s->hash);
- s->extra = 1; /* now it has its hash */
- }
- return hashstr(t, tsvalue(key));
- }
+ case LUA_TLNGSTR:
+ return hashpow2(t, luaS_hashlongstr(tsvalue(key)));
case LUA_TBOOLEAN:
return hashboolean(t, bvalue(key));
case LUA_TLIGHTUSERDATA:
@@ -522,7 +516,7 @@ const TValue *luaH_getint (Table *t, lua_Integer key) {
/*
** search function for short strings
*/
-const TValue *luaH_getstr (Table *t, TString *key) {
+const TValue *luaH_getshortstr (Table *t, TString *key) {
Node *n = hashstr(t, key);
lua_assert(key->tt == LUA_TSHRSTR);
for (;;) { /* check whether 'key' is somewhere in the chain */
@@ -531,11 +525,35 @@ const TValue *luaH_getstr (Table *t, TString *key) {
return gval(n); /* that's it */
else {
int nx = gnext(n);
- if (nx == 0) break;
+ if (nx == 0)
+ return luaO_nilobject; /* not found */
n += nx;
}
- };
- return luaO_nilobject;
+ }
+}
+
+
+static const TValue *getlngstr (Table *t, TString *key) {
+ Node *n = hashpow2(t, luaS_hashlongstr(key));
+ for (;;) { /* check whether 'key' is somewhere in the chain */
+ const TValue *k = gkey(n);
+ if (ttislngstring(k) && luaS_eqlngstr(tsvalue(k), key))
+ return gval(n); /* that's it */
+ else {
+ int nx = gnext(n);
+ if (nx == 0)
+ return luaO_nilobject; /* not found */
+ n += nx;
+ }
+ }
+}
+
+
+const TValue *luaH_getstr (Table *t, TString *key) {
+ if (key->tt == LUA_TSHRSTR)
+ return luaH_getshortstr(t, key);
+ else
+ return getlngstr(t, key);
}
@@ -544,7 +562,8 @@ const TValue *luaH_getstr (Table *t, TString *key) {
*/
const TValue *luaH_get (Table *t, const TValue *key) {
switch (ttype(key)) {
- case LUA_TSHRSTR: return luaH_getstr(t, tsvalue(key));
+ case LUA_TSHRSTR: return luaH_getshortstr(t, tsvalue(key));
+ case LUA_TLNGSTR: return getlngstr(t, tsvalue(key));
case LUA_TNUMINT: return luaH_getint(t, ivalue(key));
case LUA_TNIL: return luaO_nilobject;
case LUA_TNUMFLT: {
@@ -560,11 +579,11 @@ const TValue *luaH_get (Table *t, const TValue *key) {
return gval(n); /* that's it */
else {
int nx = gnext(n);
- if (nx == 0) break;
+ if (nx == 0)
+ return luaO_nilobject; /* not found */
n += nx;
}
};
- return luaO_nilobject;
}
}
}