diff --git a/lobject.h b/lobject.h index ba425fed..3ab75ad5 100644 --- a/lobject.h +++ b/lobject.h @@ -1,5 +1,5 @@ /* -** $Id: lobject.h,v 2.78 2013/05/14 15:59:04 roberto Exp roberto $ +** $Id: lobject.h,v 2.79 2013/08/07 12:18:11 roberto Exp roberto $ ** Type definitions for Lua objects ** See Copyright Notice in lua.h */ @@ -438,7 +438,7 @@ typedef union Closure { typedef union TKey { struct { TValuefields; - struct Node *next; /* for chaining */ + int next; /* for chaining (offset for next node) */ } nk; TValue tvk; } TKey; diff --git a/ltable.c b/ltable.c index 6a7e28f0..f5b8fcf6 100644 --- a/ltable.c +++ b/ltable.c @@ -1,5 +1,5 @@ /* -** $Id: ltable.c,v 2.77 2013/05/29 14:05:03 roberto Exp roberto $ +** $Id: ltable.c,v 2.78 2013/06/20 15:02:49 roberto Exp roberto $ ** Lua tables (hash) ** See Copyright Notice in lua.h */ @@ -79,7 +79,7 @@ static const Node dummynode_ = { {NILCONSTANT}, /* value */ - {{NILCONSTANT, NULL}} /* key */ + {{NILCONSTANT, 0}} /* key */ }; @@ -158,6 +158,7 @@ static int findindex (lua_State *L, Table *t, StkId key) { if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ return i-1; /* yes; that's the index (corrected to C) */ else { + int nx; Node *n = mainposition(t, key); for (;;) { /* check whether `key' is somewhere in the chain */ /* key may be dead already, but it is ok to use it in `next' */ @@ -168,9 +169,10 @@ static int findindex (lua_State *L, Table *t, StkId key) { /* hash elements are numbered after array ones */ return i + t->sizearray; } - else n = gnext(n); - if (n == NULL) + nx = gnext(n); + if (nx == 0) luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ + else n += nx; } } } @@ -301,7 +303,7 @@ static void setnodevector (lua_State *L, Table *t, int size) { t->node = luaM_newvector(L, size, Node); for (i=0; inext also goes) */ - gnext(mp) = NULL; /* now `mp' is free */ + while (othern + gnext(othern) != mp) /* find previous */ + othern += gnext(othern); + gnext(othern) = f - othern; /* re-chain with 'f' in place of 'mp' */ + *f = *mp; /* copy colliding node into free pos. (mp->next also goes) */ + if (gnext(mp) != 0) { + gnext(f) += mp - f; /* correct 'next' */ + gnext(mp) = 0; /* now 'mp' is free */ + } setnilvalue(gval(mp)); } else { /* colliding node is in its own main position */ /* new node will go into free position */ - gnext(n) = gnext(mp); /* chain new position */ - gnext(mp) = n; - mp = n; + if (gnext(mp) != 0) + gnext(f) = (mp + gnext(mp)) - f; /* chain new position */ + else lua_assert(gnext(f) == 0); + gnext(mp) = f - mp; + mp = f; } } setobj2t(L, gkey(mp), key); @@ -468,11 +476,15 @@ const TValue *luaH_getint (Table *t, lua_Integer key) { return &t->array[key - 1]; else { Node *n = hashint(t, key); - do { /* check whether `key' is somewhere in the chain */ + for (;;) { /* check whether `key' is somewhere in the chain */ if (ttisinteger(gkey(n)) && ivalue(gkey(n)) == key) return gval(n); /* that's it */ - else n = gnext(n); - } while (n); + else { + int nx = gnext(n); + if (nx == 0) break; + n += nx; + } + }; return luaO_nilobject; } } @@ -484,11 +496,15 @@ const TValue *luaH_getint (Table *t, lua_Integer key) { const TValue *luaH_getstr (Table *t, TString *key) { Node *n = hashstr(t, key); lua_assert(key->tsv.tt == LUA_TSHRSTR); - do { /* check whether `key' is somewhere in the chain */ + for (;;) { /* check whether `key' is somewhere in the chain */ if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key)) return gval(n); /* that's it */ - else n = gnext(n); - } while (n); + else { + int nx = gnext(n); + if (nx == 0) break; + n += nx; + } + }; return luaO_nilobject; } @@ -509,11 +525,15 @@ const TValue *luaH_get (Table *t, const TValue *key) { } default: { Node *n = mainposition(t, key); - do { /* check whether `key' is somewhere in the chain */ + for (;;) { /* check whether `key' is somewhere in the chain */ if (luaV_rawequalobj(gkey(n), key)) return gval(n); /* that's it */ - else n = gnext(n); - } while (n); + else { + int nx = gnext(n); + if (nx == 0) break; + n += nx; + } + }; return luaO_nilobject; } } diff --git a/ltests.c b/ltests.c index e99b2b61..1fb01cfd 100644 --- a/ltests.c +++ b/ltests.c @@ -1,5 +1,5 @@ /* -** $Id: ltests.c,v 2.142 2013/08/16 18:55:49 roberto Exp roberto $ +** $Id: ltests.c,v 2.143 2013/08/16 19:02:31 roberto Exp roberto $ ** Internal Module for Debugging of the Lua Implementation ** See Copyright Notice in lua.h */ @@ -718,8 +718,8 @@ static int table_query (lua_State *L) { else lua_pushliteral(L, ""); pushobject(L, gval(gnode(t, i))); - if (gnext(&t->node[i])) - lua_pushinteger(L, gnext(&t->node[i]) - t->node); + if (gnext(&t->node[i]) != 0) + lua_pushinteger(L, gnext(&t->node[i])); else lua_pushnil(L); }