summaryrefslogtreecommitdiff
path: root/ltable.c
diff options
context:
space:
mode:
Diffstat (limited to 'ltable.c')
-rw-r--r--ltable.c35
1 files changed, 27 insertions, 8 deletions
diff --git a/ltable.c b/ltable.c
index 92c165ad..ea4fe7fc 100644
--- a/ltable.c
+++ b/ltable.c
@@ -1,5 +1,5 @@
1/* 1/*
2** $Id: ltable.c,v 2.117 2015/11/19 19:16:22 roberto Exp roberto $ 2** $Id: ltable.c,v 2.118.1.4 2018/06/08 16:22:51 roberto Exp $
3** Lua tables (hash) 3** Lua tables (hash)
4** See Copyright Notice in lua.h 4** See Copyright Notice in lua.h
5*/ 5*/
@@ -223,7 +223,9 @@ static unsigned int computesizes (unsigned int nums[], unsigned int *pna) {
223 unsigned int na = 0; /* number of elements to go to array part */ 223 unsigned int na = 0; /* number of elements to go to array part */
224 unsigned int optimal = 0; /* optimal size for array part */ 224 unsigned int optimal = 0; /* optimal size for array part */
225 /* loop while keys can fill more than half of total size */ 225 /* loop while keys can fill more than half of total size */
226 for (i = 0, twotoi = 1; *pna > twotoi / 2; i++, twotoi *= 2) { 226 for (i = 0, twotoi = 1;
227 twotoi > 0 && *pna > twotoi / 2;
228 i++, twotoi *= 2) {
227 if (nums[i] > 0) { 229 if (nums[i] > 0) {
228 a += nums[i]; 230 a += nums[i];
229 if (a > twotoi/2) { /* more than half elements present? */ 231 if (a > twotoi/2) { /* more than half elements present? */
@@ -330,17 +332,34 @@ static void setnodevector (lua_State *L, Table *t, unsigned int size) {
330} 332}
331 333
332 334
335typedef struct {
336 Table *t;
337 unsigned int nhsize;
338} AuxsetnodeT;
339
340
341static void auxsetnode (lua_State *L, void *ud) {
342 AuxsetnodeT *asn = cast(AuxsetnodeT *, ud);
343 setnodevector(L, asn->t, asn->nhsize);
344}
345
346
333void luaH_resize (lua_State *L, Table *t, unsigned int nasize, 347void luaH_resize (lua_State *L, Table *t, unsigned int nasize,
334 unsigned int nhsize) { 348 unsigned int nhsize) {
335 unsigned int i; 349 unsigned int i;
336 int j; 350 int j;
351 AuxsetnodeT asn;
337 unsigned int oldasize = t->sizearray; 352 unsigned int oldasize = t->sizearray;
338 int oldhsize = allocsizenode(t); 353 int oldhsize = allocsizenode(t);
339 Node *nold = t->node; /* save old hash ... */ 354 Node *nold = t->node; /* save old hash ... */
340 if (nasize > oldasize) /* array part must grow? */ 355 if (nasize > oldasize) /* array part must grow? */
341 setarrayvector(L, t, nasize); 356 setarrayvector(L, t, nasize);
342 /* create new hash part with appropriate size */ 357 /* create new hash part with appropriate size */
343 setnodevector(L, t, nhsize); 358 asn.t = t; asn.nhsize = nhsize;
359 if (luaD_rawrunprotected(L, auxsetnode, &asn) != LUA_OK) { /* mem. error? */
360 setarrayvector(L, t, oldasize); /* array back to its original size */
361 luaD_throw(L, LUA_ERRMEM); /* rethrow memory error */
362 }
344 if (nasize < oldasize) { /* array part must shrink? */ 363 if (nasize < oldasize) { /* array part must shrink? */
345 t->sizearray = nasize; 364 t->sizearray = nasize;
346 /* re-insert elements from vanishing slice */ 365 /* re-insert elements from vanishing slice */
@@ -610,13 +629,13 @@ void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) {
610} 629}
611 630
612 631
613static int unbound_search (Table *t, unsigned int j) { 632static lua_Unsigned unbound_search (Table *t, lua_Unsigned j) {
614 unsigned int i = j; /* i is zero or a present index */ 633 lua_Unsigned i = j; /* i is zero or a present index */
615 j++; 634 j++;
616 /* find 'i' and 'j' such that i is present and j is not */ 635 /* find 'i' and 'j' such that i is present and j is not */
617 while (!ttisnil(luaH_getint(t, j))) { 636 while (!ttisnil(luaH_getint(t, j))) {
618 i = j; 637 i = j;
619 if (j > cast(unsigned int, MAX_INT)/2) { /* overflow? */ 638 if (j > l_castS2U(LUA_MAXINTEGER) / 2) { /* overflow? */
620 /* table was built with bad purposes: resort to linear search */ 639 /* table was built with bad purposes: resort to linear search */
621 i = 1; 640 i = 1;
622 while (!ttisnil(luaH_getint(t, i))) i++; 641 while (!ttisnil(luaH_getint(t, i))) i++;
@@ -626,7 +645,7 @@ static int unbound_search (Table *t, unsigned int j) {
626 } 645 }
627 /* now do a binary search between them */ 646 /* now do a binary search between them */
628 while (j - i > 1) { 647 while (j - i > 1) {
629 unsigned int m = (i+j)/2; 648 lua_Unsigned m = (i+j)/2;
630 if (ttisnil(luaH_getint(t, m))) j = m; 649 if (ttisnil(luaH_getint(t, m))) j = m;
631 else i = m; 650 else i = m;
632 } 651 }
@@ -638,7 +657,7 @@ static int unbound_search (Table *t, unsigned int j) {
638** Try to find a boundary in table 't'. A 'boundary' is an integer index 657** Try to find a boundary in table 't'. A 'boundary' is an integer index
639** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil). 658** such that t[i] is non-nil and t[i+1] is nil (and 0 if t[1] is nil).
640*/ 659*/
641int luaH_getn (Table *t) { 660lua_Unsigned luaH_getn (Table *t) {
642 unsigned int j = t->sizearray; 661 unsigned int j = t->sizearray;
643 if (j > 0 && ttisnil(&t->array[j - 1])) { 662 if (j > 0 && ttisnil(&t->array[j - 1])) {
644 /* there is a boundary in the array part: (binary) search for it */ 663 /* there is a boundary in the array part: (binary) search for it */