diff --git a/ltable.c b/ltable.c index e969adef..40a4683f 100644 --- a/ltable.c +++ b/ltable.c @@ -384,7 +384,7 @@ int luaH_next (lua_State *L, Table *t, StkId key) { int tag = *getArrTag(t, i); if (!tagisempty(tag)) { /* a non-empty entry? */ setivalue(s2v(key), i + 1); - farr2val(t, i + 1, tag, s2v(key + 1)); + farr2val(t, i, tag, s2v(key + 1)); return 1; } } @@ -692,7 +692,7 @@ static void reinsertOldSlice (lua_State *L, Table *t, unsigned oldasize, int tag = *getArrTag(t, i); if (!tagisempty(tag)) { /* a non-empty entry? */ TValue aux; - farr2val(t, i + 1, tag, &aux); /* copy entry into 'aux' */ + farr2val(t, i, tag, &aux); /* copy entry into 'aux' */ luaH_setint(L, t, i + 1, &aux); /* re-insert it into the table */ } } @@ -937,7 +937,7 @@ int luaH_getint (Table *t, lua_Integer key, TValue *res) { if (keyinarray(t, key)) { int tag = *getArrTag(t, key - 1); if (!tagisempty(tag)) - farr2val(t, key, tag, res); + farr2val(t, key - 1, tag, res); return tag; } else @@ -1048,11 +1048,11 @@ int luaH_psetint (Table *t, lua_Integer key, TValue *val) { if (keyinarray(t, key)) { lu_byte *tag = getArrTag(t, key - 1); if (!tagisempty(*tag) || checknoTM(t->metatable, TM_NEWINDEX)) { - fval2arr(t, key, tag, val); + fval2arr(t, key - 1, tag, val); return HOK; /* success */ } else - return ~cast_int(key); /* empty slot in the array part */ + return ~cast_int(key - 1); /* empty slot in the array part */ } else return finishnodeset(t, getintfromhash(t, key), val); @@ -1126,7 +1126,7 @@ void luaH_set (lua_State *L, Table *t, const TValue *key, TValue *value) { */ void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { if (keyinarray(t, key)) - obj2arr(t, key, value); + obj2arr(t, key - 1, value); else { int ok = rawfinishnodeset(getintfromhash(t, key), value); if (!ok) { diff --git a/ltable.h b/ltable.h index 6db197ba..2e7f86fd 100644 --- a/ltable.h +++ b/ltable.h @@ -47,20 +47,20 @@ #define luaH_fastgeti(t,k,res,tag) \ - { Table *h = t; lua_Unsigned u = l_castS2U(k); \ - if ((u - 1u < h->alimit)) { \ - tag = *getArrTag(h,(u)-1u); \ + { Table *h = t; lua_Unsigned u = l_castS2U(k) - 1u; \ + if ((u < h->alimit)) { \ + tag = *getArrTag(h, u); \ if (!tagisempty(tag)) { farr2val(h, u, tag, res); }} \ - else { tag = luaH_getint(h, u, res); }} + else { tag = luaH_getint(h, (k), res); }} #define luaH_fastseti(t,k,val,hres) \ - { Table *h = t; lua_Unsigned u = l_castS2U(k); \ - if ((u - 1u < h->alimit)) { \ - lu_byte *tag = getArrTag(h,(u)-1u); \ + { Table *h = t; lua_Unsigned u = l_castS2U(k) - 1u; \ + if ((u < h->alimit)) { \ + lu_byte *tag = getArrTag(h, u); \ if (tagisempty(*tag)) hres = ~cast_int(u); \ else { fval2arr(h, u, tag, val); hres = HOK; }} \ - else { hres = luaH_psetint(h, u, val); }} + else { hres = luaH_psetint(h, k, val); }} /* results from pset */ @@ -82,6 +82,12 @@ ** in the array part, the encoding is (~array index), a negative value. ** The value HNOTATABLE is used by the fast macros to signal that the ** value being indexed is not a table. +** (The size for the array part is limited by the maximum power of two +** that fits in an unsigned integer; that is INT_MAX+1. So, the C-index +** ranges from 0, which encodes to -1, to INT_MAX, which encodes to +** INT_MIN. The size of the hash part is limited by the maximum power of +** two that fits in a signed integer; that is (INT_MAX+1)/2. So, it is +** safe to add HFIRSTNODE to any index there.) */ @@ -102,21 +108,21 @@ ** and 'getArrVal'. */ -/* Computes the address of the tag for the abstract index 'k' */ +/* Computes the address of the tag for the abstract C-index 'k' */ #define getArrTag(t,k) (cast(lu_byte*, (t)->array) + (k)) -/* Computes the address of the value for the abstract index 'k' */ +/* Computes the address of the value for the abstract C-index 'k' */ #define getArrVal(t,k) ((t)->array - 1 - (k)) /* -** Move TValues to/from arrays, using Lua indices +** Move TValues to/from arrays, using C indices */ #define arr2obj(h,k,val) \ - ((val)->tt_ = *getArrTag(h,(k)-1u), (val)->value_ = *getArrVal(h,(k)-1u)) + ((val)->tt_ = *getArrTag(h,(k)), (val)->value_ = *getArrVal(h,(k))) #define obj2arr(h,k,val) \ - (*getArrTag(h,(k)-1u) = (val)->tt_, *getArrVal(h,(k)-1u) = (val)->value_) + (*getArrTag(h,(k)) = (val)->tt_, *getArrVal(h,(k)) = (val)->value_) /* @@ -125,10 +131,10 @@ ** precomputed tag value or address as an extra argument. */ #define farr2val(h,k,tag,res) \ - ((res)->tt_ = tag, (res)->value_ = *getArrVal(h,(k)-1u)) + ((res)->tt_ = tag, (res)->value_ = *getArrVal(h,(k))) #define fval2arr(h,k,tag,val) \ - (*tag = (val)->tt_, *getArrVal(h,(k)-1u) = (val)->value_) + (*tag = (val)->tt_, *getArrVal(h,(k)) = (val)->value_) LUAI_FUNC int luaH_get (Table *t, const TValue *key, TValue *res); diff --git a/ltests.c b/ltests.c index 4780673e..57df10e1 100644 --- a/ltests.c +++ b/ltests.c @@ -365,7 +365,7 @@ static void checktable (global_State *g, Table *h) { checkobjrefN(g, hgc, h->metatable); for (i = 0; i < asize; i++) { TValue aux; - arr2obj(h, i + 1, &aux); + arr2obj(h, i, &aux); checkvalref(g, hgc, &aux); } for (n = gnode(h, 0); n < limit; n++) { @@ -1010,7 +1010,7 @@ static int table_query (lua_State *L) { } else if (cast_uint(i) < asize) { lua_pushinteger(L, i); - arr2obj(t, i + 1, s2v(L->top.p)); + arr2obj(t, i, s2v(L->top.p)); api_incr_top(L); lua_pushnil(L); } diff --git a/lvm.c b/lvm.c index 88f8fe27..7ee5f6bc 100644 --- a/lvm.c +++ b/lvm.c @@ -1857,7 +1857,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { luaH_resizearray(L, h, last); /* preallocate it at once */ for (; n > 0; n--) { TValue *val = s2v(ra + n); - obj2arr(h, last, val); + obj2arr(h, last - 1, val); last--; luaC_barrierback(L, obj2gco(h), val); }