aboutsummaryrefslogtreecommitdiff
path: root/ltable.c
diff options
context:
space:
mode:
Diffstat (limited to 'ltable.c')
-rw-r--r--ltable.c46
1 files changed, 27 insertions, 19 deletions
diff --git a/ltable.c b/ltable.c
index c9f66b3c..d3e90696 100644
--- a/ltable.c
+++ b/ltable.c
@@ -541,29 +541,28 @@ static int numusehash (const Table *t, unsigned int *nums, unsigned int *pna) {
541 541
542 542
543/* 543/*
544** Convert an "abstract size" (number of values in an array) to 544** Convert an "abstract size" (number of slots in an array) to
545** "concrete size" (number of cell elements in the array). Cells 545** "concrete size" (number of bytes in the array).
546** do not need to be full; we only must make sure it has the values 546** If the abstract size is not a multiple of NM, the last cell is
547** needed and its 'tag' element. So, we compute the concrete tag index 547** incomplete, so we don't need to allocate memory for the whole cell.
548** and the concrete value index of the last element, get their maximum 548** 'extra' computes how many values are not needed in that last cell.
549** and adds 1. 549** It will be zero when 'size' is a multiple of NM, and from there it
550** increases as 'size' decreases, up to (NM - 1).
550*/ 551*/
551static unsigned int concretesize (unsigned int size) { 552static size_t concretesize (unsigned int size) {
552 if (size == 0) return 0; 553 unsigned int numcells = (size + NM - 1) / NM; /* (size / NM) rounded up */
553 else { 554 unsigned int extra = NM - 1 - ((size + NM - 1) % NM);
554 unsigned int ts = TagIndex(size - 1); 555 return numcells * sizeof(ArrayCell) - extra * sizeof(Value);
555 unsigned int vs = ValueIndex(size - 1);
556 return ((ts >= vs) ? ts : vs) + 1;
557 }
558} 556}
559 557
560 558
561static ArrayCell *resizearray (lua_State *L , Table *t, 559static ArrayCell *resizearray (lua_State *L , Table *t,
562 unsigned int oldasize, 560 unsigned int oldasize,
563 unsigned int newasize) { 561 unsigned int newasize) {
564 oldasize = concretesize(oldasize); 562 size_t oldasizeb = concretesize(oldasize);
565 newasize = concretesize(newasize); 563 size_t newasizeb = concretesize(newasize);
566 return luaM_reallocvector(L, t->array, oldasize, newasize, ArrayCell); 564 void *a = luaM_reallocvector(L, t->array, oldasizeb, newasizeb, lu_byte);
565 return cast(ArrayCell*, a);
567} 566}
568 567
569 568
@@ -747,10 +746,19 @@ Table *luaH_new (lua_State *L) {
747} 746}
748 747
749 748
749/*
750** Frees a table. The assert ensures the correctness of 'concretesize',
751** checking its result against the address of the last element in the
752** array part of the table, computed abstractly.
753*/
750void luaH_free (lua_State *L, Table *t) { 754void luaH_free (lua_State *L, Table *t) {
751 unsigned ps = concretesize(luaH_realasize(t)); 755 unsigned int realsize = luaH_realasize(t);
756 size_t sizeb = concretesize(realsize);
757 lua_assert((sizeb == 0 && realsize == 0) ||
758 cast_charp(t->array) + sizeb - sizeof(Value) ==
759 cast_charp(getArrVal(t, realsize - 1)));
752 freehash(L, t); 760 freehash(L, t);
753 luaM_freearray(L, t->array, ps); 761 luaM_freemem(L, t->array, sizeb);
754 luaM_free(L, t); 762 luaM_free(L, t);
755} 763}
756 764
@@ -944,7 +952,7 @@ TString *luaH_getstrkey (Table *t, TString *key) {
944** main search function 952** main search function
945*/ 953*/
946int luaH_get (Table *t, const TValue *key, TValue *res) { 954int luaH_get (Table *t, const TValue *key, TValue *res) {
947 const TValue *slot; 955 const TValue *slot;
948 switch (ttypetag(key)) { 956 switch (ttypetag(key)) {
949 case LUA_VSHRSTR: 957 case LUA_VSHRSTR:
950 slot = luaH_Hgetshortstr(t, tsvalue(key)); 958 slot = luaH_Hgetshortstr(t, tsvalue(key));