** Resize table 't' for the new given sizes. Both allocations (for ** the hash part and for the array part) can fail, which creates some ** subtleties. If the first allocation, for the hash part, fails, an ** error is raised and that is it. Otherwise, it copies the elements from ** the shrinking part of the array (if it is shrinking) into the new ** hash. Then it reallocates the array part. If th
| 551 | ** parts of the table. |
| 552 | */ |
| 553 | void luaH_resize (lua_State *L, Table *t, unsigned int newasize, |
| 554 | unsigned int nhsize) { |
| 555 | unsigned int i; |
| 556 | Table newt; /* to keep the new hash part */ |
| 557 | unsigned int oldasize = setlimittosize(t); |
| 558 | TValue *newarray; |
| 559 | /* create new hash part with appropriate size into 'newt' */ |
| 560 | setnodevector(L, &newt, nhsize); |
| 561 | if (newasize < oldasize) { /* will array shrink? */ |
| 562 | t->alimit = newasize; /* pretend array has new size... */ |
| 563 | exchangehashpart(t, &newt); /* and new hash */ |
| 564 | /* re-insert into the new hash the elements from vanishing slice */ |
| 565 | for (i = newasize; i < oldasize; i++) { |
| 566 | if (!isempty(&t->array[i])) |
| 567 | luaH_setint(L, t, i + 1, &t->array[i]); |
| 568 | } |
| 569 | t->alimit = oldasize; /* restore current size... */ |
| 570 | exchangehashpart(t, &newt); /* and hash (in case of errors) */ |
| 571 | } |
| 572 | /* allocate new array */ |
| 573 | newarray = luaM_reallocvector(L, t->array, oldasize, newasize, TValue); |
| 574 | if (l_unlikely(newarray == NULL && newasize > 0)) { /* allocation failed? */ |
| 575 | freehash(L, &newt); /* release new hash part */ |
| 576 | luaM_error(L); /* raise error (with array unchanged) */ |
| 577 | } |
| 578 | /* allocation ok; initialize new part of the array */ |
| 579 | exchangehashpart(t, &newt); /* 't' has the new hash ('newt' has the old) */ |
| 580 | t->array = newarray; /* set new array part */ |
| 581 | t->alimit = newasize; |
| 582 | for (i = oldasize; i < newasize; i++) /* clear new slice of the array */ |
| 583 | setempty(&t->array[i]); |
| 584 | /* re-insert elements from old hash part into new parts */ |
| 585 | reinsert(L, &newt, t); /* 'newt' now has the old hash */ |
| 586 | freehash(L, &newt); /* free old hash part */ |
| 587 | } |
| 588 | |
| 589 | |
| 590 | void luaH_resizearray (lua_State *L, Table *t, unsigned int nasize) { |
no test coverage detected