aboutsummaryrefslogtreecommitdiff
path: root/ltable.c
diff options
context:
space:
mode:
Diffstat (limited to 'ltable.c')
-rw-r--r--ltable.c131
1 files changed, 85 insertions, 46 deletions
diff --git a/ltable.c b/ltable.c
index 4ce33319..498eb121 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 2.121 2017/05/19 12:47:00 roberto Exp roberto $ 2** $Id: ltable.c,v 2.122 2017/05/19 12:57:10 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*/
@@ -75,8 +75,8 @@
75#define dummynode (&dummynode_) 75#define dummynode (&dummynode_)
76 76
77static const Node dummynode_ = { 77static const Node dummynode_ = {
78 {NILCONSTANT}, /* value */ 78 {{NULL}, LUA_TNIL, /* value's value and type */
79 {{NILCONSTANT, 0}} /* key */ 79 LUA_TNIL, 0, {NULL}} /* key type, next, and key value */
80}; 80};
81 81
82 82
@@ -111,43 +111,79 @@ static int l_hashfloat (lua_Number n) {
111 111
112 112
113/* 113/*
114** returns the 'main' position of an element in a table (that is, the index 114** returns the 'main' position of an element in a table (that is,
115** of its hash value) 115** the index of its hash value). The key comes broken (tag in 'ktt'
116** and value in 'vkl') so that we can call it on keys inserted into
117** nodes.
116*/ 118*/
117static Node *mainposition (const Table *t, const TValue *key) { 119static Node *mainposition (const Table *t, int ktt, const Value *kvl) {
118 switch (ttype(key)) { 120 switch (ttyperaw(ktt)) {
119 case LUA_TNUMINT: 121 case LUA_TNUMINT:
120 return hashint(t, ivalue(key)); 122 return hashint(t, ivalueraw(*kvl));
121 case LUA_TNUMFLT: 123 case LUA_TNUMFLT:
122 return hashmod(t, l_hashfloat(fltvalue(key))); 124 return hashmod(t, l_hashfloat(fltvalueraw(*kvl)));
123 case LUA_TSHRSTR: 125 case LUA_TSHRSTR:
124 return hashstr(t, tsvalue(key)); 126 return hashstr(t, tsvalueraw(*kvl));
125 case LUA_TLNGSTR: 127 case LUA_TLNGSTR:
126 return hashpow2(t, luaS_hashlongstr(tsvalue(key))); 128 return hashpow2(t, luaS_hashlongstr(tsvalueraw(*kvl)));
127 case LUA_TBOOLEAN: 129 case LUA_TBOOLEAN:
128 return hashboolean(t, bvalue(key)); 130 return hashboolean(t, bvalueraw(*kvl));
129 case LUA_TLIGHTUSERDATA: 131 case LUA_TLIGHTUSERDATA:
130 return hashpointer(t, pvalue(key)); 132 return hashpointer(t, pvalueraw(*kvl));
131 case LUA_TLCF: 133 case LUA_TLCF:
132 return hashpointer(t, fvalue(key)); 134 return hashpointer(t, fvalueraw(*kvl));
133 default: 135 default:
134 lua_assert(!ttisdeadkey(key)); 136 return hashpointer(t, gcvalueraw(*kvl));
135 return hashpointer(t, gcvalue(key));
136 } 137 }
137} 138}
138 139
139 140
141static Node *mainpositionTV (const Table *t, const TValue *key) {
142 return mainposition(t, rttype(key), valraw(key));
143}
144
145
140/* 146/*
141** returns the index for 'key' if 'key' is an appropriate key to live in 147** Check whether key 'k1' is equal to the key in node 'n2'.
142** the array part of the table, 0 otherwise. 148** This equality is raw, so there are no metamethods. Floats
149** with integer values have been normalized, so integers cannot
150** be equal to floats. It is assumed that 'eqshrstr' is simply
151** pointer equality, so that short strings are handled in the
152** default case.
143*/ 153*/
144static unsigned int arrayindex (const TValue *key) { 154static int equalkey (const TValue *k1, const Node *n2) {
145 if (ttisinteger(key)) { 155 if (rttype(k1) != keytt(n2)) /* not the same variants? */
146 lua_Integer k = ivalue(key); 156 return 0; /* cannot be same key */
147 if (0 < k && (lua_Unsigned)k <= MAXASIZE) 157 switch (ttype(k1)) {
148 return cast(unsigned int, k); /* 'key' is an appropriate array index */ 158 case LUA_TNIL:
159 return 1;
160 case LUA_TNUMINT:
161 return (ivalue(k1) == keyival(n2));
162 case LUA_TNUMFLT:
163 return luai_numeq(fltvalue(k1), fltvalueraw(keyval(n2)));
164 case LUA_TBOOLEAN:
165 return bvalue(k1) == bvalueraw(keyval(n2));
166 case LUA_TLIGHTUSERDATA:
167 return pvalue(k1) == pvalueraw(keyval(n2));
168 case LUA_TLCF:
169 return fvalue(k1) == fvalueraw(keyval(n2));
170 case LUA_TLNGSTR:
171 return luaS_eqlngstr(tsvalue(k1), keystrval(n2));
172 default:
173 return gcvalue(k1) == gcvalueraw(keyval(n2));
149 } 174 }
150 return 0; /* 'key' did not match some condition */ 175}
176
177
178/*
179** returns the index for 'k' if 'k' is an appropriate key to live in
180** the array part of a table, 0 otherwise.
181*/
182static unsigned int arrayindex (lua_Integer k) {
183 if (0 < k && l_castS2U(k) <= MAXASIZE)
184 return cast(unsigned int, k); /* 'key' is an appropriate array index */
185 else
186 return 0;
151} 187}
152 188
153 189
@@ -159,17 +195,17 @@ static unsigned int arrayindex (const TValue *key) {
159static unsigned int findindex (lua_State *L, Table *t, StkId key) { 195static unsigned int findindex (lua_State *L, Table *t, StkId key) {
160 unsigned int i; 196 unsigned int i;
161 if (ttisnil(key)) return 0; /* first iteration */ 197 if (ttisnil(key)) return 0; /* first iteration */
162 i = arrayindex(key); 198 i = ttisinteger(key) ? arrayindex(ivalue(key)) : 0;
163 if (i != 0 && i <= t->sizearray) /* is 'key' inside array part? */ 199 if (i != 0 && i <= t->sizearray) /* is 'key' inside array part? */
164 return i; /* yes; that's the index */ 200 return i; /* yes; that's the index */
165 else { 201 else {
166 int nx; 202 int nx;
167 Node *n = mainposition(t, key); 203 Node *n = mainpositionTV(t, key);
168 for (;;) { /* check whether 'key' is somewhere in the chain */ 204 for (;;) { /* check whether 'key' is somewhere in the chain */
169 /* key may be dead already, but it is ok to use it in 'next' */ 205 /* key may be dead already, but it is ok to use it in 'next' */
170 if (luaV_rawequalobj(gkey(n), key) || 206 if (equalkey(key, n) ||
171 (ttisdeadkey(gkey(n)) && iscollectable(key) && 207 (keyisdead(n) && iscollectable(key) &&
172 deadvalue(gkey(n)) == gcvalue(key))) { 208 deadkey(n) == gcvalue(key))) {
173 i = cast_int(n - gnode(t, 0)); /* key index in hash table */ 209 i = cast_int(n - gnode(t, 0)); /* key index in hash table */
174 /* hash elements are numbered after array ones */ 210 /* hash elements are numbered after array ones */
175 return (i + 1) + t->sizearray; 211 return (i + 1) + t->sizearray;
@@ -194,8 +230,9 @@ int luaH_next (lua_State *L, Table *t, StkId key) {
194 } 230 }
195 for (i -= t->sizearray; cast_int(i) < sizenode(t); i++) { /* hash part */ 231 for (i -= t->sizearray; cast_int(i) < sizenode(t); i++) { /* hash part */
196 if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ 232 if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */
197 setobj2s(L, key, gkey(gnode(t, i))); 233 Node *n = gnode(t, i);
198 setobj2s(L, key+1, gval(gnode(t, i))); 234 getnodekey(L, key, n);
235 setobj2s(L, key + 1, gval(n));
199 return 1; 236 return 1;
200 } 237 }
201 } 238 }
@@ -239,7 +276,7 @@ static unsigned int computesizes (unsigned int nums[], unsigned int *pna) {
239} 276}
240 277
241 278
242static int countint (const TValue *key, unsigned int *nums) { 279static int countint (lua_Integer key, unsigned int *nums) {
243 unsigned int k = arrayindex(key); 280 unsigned int k = arrayindex(key);
244 if (k != 0) { /* is 'key' an appropriate array index? */ 281 if (k != 0) { /* is 'key' an appropriate array index? */
245 nums[luaO_ceillog2(k)]++; /* count as such */ 282 nums[luaO_ceillog2(k)]++; /* count as such */
@@ -288,7 +325,8 @@ static int numusehash (const Table *t, unsigned int *nums, unsigned int *pna) {
288 while (i--) { 325 while (i--) {
289 Node *n = &t->node[i]; 326 Node *n = &t->node[i];
290 if (!ttisnil(gval(n))) { 327 if (!ttisnil(gval(n))) {
291 ause += countint(gkey(n), nums); 328 if (keyisinteger(n))
329 ause += countint(keyival(n), nums);
292 totaluse++; 330 totaluse++;
293 } 331 }
294 } 332 }
@@ -322,7 +360,7 @@ static void setnodevector (lua_State *L, Table *t, unsigned int size) {
322 for (i = 0; i < (int)size; i++) { 360 for (i = 0; i < (int)size; i++) {
323 Node *n = gnode(t, i); 361 Node *n = gnode(t, i);
324 gnext(n) = 0; 362 gnext(n) = 0;
325 setnilvalue(wgkey(n)); 363 setnilkey(n);
326 setnilvalue(gval(n)); 364 setnilvalue(gval(n));
327 } 365 }
328 t->lsizenode = cast_byte(lsize); 366 t->lsizenode = cast_byte(lsize);
@@ -358,7 +396,8 @@ void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
358 if (!ttisnil(gval(old))) { 396 if (!ttisnil(gval(old))) {
359 /* doesn't need barrier/invalidate cache, as entry was 397 /* doesn't need barrier/invalidate cache, as entry was
360 already present in the table */ 398 already present in the table */
361 setobjt2t(L, luaH_set(L, t, gkey(old)), gval(old)); 399 TValue k; getnodekey(L, &k, old);
400 setobjt2t(L, luaH_set(L, t, &k), gval(old));
362 } 401 }
363 } 402 }
364 if (oldhsize > 0) /* not the dummy node? */ 403 if (oldhsize > 0) /* not the dummy node? */
@@ -385,7 +424,8 @@ static void rehash (lua_State *L, Table *t, const TValue *ek) {
385 totaluse = na; /* all those keys are integer keys */ 424 totaluse = na; /* all those keys are integer keys */
386 totaluse += numusehash(t, nums, &na); /* count keys in hash part */ 425 totaluse += numusehash(t, nums, &na); /* count keys in hash part */
387 /* count extra key */ 426 /* count extra key */
388 na += countint(ek, nums); 427 if (ttisinteger(ek))
428 na += countint(ivalue(ek), nums);
389 totaluse++; 429 totaluse++;
390 /* compute new size for array part */ 430 /* compute new size for array part */
391 asize = computesizes(nums, &na); 431 asize = computesizes(nums, &na);
@@ -424,7 +464,7 @@ static Node *getfreepos (Table *t) {
424 if (!isdummy(t)) { 464 if (!isdummy(t)) {
425 while (t->lastfree > t->node) { 465 while (t->lastfree > t->node) {
426 t->lastfree--; 466 t->lastfree--;
427 if (ttisnil(gkey(t->lastfree))) 467 if (keyisnil(t->lastfree))
428 return t->lastfree; 468 return t->lastfree;
429 } 469 }
430 } 470 }
@@ -453,7 +493,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
453 else if (luai_numisnan(fltvalue(key))) 493 else if (luai_numisnan(fltvalue(key)))
454 luaG_runerror(L, "table index is NaN"); 494 luaG_runerror(L, "table index is NaN");
455 } 495 }
456 mp = mainposition(t, key); 496 mp = mainpositionTV(t, key);
457 if (!ttisnil(gval(mp)) || isdummy(t)) { /* main position is taken? */ 497 if (!ttisnil(gval(mp)) || isdummy(t)) { /* main position is taken? */
458 Node *othern; 498 Node *othern;
459 Node *f = getfreepos(t); /* get a free place */ 499 Node *f = getfreepos(t); /* get a free place */
@@ -463,7 +503,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
463 return luaH_set(L, t, key); /* insert key into grown table */ 503 return luaH_set(L, t, key); /* insert key into grown table */
464 } 504 }
465 lua_assert(!isdummy(t)); 505 lua_assert(!isdummy(t));
466 othern = mainposition(t, gkey(mp)); 506 othern = mainposition(t, keytt(mp), &keyval(mp));
467 if (othern != mp) { /* is colliding node out of its main position? */ 507 if (othern != mp) { /* is colliding node out of its main position? */
468 /* yes; move colliding node into free position */ 508 /* yes; move colliding node into free position */
469 while (othern + gnext(othern) != mp) /* find previous */ 509 while (othern + gnext(othern) != mp) /* find previous */
@@ -485,7 +525,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
485 mp = f; 525 mp = f;
486 } 526 }
487 } 527 }
488 setnodekey(L, &mp->i_key, key); 528 setnodekey(L, mp, key);
489 luaC_barrierback(L, t, key); 529 luaC_barrierback(L, t, key);
490 lua_assert(ttisnil(gval(mp))); 530 lua_assert(ttisnil(gval(mp)));
491 return gval(mp); 531 return gval(mp);
@@ -502,7 +542,7 @@ const TValue *luaH_getint (Table *t, lua_Integer key) {
502 else { 542 else {
503 Node *n = hashint(t, key); 543 Node *n = hashint(t, key);
504 for (;;) { /* check whether 'key' is somewhere in the chain */ 544 for (;;) { /* check whether 'key' is somewhere in the chain */
505 if (ttisinteger(gkey(n)) && ivalue(gkey(n)) == key) 545 if (keyisinteger(n) && keyival(n) == key)
506 return gval(n); /* that's it */ 546 return gval(n); /* that's it */
507 else { 547 else {
508 int nx = gnext(n); 548 int nx = gnext(n);
@@ -522,8 +562,7 @@ const TValue *luaH_getshortstr (Table *t, TString *key) {
522 Node *n = hashstr(t, key); 562 Node *n = hashstr(t, key);
523 lua_assert(key->tt == LUA_TSHRSTR); 563 lua_assert(key->tt == LUA_TSHRSTR);
524 for (;;) { /* check whether 'key' is somewhere in the chain */ 564 for (;;) { /* check whether 'key' is somewhere in the chain */
525 const TValue *k = gkey(n); 565 if (keyisshrstr(n) && eqshrstr(keystrval(n), key))
526 if (ttisshrstring(k) && eqshrstr(tsvalue(k), key))
527 return gval(n); /* that's it */ 566 return gval(n); /* that's it */
528 else { 567 else {
529 int nx = gnext(n); 568 int nx = gnext(n);
@@ -540,9 +579,9 @@ const TValue *luaH_getshortstr (Table *t, TString *key) {
540** which may be in array part, nor for floats with integral values.) 579** which may be in array part, nor for floats with integral values.)
541*/ 580*/
542static const TValue *getgeneric (Table *t, const TValue *key) { 581static const TValue *getgeneric (Table *t, const TValue *key) {
543 Node *n = mainposition(t, key); 582 Node *n = mainpositionTV(t, key);
544 for (;;) { /* check whether 'key' is somewhere in the chain */ 583 for (;;) { /* check whether 'key' is somewhere in the chain */
545 if (luaV_rawequalobj(gkey(n), key)) 584 if (equalkey(key, n))
546 return gval(n); /* that's it */ 585 return gval(n); /* that's it */
547 else { 586 else {
548 int nx = gnext(n); 587 int nx = gnext(n);
@@ -683,7 +722,7 @@ lua_Unsigned luaH_getn (Table *t) {
683#if defined(LUA_DEBUG) 722#if defined(LUA_DEBUG)
684 723
685Node *luaH_mainposition (const Table *t, const TValue *key) { 724Node *luaH_mainposition (const Table *t, const TValue *key) {
686 return mainposition(t, key); 725 return mainpositionTV(t, key);
687} 726}
688 727
689int luaH_isdummy (const Table *t) { return isdummy(t); } 728int luaH_isdummy (const Table *t) { return isdummy(t); }