diff options
| -rw-r--r-- | lobject.h | 4 | ||||
| -rw-r--r-- | ltable.c | 68 | ||||
| -rw-r--r-- | ltests.c | 6 |
3 files changed, 49 insertions, 29 deletions
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: lobject.h,v 2.78 2013/05/14 15:59:04 roberto Exp roberto $ | 2 | ** $Id: lobject.h,v 2.79 2013/08/07 12:18:11 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 | */ |
| @@ -438,7 +438,7 @@ typedef union Closure { | |||
| 438 | typedef union TKey { | 438 | typedef union TKey { |
| 439 | struct { | 439 | struct { |
| 440 | TValuefields; | 440 | TValuefields; |
| 441 | struct Node *next; /* for chaining */ | 441 | int next; /* for chaining (offset for next node) */ |
| 442 | } nk; | 442 | } nk; |
| 443 | TValue tvk; | 443 | TValue tvk; |
| 444 | } TKey; | 444 | } TKey; |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltable.c,v 2.77 2013/05/29 14:05:03 roberto Exp roberto $ | 2 | ** $Id: ltable.c,v 2.78 2013/06/20 15:02:49 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 | */ |
| @@ -79,7 +79,7 @@ | |||
| 79 | 79 | ||
| 80 | static const Node dummynode_ = { | 80 | static const Node dummynode_ = { |
| 81 | {NILCONSTANT}, /* value */ | 81 | {NILCONSTANT}, /* value */ |
| 82 | {{NILCONSTANT, NULL}} /* key */ | 82 | {{NILCONSTANT, 0}} /* key */ |
| 83 | }; | 83 | }; |
| 84 | 84 | ||
| 85 | 85 | ||
| @@ -158,6 +158,7 @@ static int findindex (lua_State *L, Table *t, StkId key) { | |||
| 158 | if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ | 158 | if (0 < i && i <= t->sizearray) /* is `key' inside array part? */ |
| 159 | return i-1; /* yes; that's the index (corrected to C) */ | 159 | return i-1; /* yes; that's the index (corrected to C) */ |
| 160 | else { | 160 | else { |
| 161 | int nx; | ||
| 161 | Node *n = mainposition(t, key); | 162 | Node *n = mainposition(t, key); |
| 162 | for (;;) { /* check whether `key' is somewhere in the chain */ | 163 | for (;;) { /* check whether `key' is somewhere in the chain */ |
| 163 | /* key may be dead already, but it is ok to use it in `next' */ | 164 | /* 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) { | |||
| 168 | /* hash elements are numbered after array ones */ | 169 | /* hash elements are numbered after array ones */ |
| 169 | return i + t->sizearray; | 170 | return i + t->sizearray; |
| 170 | } | 171 | } |
| 171 | else n = gnext(n); | 172 | nx = gnext(n); |
| 172 | if (n == NULL) | 173 | if (nx == 0) |
| 173 | luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ | 174 | luaG_runerror(L, "invalid key to " LUA_QL("next")); /* key not found */ |
| 175 | else n += nx; | ||
| 174 | } | 176 | } |
| 175 | } | 177 | } |
| 176 | } | 178 | } |
| @@ -301,7 +303,7 @@ static void setnodevector (lua_State *L, Table *t, int size) { | |||
| 301 | t->node = luaM_newvector(L, size, Node); | 303 | t->node = luaM_newvector(L, size, Node); |
| 302 | for (i=0; i<size; i++) { | 304 | for (i=0; i<size; i++) { |
| 303 | Node *n = gnode(t, i); | 305 | Node *n = gnode(t, i); |
| 304 | gnext(n) = NULL; | 306 | gnext(n) = 0; |
| 305 | setnilvalue(gkey(n)); | 307 | setnilvalue(gkey(n)); |
| 306 | setnilvalue(gval(n)); | 308 | setnilvalue(gval(n)); |
| 307 | } | 309 | } |
| @@ -429,27 +431,33 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) { | |||
| 429 | mp = mainposition(t, key); | 431 | mp = mainposition(t, key); |
| 430 | if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */ | 432 | if (!ttisnil(gval(mp)) || isdummy(mp)) { /* main position is taken? */ |
| 431 | Node *othern; | 433 | Node *othern; |
| 432 | Node *n = getfreepos(t); /* get a free place */ | 434 | Node *f = getfreepos(t); /* get a free place */ |
| 433 | if (n == NULL) { /* cannot find a free place? */ | 435 | if (f == NULL) { /* cannot find a free place? */ |
| 434 | rehash(L, t, key); /* grow table */ | 436 | rehash(L, t, key); /* grow table */ |
| 435 | /* whatever called 'newkey' take care of TM cache and GC barrier */ | 437 | /* whatever called 'newkey' take care of TM cache and GC barrier */ |
| 436 | return luaH_set(L, t, key); /* insert key into grown table */ | 438 | return luaH_set(L, t, key); /* insert key into grown table */ |
| 437 | } | 439 | } |
| 438 | lua_assert(!isdummy(n)); | 440 | lua_assert(!isdummy(f)); |
| 439 | othern = mainposition(t, gkey(mp)); | 441 | othern = mainposition(t, gkey(mp)); |
| 440 | if (othern != mp) { /* is colliding node out of its main position? */ | 442 | if (othern != mp) { /* is colliding node out of its main position? */ |
| 441 | /* yes; move colliding node into free position */ | 443 | /* yes; move colliding node into free position */ |
| 442 | while (gnext(othern) != mp) othern = gnext(othern); /* find previous */ | 444 | while (othern + gnext(othern) != mp) /* find previous */ |
| 443 | gnext(othern) = n; /* redo the chain with `n' in place of `mp' */ | 445 | othern += gnext(othern); |
| 444 | *n = *mp; /* copy colliding node into free pos. (mp->next also goes) */ | 446 | gnext(othern) = f - othern; /* re-chain with 'f' in place of 'mp' */ |
| 445 | gnext(mp) = NULL; /* now `mp' is free */ | 447 | *f = *mp; /* copy colliding node into free pos. (mp->next also goes) */ |
| 448 | if (gnext(mp) != 0) { | ||
| 449 | gnext(f) += mp - f; /* correct 'next' */ | ||
| 450 | gnext(mp) = 0; /* now 'mp' is free */ | ||
| 451 | } | ||
| 446 | setnilvalue(gval(mp)); | 452 | setnilvalue(gval(mp)); |
| 447 | } | 453 | } |
| 448 | else { /* colliding node is in its own main position */ | 454 | else { /* colliding node is in its own main position */ |
| 449 | /* new node will go into free position */ | 455 | /* new node will go into free position */ |
| 450 | gnext(n) = gnext(mp); /* chain new position */ | 456 | if (gnext(mp) != 0) |
| 451 | gnext(mp) = n; | 457 | gnext(f) = (mp + gnext(mp)) - f; /* chain new position */ |
| 452 | mp = n; | 458 | else lua_assert(gnext(f) == 0); |
| 459 | gnext(mp) = f - mp; | ||
| 460 | mp = f; | ||
| 453 | } | 461 | } |
| 454 | } | 462 | } |
| 455 | setobj2t(L, gkey(mp), key); | 463 | setobj2t(L, gkey(mp), key); |
| @@ -468,11 +476,15 @@ const TValue *luaH_getint (Table *t, lua_Integer key) { | |||
| 468 | return &t->array[key - 1]; | 476 | return &t->array[key - 1]; |
| 469 | else { | 477 | else { |
| 470 | Node *n = hashint(t, key); | 478 | Node *n = hashint(t, key); |
| 471 | do { /* check whether `key' is somewhere in the chain */ | 479 | for (;;) { /* check whether `key' is somewhere in the chain */ |
| 472 | if (ttisinteger(gkey(n)) && ivalue(gkey(n)) == key) | 480 | if (ttisinteger(gkey(n)) && ivalue(gkey(n)) == key) |
| 473 | return gval(n); /* that's it */ | 481 | return gval(n); /* that's it */ |
| 474 | else n = gnext(n); | 482 | else { |
| 475 | } while (n); | 483 | int nx = gnext(n); |
| 484 | if (nx == 0) break; | ||
| 485 | n += nx; | ||
| 486 | } | ||
| 487 | }; | ||
| 476 | return luaO_nilobject; | 488 | return luaO_nilobject; |
| 477 | } | 489 | } |
| 478 | } | 490 | } |
| @@ -484,11 +496,15 @@ const TValue *luaH_getint (Table *t, lua_Integer key) { | |||
| 484 | const TValue *luaH_getstr (Table *t, TString *key) { | 496 | const TValue *luaH_getstr (Table *t, TString *key) { |
| 485 | Node *n = hashstr(t, key); | 497 | Node *n = hashstr(t, key); |
| 486 | lua_assert(key->tsv.tt == LUA_TSHRSTR); | 498 | lua_assert(key->tsv.tt == LUA_TSHRSTR); |
| 487 | do { /* check whether `key' is somewhere in the chain */ | 499 | for (;;) { /* check whether `key' is somewhere in the chain */ |
| 488 | if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key)) | 500 | if (ttisshrstring(gkey(n)) && eqshrstr(rawtsvalue(gkey(n)), key)) |
| 489 | return gval(n); /* that's it */ | 501 | return gval(n); /* that's it */ |
| 490 | else n = gnext(n); | 502 | else { |
| 491 | } while (n); | 503 | int nx = gnext(n); |
| 504 | if (nx == 0) break; | ||
| 505 | n += nx; | ||
| 506 | } | ||
| 507 | }; | ||
| 492 | return luaO_nilobject; | 508 | return luaO_nilobject; |
| 493 | } | 509 | } |
| 494 | 510 | ||
| @@ -509,11 +525,15 @@ const TValue *luaH_get (Table *t, const TValue *key) { | |||
| 509 | } | 525 | } |
| 510 | default: { | 526 | default: { |
| 511 | Node *n = mainposition(t, key); | 527 | Node *n = mainposition(t, key); |
| 512 | do { /* check whether `key' is somewhere in the chain */ | 528 | for (;;) { /* check whether `key' is somewhere in the chain */ |
| 513 | if (luaV_rawequalobj(gkey(n), key)) | 529 | if (luaV_rawequalobj(gkey(n), key)) |
| 514 | return gval(n); /* that's it */ | 530 | return gval(n); /* that's it */ |
| 515 | else n = gnext(n); | 531 | else { |
| 516 | } while (n); | 532 | int nx = gnext(n); |
| 533 | if (nx == 0) break; | ||
| 534 | n += nx; | ||
| 535 | } | ||
| 536 | }; | ||
| 517 | return luaO_nilobject; | 537 | return luaO_nilobject; |
| 518 | } | 538 | } |
| 519 | } | 539 | } |
| @@ -1,5 +1,5 @@ | |||
| 1 | /* | 1 | /* |
| 2 | ** $Id: ltests.c,v 2.142 2013/08/16 18:55:49 roberto Exp roberto $ | 2 | ** $Id: ltests.c,v 2.143 2013/08/16 19:02:31 roberto Exp roberto $ |
| 3 | ** Internal Module for Debugging of the Lua Implementation | 3 | ** Internal Module for Debugging of the Lua Implementation |
| 4 | ** See Copyright Notice in lua.h | 4 | ** See Copyright Notice in lua.h |
| 5 | */ | 5 | */ |
| @@ -718,8 +718,8 @@ static int table_query (lua_State *L) { | |||
| 718 | else | 718 | else |
| 719 | lua_pushliteral(L, "<undef>"); | 719 | lua_pushliteral(L, "<undef>"); |
| 720 | pushobject(L, gval(gnode(t, i))); | 720 | pushobject(L, gval(gnode(t, i))); |
| 721 | if (gnext(&t->node[i])) | 721 | if (gnext(&t->node[i]) != 0) |
| 722 | lua_pushinteger(L, gnext(&t->node[i]) - t->node); | 722 | lua_pushinteger(L, gnext(&t->node[i])); |
| 723 | else | 723 | else |
| 724 | lua_pushnil(L); | 724 | lua_pushnil(L); |
| 725 | } | 725 | } |
