Skip to content

Commit 94b503d

Browse files
committed
Encoding of table indices (hres) must use C indices
As the encoding of array indices is (~index), 0 is encoded as -1 and INT_MAX is encoded as INT_MIN.
1 parent bdc8535 commit 94b503d

4 files changed

Lines changed: 30 additions & 24 deletions

File tree

ltable.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -384,7 +384,7 @@ int luaH_next (lua_State *L, Table *t, StkId key) {
384384
int tag = *getArrTag(t, i);
385385
if (!tagisempty(tag)) { /* a non-empty entry? */
386386
setivalue(s2v(key), i + 1);
387-
farr2val(t, i + 1, tag, s2v(key + 1));
387+
farr2val(t, i, tag, s2v(key + 1));
388388
return 1;
389389
}
390390
}
@@ -692,7 +692,7 @@ static void reinsertOldSlice (lua_State *L, Table *t, unsigned oldasize,
692692
int tag = *getArrTag(t, i);
693693
if (!tagisempty(tag)) { /* a non-empty entry? */
694694
TValue aux;
695-
farr2val(t, i + 1, tag, &aux); /* copy entry into 'aux' */
695+
farr2val(t, i, tag, &aux); /* copy entry into 'aux' */
696696
luaH_setint(L, t, i + 1, &aux); /* re-insert it into the table */
697697
}
698698
}
@@ -937,7 +937,7 @@ int luaH_getint (Table *t, lua_Integer key, TValue *res) {
937937
if (keyinarray(t, key)) {
938938
int tag = *getArrTag(t, key - 1);
939939
if (!tagisempty(tag))
940-
farr2val(t, key, tag, res);
940+
farr2val(t, key - 1, tag, res);
941941
return tag;
942942
}
943943
else
@@ -1048,11 +1048,11 @@ int luaH_psetint (Table *t, lua_Integer key, TValue *val) {
10481048
if (keyinarray(t, key)) {
10491049
lu_byte *tag = getArrTag(t, key - 1);
10501050
if (!tagisempty(*tag) || checknoTM(t->metatable, TM_NEWINDEX)) {
1051-
fval2arr(t, key, tag, val);
1051+
fval2arr(t, key - 1, tag, val);
10521052
return HOK; /* success */
10531053
}
10541054
else
1055-
return ~cast_int(key); /* empty slot in the array part */
1055+
return ~cast_int(key - 1); /* empty slot in the array part */
10561056
}
10571057
else
10581058
return finishnodeset(t, getintfromhash(t, key), val);
@@ -1126,7 +1126,7 @@ void luaH_set (lua_State *L, Table *t, const TValue *key, TValue *value) {
11261126
*/
11271127
void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) {
11281128
if (keyinarray(t, key))
1129-
obj2arr(t, key, value);
1129+
obj2arr(t, key - 1, value);
11301130
else {
11311131
int ok = rawfinishnodeset(getintfromhash(t, key), value);
11321132
if (!ok) {

ltable.h

Lines changed: 21 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -47,20 +47,20 @@
4747

4848

4949
#define luaH_fastgeti(t,k,res,tag) \
50-
{ Table *h = t; lua_Unsigned u = l_castS2U(k); \
51-
if ((u - 1u < h->alimit)) { \
52-
tag = *getArrTag(h,(u)-1u); \
50+
{ Table *h = t; lua_Unsigned u = l_castS2U(k) - 1u; \
51+
if ((u < h->alimit)) { \
52+
tag = *getArrTag(h, u); \
5353
if (!tagisempty(tag)) { farr2val(h, u, tag, res); }} \
54-
else { tag = luaH_getint(h, u, res); }}
54+
else { tag = luaH_getint(h, (k), res); }}
5555

5656

5757
#define luaH_fastseti(t,k,val,hres) \
58-
{ Table *h = t; lua_Unsigned u = l_castS2U(k); \
59-
if ((u - 1u < h->alimit)) { \
60-
lu_byte *tag = getArrTag(h,(u)-1u); \
58+
{ Table *h = t; lua_Unsigned u = l_castS2U(k) - 1u; \
59+
if ((u < h->alimit)) { \
60+
lu_byte *tag = getArrTag(h, u); \
6161
if (tagisempty(*tag)) hres = ~cast_int(u); \
6262
else { fval2arr(h, u, tag, val); hres = HOK; }} \
63-
else { hres = luaH_psetint(h, u, val); }}
63+
else { hres = luaH_psetint(h, k, val); }}
6464

6565

6666
/* results from pset */
@@ -82,6 +82,12 @@
8282
** in the array part, the encoding is (~array index), a negative value.
8383
** The value HNOTATABLE is used by the fast macros to signal that the
8484
** value being indexed is not a table.
85+
** (The size for the array part is limited by the maximum power of two
86+
** that fits in an unsigned integer; that is INT_MAX+1. So, the C-index
87+
** ranges from 0, which encodes to -1, to INT_MAX, which encodes to
88+
** INT_MIN. The size of the hash part is limited by the maximum power of
89+
** two that fits in a signed integer; that is (INT_MAX+1)/2. So, it is
90+
** safe to add HFIRSTNODE to any index there.)
8591
*/
8692

8793

@@ -102,21 +108,21 @@
102108
** and 'getArrVal'.
103109
*/
104110

105-
/* Computes the address of the tag for the abstract index 'k' */
111+
/* Computes the address of the tag for the abstract C-index 'k' */
106112
#define getArrTag(t,k) (cast(lu_byte*, (t)->array) + (k))
107113

108-
/* Computes the address of the value for the abstract index 'k' */
114+
/* Computes the address of the value for the abstract C-index 'k' */
109115
#define getArrVal(t,k) ((t)->array - 1 - (k))
110116

111117

112118
/*
113-
** Move TValues to/from arrays, using Lua indices
119+
** Move TValues to/from arrays, using C indices
114120
*/
115121
#define arr2obj(h,k,val) \
116-
((val)->tt_ = *getArrTag(h,(k)-1u), (val)->value_ = *getArrVal(h,(k)-1u))
122+
((val)->tt_ = *getArrTag(h,(k)), (val)->value_ = *getArrVal(h,(k)))
117123

118124
#define obj2arr(h,k,val) \
119-
(*getArrTag(h,(k)-1u) = (val)->tt_, *getArrVal(h,(k)-1u) = (val)->value_)
125+
(*getArrTag(h,(k)) = (val)->tt_, *getArrVal(h,(k)) = (val)->value_)
120126

121127

122128
/*
@@ -125,10 +131,10 @@
125131
** precomputed tag value or address as an extra argument.
126132
*/
127133
#define farr2val(h,k,tag,res) \
128-
((res)->tt_ = tag, (res)->value_ = *getArrVal(h,(k)-1u))
134+
((res)->tt_ = tag, (res)->value_ = *getArrVal(h,(k)))
129135

130136
#define fval2arr(h,k,tag,val) \
131-
(*tag = (val)->tt_, *getArrVal(h,(k)-1u) = (val)->value_)
137+
(*tag = (val)->tt_, *getArrVal(h,(k)) = (val)->value_)
132138

133139

134140
LUAI_FUNC int luaH_get (Table *t, const TValue *key, TValue *res);

ltests.c

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -365,7 +365,7 @@ static void checktable (global_State *g, Table *h) {
365365
checkobjrefN(g, hgc, h->metatable);
366366
for (i = 0; i < asize; i++) {
367367
TValue aux;
368-
arr2obj(h, i + 1, &aux);
368+
arr2obj(h, i, &aux);
369369
checkvalref(g, hgc, &aux);
370370
}
371371
for (n = gnode(h, 0); n < limit; n++) {
@@ -1010,7 +1010,7 @@ static int table_query (lua_State *L) {
10101010
}
10111011
else if (cast_uint(i) < asize) {
10121012
lua_pushinteger(L, i);
1013-
arr2obj(t, i + 1, s2v(L->top.p));
1013+
arr2obj(t, i, s2v(L->top.p));
10141014
api_incr_top(L);
10151015
lua_pushnil(L);
10161016
}

lvm.c

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1857,7 +1857,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) {
18571857
luaH_resizearray(L, h, last); /* preallocate it at once */
18581858
for (; n > 0; n--) {
18591859
TValue *val = s2v(ra + n);
1860-
obj2arr(h, last, val);
1860+
obj2arr(h, last - 1, val);
18611861
last--;
18621862
luaC_barrierback(L, obj2gco(h), val);
18631863
}

0 commit comments

Comments
 (0)