diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-11-03 13:47:30 -0200 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2015-11-03 13:47:30 -0200 |
| commit | 46de77b219e381ff8553fdba0f52b319c00ea1e1 (patch) | |
| tree | 3b703e4df3dd2b69f0f768153fc75d2336d98bdb | |
| parent | d356183402e214f4859cd6508964d4b5e781c598 (diff) | |
| download | lua-46de77b219e381ff8553fdba0f52b319c00ea1e1.tar.gz lua-46de77b219e381ff8553fdba0f52b319c00ea1e1.tar.bz2 lua-46de77b219e381ff8553fdba0f52b319c00ea1e1.zip | |
bug: despite its name, 'luaH_getstr' did not work for strings in
general, but only for short strings
| -rw-r--r-- | ltable.c | 51 | ||||
| -rw-r--r-- | ltable.h | 7 | ||||
| -rw-r--r-- | ltm.c | 6 |
3 files changed, 44 insertions, 20 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltable.c,v 2.112 2015/07/01 17:46:55 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 2.113 2015/07/04 16:32:34 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 | */ |
| @@ -124,14 +124,8 @@ static Node *mainposition (const Table *t, const TValue *key) { | |||
| 124 | return hashmod(t, l_hashfloat(fltvalue(key))); | 124 | return hashmod(t, l_hashfloat(fltvalue(key))); |
| 125 | case LUA_TSHRSTR: | 125 | case LUA_TSHRSTR: |
| 126 | return hashstr(t, tsvalue(key)); | 126 | return hashstr(t, tsvalue(key)); |
| 127 | case LUA_TLNGSTR: { | 127 | case LUA_TLNGSTR: |
| 128 | TString *s = tsvalue(key); | 128 | return hashpow2(t, luaS_hashlongstr(tsvalue(key))); |
| 129 | if (s->extra == 0) { /* no hash? */ | ||
| 130 | s->hash = luaS_hash(getstr(s), s->u.lnglen, s->hash); | ||
| 131 | s->extra = 1; /* now it has its hash */ | ||
| 132 | } | ||
| 133 | return hashstr(t, tsvalue(key)); | ||
| 134 | } | ||
| 135 | case LUA_TBOOLEAN: | 129 | case LUA_TBOOLEAN: |
| 136 | return hashboolean(t, bvalue(key)); | 130 | return hashboolean(t, bvalue(key)); |
| 137 | case LUA_TLIGHTUSERDATA: | 131 | case LUA_TLIGHTUSERDATA: |
| @@ -522,7 +516,7 @@ const TValue *luaH_getint (Table *t, lua_Integer key) { | |||
| 522 | /* | 516 | /* |
| 523 | ** search function for short strings | 517 | ** search function for short strings |
| 524 | */ | 518 | */ |
| 525 | const TValue *luaH_getstr (Table *t, TString *key) { | 519 | const TValue *luaH_getshortstr (Table *t, TString *key) { |
| 526 | Node *n = hashstr(t, key); | 520 | Node *n = hashstr(t, key); |
| 527 | lua_assert(key->tt == LUA_TSHRSTR); | 521 | lua_assert(key->tt == LUA_TSHRSTR); |
| 528 | for (;;) { /* check whether 'key' is somewhere in the chain */ | 522 | for (;;) { /* check whether 'key' is somewhere in the chain */ |
| @@ -531,11 +525,35 @@ const TValue *luaH_getstr (Table *t, TString *key) { | |||
| 531 | return gval(n); /* that's it */ | 525 | return gval(n); /* that's it */ |
| 532 | else { | 526 | else { |
| 533 | int nx = gnext(n); | 527 | int nx = gnext(n); |
| 534 | if (nx == 0) break; | 528 | if (nx == 0) |
| 529 | return luaO_nilobject; /* not found */ | ||
| 535 | n += nx; | 530 | n += nx; |
| 536 | } | 531 | } |
| 537 | }; | 532 | } |
| 538 | return luaO_nilobject; | 533 | } |
| 534 | |||
| 535 | |||
| 536 | static const TValue *getlngstr (Table *t, TString *key) { | ||
| 537 | Node *n = hashpow2(t, luaS_hashlongstr(key)); | ||
| 538 | for (;;) { /* check whether 'key' is somewhere in the chain */ | ||
| 539 | const TValue *k = gkey(n); | ||
| 540 | if (ttislngstring(k) && luaS_eqlngstr(tsvalue(k), key)) | ||
| 541 | return gval(n); /* that's it */ | ||
| 542 | else { | ||
| 543 | int nx = gnext(n); | ||
| 544 | if (nx == 0) | ||
| 545 | return luaO_nilobject; /* not found */ | ||
| 546 | n += nx; | ||
| 547 | } | ||
| 548 | } | ||
| 549 | } | ||
| 550 | |||
| 551 | |||
| 552 | const TValue *luaH_getstr (Table *t, TString *key) { | ||
| 553 | if (key->tt == LUA_TSHRSTR) | ||
| 554 | return luaH_getshortstr(t, key); | ||
| 555 | else | ||
| 556 | return getlngstr(t, key); | ||
| 539 | } | 557 | } |
| 540 | 558 | ||
| 541 | 559 | ||
| @@ -544,7 +562,8 @@ const TValue *luaH_getstr (Table *t, TString *key) { | |||
| 544 | */ | 562 | */ |
| 545 | const TValue *luaH_get (Table *t, const TValue *key) { | 563 | const TValue *luaH_get (Table *t, const TValue *key) { |
| 546 | switch (ttype(key)) { | 564 | switch (ttype(key)) { |
| 547 | case LUA_TSHRSTR: return luaH_getstr(t, tsvalue(key)); | 565 | case LUA_TSHRSTR: return luaH_getshortstr(t, tsvalue(key)); |
| 566 | case LUA_TLNGSTR: return getlngstr(t, tsvalue(key)); | ||
| 548 | case LUA_TNUMINT: return luaH_getint(t, ivalue(key)); | 567 | case LUA_TNUMINT: return luaH_getint(t, ivalue(key)); |
| 549 | case LUA_TNIL: return luaO_nilobject; | 568 | case LUA_TNIL: return luaO_nilobject; |
| 550 | case LUA_TNUMFLT: { | 569 | case LUA_TNUMFLT: { |
| @@ -560,11 +579,11 @@ const TValue *luaH_get (Table *t, const TValue *key) { | |||
| 560 | return gval(n); /* that's it */ | 579 | return gval(n); /* that's it */ |
| 561 | else { | 580 | else { |
| 562 | int nx = gnext(n); | 581 | int nx = gnext(n); |
| 563 | if (nx == 0) break; | 582 | if (nx == 0) |
| 583 | return luaO_nilobject; /* not found */ | ||
| 564 | n += nx; | 584 | n += nx; |
| 565 | } | 585 | } |
| 566 | }; | 586 | }; |
| 567 | return luaO_nilobject; | ||
| 568 | } | 587 | } |
| 569 | } | 588 | } |
| 570 | } | 589 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltable.h,v 2.19 2014/07/29 16:22:24 roberto Exp roberto $ | 2 | ** $Id: ltable.h,v 2.20 2014/09/04 18:15:29 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 | */ |
| @@ -18,6 +18,10 @@ | |||
| 18 | /* 'const' to avoid wrong writings that can mess up field 'next' */ | 18 | /* 'const' to avoid wrong writings that can mess up field 'next' */ |
| 19 | #define gkey(n) cast(const TValue*, (&(n)->i_key.tvk)) | 19 | #define gkey(n) cast(const TValue*, (&(n)->i_key.tvk)) |
| 20 | 20 | ||
| 21 | /* | ||
| 22 | ** writable version of 'gkey'; allows updates to individual fields, | ||
| 23 | ** but not to the whole (which has incompatible type) | ||
| 24 | */ | ||
| 21 | #define wgkey(n) (&(n)->i_key.nk) | 25 | #define wgkey(n) (&(n)->i_key.nk) |
| 22 | 26 | ||
| 23 | #define invalidateTMcache(t) ((t)->flags = 0) | 27 | #define invalidateTMcache(t) ((t)->flags = 0) |
| @@ -31,6 +35,7 @@ | |||
| 31 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); | 35 | LUAI_FUNC const TValue *luaH_getint (Table *t, lua_Integer key); |
| 32 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, | 36 | LUAI_FUNC void luaH_setint (lua_State *L, Table *t, lua_Integer key, |
| 33 | TValue *value); | 37 | TValue *value); |
| 38 | LUAI_FUNC const TValue *luaH_getshortstr (Table *t, TString *key); | ||
| 34 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); | 39 | LUAI_FUNC const TValue *luaH_getstr (Table *t, TString *key); |
| 35 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); | 40 | LUAI_FUNC const TValue *luaH_get (Table *t, const TValue *key); |
| 36 | LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); | 41 | LUAI_FUNC TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key); |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltm.c,v 2.34 2015/03/30 15:42:27 roberto Exp roberto $ | 2 | ** $Id: ltm.c,v 2.35 2015/11/02 18:48:07 roberto Exp roberto $ |
| 3 | ** Tag methods | 3 | ** Tag methods |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -57,7 +57,7 @@ void luaT_init (lua_State *L) { | |||
| 57 | ** tag methods | 57 | ** tag methods |
| 58 | */ | 58 | */ |
| 59 | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { | 59 | const TValue *luaT_gettm (Table *events, TMS event, TString *ename) { |
| 60 | const TValue *tm = luaH_getstr(events, ename); | 60 | const TValue *tm = luaH_getshortstr(events, ename); |
| 61 | lua_assert(event <= TM_EQ); | 61 | lua_assert(event <= TM_EQ); |
| 62 | if (ttisnil(tm)) { /* no tag method? */ | 62 | if (ttisnil(tm)) { /* no tag method? */ |
| 63 | events->flags |= cast_byte(1u<<event); /* cache this fact */ | 63 | 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) { | |||
| 79 | default: | 79 | default: |
| 80 | mt = G(L)->mt[ttnov(o)]; | 80 | mt = G(L)->mt[ttnov(o)]; |
| 81 | } | 81 | } |
| 82 | return (mt ? luaH_getstr(mt, G(L)->tmname[event]) : luaO_nilobject); | 82 | return (mt ? luaH_getshortstr(mt, G(L)->tmname[event]) : luaO_nilobject); |
| 83 | } | 83 | } |
| 84 | 84 | ||
| 85 | 85 | ||
