diff options
Diffstat (limited to 'ltable.c')
-rw-r--r-- | ltable.c | 35 |
1 files changed, 27 insertions, 8 deletions
@@ -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 | ||
335 | typedef struct { | ||
336 | Table *t; | ||
337 | unsigned int nhsize; | ||
338 | } AuxsetnodeT; | ||
339 | |||
340 | |||
341 | static void auxsetnode (lua_State *L, void *ud) { | ||
342 | AuxsetnodeT *asn = cast(AuxsetnodeT *, ud); | ||
343 | setnodevector(L, asn->t, asn->nhsize); | ||
344 | } | ||
345 | |||
346 | |||
333 | void luaH_resize (lua_State *L, Table *t, unsigned int nasize, | 347 | void 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 | ||
613 | static int unbound_search (Table *t, unsigned int j) { | 632 | static 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 | */ |
641 | int luaH_getn (Table *t) { | 660 | lua_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 */ |