aboutsummaryrefslogtreecommitdiff
path: root/ltable.c
diff options
context:
space:
mode:
Diffstat (limited to 'ltable.c')
-rw-r--r--ltable.c46
1 files changed, 37 insertions, 9 deletions
diff --git a/ltable.c b/ltable.c
index ddda9a44..b7362a36 100644
--- a/ltable.c
+++ b/ltable.c
@@ -350,7 +350,7 @@ int luaH_next (lua_State *L, Table *t, StkId key) {
350 unsigned int asize = luaH_realasize(t); 350 unsigned int asize = luaH_realasize(t);
351 unsigned int i = findindex(L, t, s2v(key), asize); /* find original key */ 351 unsigned int i = findindex(L, t, s2v(key), asize); /* find original key */
352 for (; i < asize; i++) { /* try first array part */ 352 for (; i < asize; i++) { /* try first array part */
353 int tag = *getArrTag(t, i + 1); 353 int tag = *getArrTag(t, i);
354 if (!tagisempty(tag)) { /* a non-empty entry? */ 354 if (!tagisempty(tag)) { /* a non-empty entry? */
355 setivalue(s2v(key), i + 1); 355 setivalue(s2v(key), i + 1);
356 farr2val(t, i + 1, tag, s2v(key + 1)); 356 farr2val(t, i + 1, tag, s2v(key + 1));
@@ -458,7 +458,7 @@ static int countint (lua_Integer key, unsigned int *nums) {
458 458
459 459
460l_sinline int arraykeyisempty (const Table *t, lua_Integer key) { 460l_sinline int arraykeyisempty (const Table *t, lua_Integer key) {
461 int tag = *getArrTag(t, key); 461 int tag = *getArrTag(t, key - 1);
462 return tagisempty(tag); 462 return tagisempty(tag);
463} 463}
464 464
@@ -513,6 +513,33 @@ static int numusehash (const Table *t, unsigned int *nums, unsigned int *pna) {
513 513
514 514
515/* 515/*
516** Convert an "abstract size" (number of values in an array) to
517** "concrete size" (number of cell elements in the array). Cells
518** do not need to be full; we only must make sure it has the values
519** needed and its 'tag' element. So, we compute the concrete tag index
520** and the concrete value index of the last element, get their maximum
521** and adds 1.
522*/
523static unsigned int concretesize (unsigned int size) {
524 if (size == 0) return 0;
525 else {
526 unsigned int ts = TagIndex(size - 1);
527 unsigned int vs = ValueIndex(size - 1);
528 return ((ts >= vs) ? ts : vs) + 1;
529 }
530}
531
532
533static ArrayCell *resizearray (lua_State *L , Table *t,
534 unsigned int oldasize,
535 unsigned int newasize) {
536 oldasize = concretesize(oldasize);
537 newasize = concretesize(newasize);
538 return luaM_reallocvector(L, t->array, oldasize, newasize, ArrayCell);
539}
540
541
542/*
516** Creates an array for the hash part of a table with the given 543** Creates an array for the hash part of a table with the given
517** size, or reuses the dummy node if size is zero. 544** size, or reuses the dummy node if size is zero.
518** The computation for size overflow is in two steps: the first 545** The computation for size overflow is in two steps: the first
@@ -605,7 +632,7 @@ void luaH_resize (lua_State *L, Table *t, unsigned int newasize,
605 exchangehashpart(t, &newt); /* and new hash */ 632 exchangehashpart(t, &newt); /* and new hash */
606 /* re-insert into the new hash the elements from vanishing slice */ 633 /* re-insert into the new hash the elements from vanishing slice */
607 for (i = newasize; i < oldasize; i++) { 634 for (i = newasize; i < oldasize; i++) {
608 int tag = *getArrTag(t, i + 1); 635 int tag = *getArrTag(t, i);
609 if (!tagisempty(tag)) { /* a non-empty entry? */ 636 if (!tagisempty(tag)) { /* a non-empty entry? */
610 TValue aux; 637 TValue aux;
611 farr2val(t, i + 1, tag, &aux); 638 farr2val(t, i + 1, tag, &aux);
@@ -616,7 +643,7 @@ void luaH_resize (lua_State *L, Table *t, unsigned int newasize,
616 exchangehashpart(t, &newt); /* and hash (in case of errors) */ 643 exchangehashpart(t, &newt); /* and hash (in case of errors) */
617 } 644 }
618 /* allocate new array */ 645 /* allocate new array */
619 newarray = luaM_reallocvector(L, t->array, oldasize, newasize, ArrayCell); 646 newarray = resizearray(L, t, oldasize, newasize);
620 if (l_unlikely(newarray == NULL && newasize > 0)) { /* allocation failed? */ 647 if (l_unlikely(newarray == NULL && newasize > 0)) { /* allocation failed? */
621 freehash(L, &newt); /* release new hash part */ 648 freehash(L, &newt); /* release new hash part */
622 luaM_error(L); /* raise error (with array unchanged) */ 649 luaM_error(L); /* raise error (with array unchanged) */
@@ -626,7 +653,7 @@ void luaH_resize (lua_State *L, Table *t, unsigned int newasize,
626 t->array = newarray; /* set new array part */ 653 t->array = newarray; /* set new array part */
627 t->alimit = newasize; 654 t->alimit = newasize;
628 for (i = oldasize; i < newasize; i++) /* clear new slice of the array */ 655 for (i = oldasize; i < newasize; i++) /* clear new slice of the array */
629 *getArrTag(t, i + 1) = LUA_VEMPTY; 656 *getArrTag(t, i) = LUA_VEMPTY;
630 /* re-insert elements from old hash part into new parts */ 657 /* re-insert elements from old hash part into new parts */
631 reinsert(L, &newt, t); /* 'newt' now has the old hash */ 658 reinsert(L, &newt, t); /* 'newt' now has the old hash */
632 freehash(L, &newt); /* free old hash part */ 659 freehash(L, &newt); /* free old hash part */
@@ -682,8 +709,9 @@ Table *luaH_new (lua_State *L) {
682 709
683 710
684void luaH_free (lua_State *L, Table *t) { 711void luaH_free (lua_State *L, Table *t) {
712 unsigned ps = concretesize(luaH_realasize(t));
685 freehash(L, t); 713 freehash(L, t);
686 luaM_freearray(L, t->array, luaH_realasize(t)); 714 luaM_freearray(L, t->array, ps);
687 luaM_free(L, t); 715 luaM_free(L, t);
688} 716}
689 717
@@ -799,7 +827,7 @@ static int finishnodeget (const TValue *val, TValue *res) {
799 827
800int luaH_getint (Table *t, lua_Integer key, TValue *res) { 828int luaH_getint (Table *t, lua_Integer key, TValue *res) {
801 if (keyinarray(t, key)) { 829 if (keyinarray(t, key)) {
802 int tag = *getArrTag(t, key); 830 int tag = *getArrTag(t, key - 1);
803 if (!tagisempty(tag)) { 831 if (!tagisempty(tag)) {
804 farr2val(t, key, tag, res); 832 farr2val(t, key, tag, res);
805 return HOK; /* success */ 833 return HOK; /* success */
@@ -902,7 +930,7 @@ static int finishnodeset (Table *t, const TValue *slot, TValue *val) {
902 930
903int luaH_psetint (Table *t, lua_Integer key, TValue *val) { 931int luaH_psetint (Table *t, lua_Integer key, TValue *val) {
904 if (keyinarray(t, key)) { 932 if (keyinarray(t, key)) {
905 lu_byte *tag = getArrTag(t, key); 933 lu_byte *tag = getArrTag(t, key - 1);
906 if (!tagisempty(*tag)) { 934 if (!tagisempty(*tag)) {
907 fval2arr(t, key, tag, val); 935 fval2arr(t, key, tag, val);
908 return HOK; /* success */ 936 return HOK; /* success */
@@ -960,7 +988,7 @@ void luaH_finishset (lua_State *L, Table *t, const TValue *key,
960 } 988 }
961 else { /* array entry */ 989 else { /* array entry */
962 hres = ~hres; /* real index */ 990 hres = ~hres; /* real index */
963 fval2arr(t, hres, getArrTag(t, hres), value); 991 obj2arr(t, hres, value);
964 } 992 }
965} 993}
966 994