2
0
Эх сурвалжийг харах

bug: despite its name, 'luaH_getstr' did not work for strings in
general, but only for short strings

Roberto Ierusalimschy 9 жил өмнө
parent
commit
46de77b219
3 өөрчлөгдсөн 44 нэмэгдсэн , 20 устгасан
  1. 35 16
      ltable.c
  2. 6 1
      ltable.h
  3. 3 3
      ltm.c

+ 35 - 16
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;
     }
   }
 }

+ 6 - 1
ltable.h

@@ -1,5 +1,5 @@
 /*
-** $Id: ltable.h,v 2.19 2014/07/29 16:22:24 roberto Exp roberto $
+** $Id: ltable.h,v 2.20 2014/09/04 18:15:29 roberto Exp roberto $
 ** Lua tables (hash)
 ** See Copyright Notice in lua.h
 */
@@ -18,6 +18,10 @@
 /* 'const' to avoid wrong writings that can mess up field 'next' */ 
 #define gkey(n)		cast(const TValue*, (&(n)->i_key.tvk))
 
+/*
+** writable version of 'gkey'; allows updates to individual fields,
+** but not to the whole (which has incompatible type)
+*/
 #define wgkey(n)		(&(n)->i_key.nk)
 
 #define invalidateTMcache(t)	((t)->flags = 0)
@@ -31,6 +35,7 @@
 LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key);
 LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key,
                                                     TValue *value);
+LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key);
 LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key);
 LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key);
 LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key);

+ 3 - 3
ltm.c

@@ -1,5 +1,5 @@
 /*
-** $Id: ltm.c,v 2.34 2015/03/30 15:42:27 roberto Exp roberto $
+** $Id: ltm.c,v 2.35 2015/11/02 18:48:07 roberto Exp roberto $
 ** Tag methods
 ** See Copyright Notice in lua.h
 */
@@ -57,7 +57,7 @@ void luaT_init (lua_State *L) {
 ** tag methods
 */
 const TValue *luaT_gettm (Table *events, TMS event, TString *ename) {
-  const TValue *tm = luaH_getstr(events, ename);
+  const TValue *tm = luaH_getshortstr(events, ename);
   lua_assert(event <= TM_EQ);
   if (ttisnil(tm)) {  /* no tag method? */
     events->flags |= cast_byte(1u<<event);  /* cache this fact */
@@ -79,7 +79,7 @@ const TValue *luaT_gettmbyobj (lua_State *L, const TValue *o, TMS event) {
     default:
       mt = G(L)->mt[ttnov(o)];
   }
-  return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject);
+  return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : luaO_nilobject);
 }