aboutsummaryrefslogtreecommitdiff
path: root/ltable.c
diff options
context:
space:
mode:
authorRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-02-23 10:16:18 -0300
committerRoberto Ierusalimschy <roberto@inf.puc-rio.br>2018-02-23 10:16:18 -0300
commit9243c414d92c253edd908f438caa31e2aa16f3f4 (patch)
treee8959a48f4672037aef061cc6eb82bba21d0766b /ltable.c
parent477ca2fe8ceaf79038972977915987adbef0e425 (diff)
downloadlua-9243c414d92c253edd908f438caa31e2aa16f3f4.tar.gz
lua-9243c414d92c253edd908f438caa31e2aa16f3f4.tar.bz2
lua-9243c414d92c253edd908f438caa31e2aa16f3f4.zip
first version of empty entries in tables
(so that, in the future, tables can contain regular nil entries)
Diffstat (limited to 'ltable.c')
-rw-r--r--ltable.c63
1 files changed, 33 insertions, 30 deletions
diff --git a/ltable.c b/ltable.c
index 5378e31a..c71d627a 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 2.132 2018/02/19 20:06:56 roberto Exp roberto $ 2** $Id: ltable.c,v 2.133 2018/02/21 12:54:26 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*/
@@ -88,11 +88,14 @@
88#define dummynode (&dummynode_) 88#define dummynode (&dummynode_)
89 89
90static const Node dummynode_ = { 90static const Node dummynode_ = {
91 {{NULL}, LUA_TNIL, /* value's value and type */ 91 {{NULL}, LUA_TEMPTY, /* value's value and type */
92 LUA_TNIL, 0, {NULL}} /* key type, next, and key value */ 92 LUA_TNIL, 0, {NULL}} /* key type, next, and key value */
93}; 93};
94 94
95 95
96LUAI_DDEF const TValue luaH_emptyobject_ = {EMPTYCONSTANT};
97
98
96/* 99/*
97** Hash for floating-point numbers. 100** Hash for floating-point numbers.
98** The main computation should be just 101** The main computation should be just
@@ -200,7 +203,7 @@ static const TValue *getgeneric (Table *t, const TValue *key) {
200 else { 203 else {
201 int nx = gnext(n); 204 int nx = gnext(n);
202 if (nx == 0) 205 if (nx == 0)
203 return luaO_nilobject; /* not found */ 206 return luaH_emptyobject; /* not found */
204 n += nx; 207 n += nx;
205 } 208 }
206 } 209 }
@@ -232,7 +235,7 @@ static unsigned int findindex (lua_State *L, Table *t, TValue *key) {
232 return i; /* yes; that's the index */ 235 return i; /* yes; that's the index */
233 else { 236 else {
234 const TValue *n = getgeneric(t, key); 237 const TValue *n = getgeneric(t, key);
235 if (n == luaO_nilobject) 238 if (n == luaH_emptyobject)
236 luaG_runerror(L, "invalid key to 'next'"); /* key not found */ 239 luaG_runerror(L, "invalid key to 'next'"); /* key not found */
237 i = cast_int(nodefromval(n) - gnode(t, 0)); /* key index in hash table */ 240 i = cast_int(nodefromval(n) - gnode(t, 0)); /* key index in hash table */
238 /* hash elements are numbered after array ones */ 241 /* hash elements are numbered after array ones */
@@ -244,14 +247,14 @@ static unsigned int findindex (lua_State *L, Table *t, TValue *key) {
244int luaH_next (lua_State *L, Table *t, StkId key) { 247int luaH_next (lua_State *L, Table *t, StkId key) {
245 unsigned int i = findindex(L, t, s2v(key)); /* find original element */ 248 unsigned int i = findindex(L, t, s2v(key)); /* find original element */
246 for (; i < t->sizearray; i++) { /* try first array part */ 249 for (; i < t->sizearray; i++) { /* try first array part */
247 if (!ttisnil(&t->array[i])) { /* a non-nil value? */ 250 if (!isempty(&t->array[i])) { /* a non-empty entry? */
248 setivalue(s2v(key), i + 1); 251 setivalue(s2v(key), i + 1);
249 setobj2s(L, key + 1, &t->array[i]); 252 setobj2s(L, key + 1, &t->array[i]);
250 return 1; 253 return 1;
251 } 254 }
252 } 255 }
253 for (i -= t->sizearray; cast_int(i) < sizenode(t); i++) { /* hash part */ 256 for (i -= t->sizearray; cast_int(i) < sizenode(t); i++) { /* hash part */
254 if (!ttisnil(gval(gnode(t, i)))) { /* a non-nil value? */ 257 if (!isempty(gval(gnode(t, i)))) { /* a non-empty entry? */
255 Node *n = gnode(t, i); 258 Node *n = gnode(t, i);
256 getnodekey(L, s2v(key), n); 259 getnodekey(L, s2v(key), n);
257 setobj2s(L, key + 1, gval(n)); 260 setobj2s(L, key + 1, gval(n));
@@ -336,7 +339,7 @@ static unsigned int numusearray (const Table *t, unsigned int *nums) {
336 } 339 }
337 /* count elements in range (2^(lg - 1), 2^lg] */ 340 /* count elements in range (2^(lg - 1), 2^lg] */
338 for (; i <= lim; i++) { 341 for (; i <= lim; i++) {
339 if (!ttisnil(&t->array[i-1])) 342 if (!isempty(&t->array[i-1]))
340 lc++; 343 lc++;
341 } 344 }
342 nums[lg] += lc; 345 nums[lg] += lc;
@@ -352,7 +355,7 @@ static int numusehash (const Table *t, unsigned int *nums, unsigned int *pna) {
352 int i = sizenode(t); 355 int i = sizenode(t);
353 while (i--) { 356 while (i--) {
354 Node *n = &t->node[i]; 357 Node *n = &t->node[i];
355 if (!ttisnil(gval(n))) { 358 if (!isempty(gval(n))) {
356 if (keyisinteger(n)) 359 if (keyisinteger(n))
357 ause += countint(keyival(n), nums); 360 ause += countint(keyival(n), nums);
358 totaluse++; 361 totaluse++;
@@ -387,7 +390,7 @@ static void setnodevector (lua_State *L, Table *t, unsigned int size) {
387 Node *n = gnode(t, i); 390 Node *n = gnode(t, i);
388 gnext(n) = 0; 391 gnext(n) = 0;
389 setnilkey(n); 392 setnilkey(n);
390 setnilvalue(gval(n)); 393 setempty(gval(n));
391 } 394 }
392 t->lsizenode = cast_byte(lsize); 395 t->lsizenode = cast_byte(lsize);
393 t->lastfree = gnode(t, size); /* all positions are free */ 396 t->lastfree = gnode(t, size); /* all positions are free */
@@ -403,7 +406,7 @@ static void reinsert (lua_State *L, Table *ot, Table *t) {
403 int size = sizenode(ot); 406 int size = sizenode(ot);
404 for (j = 0; j < size; j++) { 407 for (j = 0; j < size; j++) {
405 Node *old = gnode(ot, j); 408 Node *old = gnode(ot, j);
406 if (!ttisnil(gval(old))) { 409 if (!isempty(gval(old))) {
407 /* doesn't need barrier/invalidate cache, as entry was 410 /* doesn't need barrier/invalidate cache, as entry was
408 already present in the table */ 411 already present in the table */
409 TValue k; 412 TValue k;
@@ -456,7 +459,7 @@ void luaH_resize (lua_State *L, Table *t, unsigned int newasize,
456 exchangehashpart(t, &newt); /* and new hash */ 459 exchangehashpart(t, &newt); /* and new hash */
457 /* re-insert into the new hash the elements from vanishing slice */ 460 /* re-insert into the new hash the elements from vanishing slice */
458 for (i = newasize; i < oldasize; i++) { 461 for (i = newasize; i < oldasize; i++) {
459 if (!ttisnil(&t->array[i])) 462 if (!isempty(&t->array[i]))
460 luaH_setint(L, t, i + 1, &t->array[i]); 463 luaH_setint(L, t, i + 1, &t->array[i]);
461 } 464 }
462 t->sizearray = oldasize; /* restore current size... */ 465 t->sizearray = oldasize; /* restore current size... */
@@ -473,7 +476,7 @@ void luaH_resize (lua_State *L, Table *t, unsigned int newasize,
473 t->array = newarray; /* set new array part */ 476 t->array = newarray; /* set new array part */
474 t->sizearray = newasize; 477 t->sizearray = newasize;
475 for (i = oldasize; i < newasize; i++) /* clear new slice of the array */ 478 for (i = oldasize; i < newasize; i++) /* clear new slice of the array */
476 setnilvalue(&t->array[i]); 479 setempty(&t->array[i]);
477 /* re-insert elements from old hash part into new parts */ 480 /* re-insert elements from old hash part into new parts */
478 reinsert(L, &newt, t); /* 'newt' now has the old hash */ 481 reinsert(L, &newt, t); /* 'newt' now has the old hash */
479 freehash(L, &newt); /* free old hash part */ 482 freehash(L, &newt); /* free old hash part */
@@ -569,7 +572,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
569 luaG_runerror(L, "table index is NaN"); 572 luaG_runerror(L, "table index is NaN");
570 } 573 }
571 mp = mainpositionTV(t, key); 574 mp = mainpositionTV(t, key);
572 if (!ttisnil(gval(mp)) || isdummy(t)) { /* main position is taken? */ 575 if (!isempty(gval(mp)) || isdummy(t)) { /* main position is taken? */
573 Node *othern; 576 Node *othern;
574 Node *f = getfreepos(t); /* get a free place */ 577 Node *f = getfreepos(t); /* get a free place */
575 if (f == NULL) { /* cannot find a free place? */ 578 if (f == NULL) { /* cannot find a free place? */
@@ -589,7 +592,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
589 gnext(f) += cast_int(mp - f); /* correct 'next' */ 592 gnext(f) += cast_int(mp - f); /* correct 'next' */
590 gnext(mp) = 0; /* now 'mp' is free */ 593 gnext(mp) = 0; /* now 'mp' is free */
591 } 594 }
592 setnilvalue(gval(mp)); 595 setempty(gval(mp));
593 } 596 }
594 else { /* colliding node is in its own main position */ 597 else { /* colliding node is in its own main position */
595 /* new node will go into free position */ 598 /* new node will go into free position */
@@ -602,7 +605,7 @@ TValue *luaH_newkey (lua_State *L, Table *t, const TValue *key) {
602 } 605 }
603 setnodekey(L, mp, key); 606 setnodekey(L, mp, key);
604 luaC_barrierback(L, obj2gco(t), key); 607 luaC_barrierback(L, obj2gco(t), key);
605 lua_assert(ttisnil(gval(mp))); 608 lua_assert(isempty(gval(mp)));
606 return gval(mp); 609 return gval(mp);
607} 610}
608 611
@@ -625,7 +628,7 @@ const TValue *luaH_getint (Table *t, lua_Integer key) {
625 n += nx; 628 n += nx;
626 } 629 }
627 } 630 }
628 return luaO_nilobject; 631 return luaH_emptyobject;
629 } 632 }
630} 633}
631 634
@@ -642,7 +645,7 @@ const TValue *luaH_getshortstr (Table *t, TString *key) {
642 else { 645 else {
643 int nx = gnext(n); 646 int nx = gnext(n);
644 if (nx == 0) 647 if (nx == 0)
645 return luaO_nilobject; /* not found */ 648 return luaH_emptyobject; /* not found */
646 n += nx; 649 n += nx;
647 } 650 }
648 } 651 }
@@ -667,7 +670,7 @@ const TValue *luaH_get (Table *t, const TValue *key) {
667 switch (ttype(key)) { 670 switch (ttype(key)) {
668 case LUA_TSHRSTR: return luaH_getshortstr(t, tsvalue(key)); 671 case LUA_TSHRSTR: return luaH_getshortstr(t, tsvalue(key));
669 case LUA_TNUMINT: return luaH_getint(t, ivalue(key)); 672 case LUA_TNUMINT: return luaH_getint(t, ivalue(key));
670 case LUA_TNIL: return luaO_nilobject; 673 case LUA_TNIL: return luaH_emptyobject;
671 case LUA_TNUMFLT: { 674 case LUA_TNUMFLT: {
672 lua_Integer k; 675 lua_Integer k;
673 if (luaV_flttointeger(fltvalue(key), &k, 0)) /* index is an integral? */ 676 if (luaV_flttointeger(fltvalue(key), &k, 0)) /* index is an integral? */
@@ -686,7 +689,7 @@ const TValue *luaH_get (Table *t, const TValue *key) {
686*/ 689*/
687TValue *luaH_set (lua_State *L, Table *t, const TValue *key) { 690TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
688 const TValue *p = luaH_get(t, key); 691 const TValue *p = luaH_get(t, key);
689 if (p != luaO_nilobject) 692 if (p != luaH_emptyobject)
690 return cast(TValue *, p); 693 return cast(TValue *, p);
691 else return luaH_newkey(L, t, key); 694 else return luaH_newkey(L, t, key);
692} 695}
@@ -695,7 +698,7 @@ TValue *luaH_set (lua_State *L, Table *t, const TValue *key) {
695void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { 698void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) {
696 const TValue *p = luaH_getint(t, key); 699 const TValue *p = luaH_getint(t, key);
697 TValue *cell; 700 TValue *cell;
698 if (p != luaO_nilobject) 701 if (p != luaH_emptyobject)
699 cell = cast(TValue *, p); 702 cell = cast(TValue *, p);
700 else { 703 else {
701 TValue k; 704 TValue k;
@@ -728,16 +731,16 @@ static lua_Unsigned hash_search (Table *t, lua_Unsigned j) {
728 j *= 2; 731 j *= 2;
729 else { 732 else {
730 j = LUA_MAXINTEGER; 733 j = LUA_MAXINTEGER;
731 if (ttisnil(luaH_getint(t, j))) /* t[j] == nil? */ 734 if (isempty(luaH_getint(t, j))) /* t[j] not present? */
732 break; /* 'j' now is an absent index */ 735 break; /* 'j' now is an absent index */
733 else /* weird case */ 736 else /* weird case */
734 return j; /* well, max integer is a boundary... */ 737 return j; /* well, max integer is a boundary... */
735 } 738 }
736 } while (!ttisnil(luaH_getint(t, j))); /* repeat until t[j] == nil */ 739 } while (!isempty(luaH_getint(t, j))); /* repeat until an absent t[j] */
737 /* i < j && t[i] !≃ nil && t[j] == nil */ 740 /* i < j && t[i] present && t[j] absent */
738 while (j - i > 1u) { /* do a binary search between them */ 741 while (j - i > 1u) { /* do a binary search between them */
739 lua_Unsigned m = (i + j) / 2; 742 lua_Unsigned m = (i + j) / 2;
740 if (ttisnil(luaH_getint(t, m))) j = m; 743 if (isempty(luaH_getint(t, m))) j = m;
741 else i = m; 744 else i = m;
742 } 745 }
743 return i; 746 return i;
@@ -746,27 +749,27 @@ static lua_Unsigned hash_search (Table *t, lua_Unsigned j) {
746 749
747/* 750/*
748** Try to find a boundary in table 't'. (A 'boundary' is an integer index 751** Try to find a boundary in table 't'. (A 'boundary' is an integer index
749** such that t[i] is non-nil and t[i+1] is nil, plus 0 if t[1] is nil 752** such that t[i] is present and t[i+1] is absent, or 0 if t[1] is absent
750** and 'maxinteger' if t[maxinteger] is not nil.) 753** and 'maxinteger' if t[maxinteger] is present.)
751** First, try the array part: if there is an array part and its last 754** First, try the array part: if there is an array part and its last
752** element is nil, there must be a boundary there; a binary search 755** element is absent, there must be a boundary there; a binary search
753** finds that boundary. Otherwise, if the hash part is empty or does not 756** finds that boundary. Otherwise, if the hash part is empty or does not
754** contain 'j + 1', 'j' is a boundary. Otherwize, call 'hash_search' 757** contain 'j + 1', 'j' is a boundary. Otherwize, call 'hash_search'
755** to find a boundary in the hash part. 758** to find a boundary in the hash part.
756*/ 759*/
757lua_Unsigned luaH_getn (Table *t) { 760lua_Unsigned luaH_getn (Table *t) {
758 unsigned int j = t->sizearray; 761 unsigned int j = t->sizearray;
759 if (j > 0 && ttisnil(&t->array[j - 1])) { 762 if (j > 0 && isempty(&t->array[j - 1])) {
760 unsigned int i = 0; 763 unsigned int i = 0;
761 while (j - i > 1u) { /* binary search */ 764 while (j - i > 1u) { /* binary search */
762 unsigned int m = (i + j) / 2; 765 unsigned int m = (i + j) / 2;
763 if (ttisnil(&t->array[m - 1])) j = m; 766 if (isempty(&t->array[m - 1])) j = m;
764 else i = m; 767 else i = m;
765 } 768 }
766 return i; 769 return i;
767 } 770 }
768 else { /* 'j' is zero or present in table */ 771 else { /* 'j' is zero or present in table */
769 if (isdummy(t) || ttisnil(luaH_getint(t, l_castU2S(j + 1)))) 772 if (isdummy(t) || isempty(luaH_getint(t, l_castU2S(j + 1))))
770 return j; /* 'j + 1' is absent... */ 773 return j; /* 'j + 1' is absent... */
771 else /* 'j + 1' is also present */ 774 else /* 'j + 1' is also present */
772 return hash_search(t, j); 775 return hash_search(t, j);