diff options
| author | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-06-10 12:09:35 -0300 |
|---|---|---|
| committer | Roberto Ierusalimschy <roberto@inf.puc-rio.br> | 2024-06-10 12:09:35 -0300 |
| commit | 94b503d95ef00f1e38b58b024ef45bf8973a8746 (patch) | |
| tree | c713558a386934bc1d251f064c8d9fae1fb725c0 | |
| parent | bdc85357aa41a9610498232c2cffe7aa191e5cf6 (diff) | |
| download | lua-94b503d95ef00f1e38b58b024ef45bf8973a8746.tar.gz lua-94b503d95ef00f1e38b58b024ef45bf8973a8746.tar.bz2 lua-94b503d95ef00f1e38b58b024ef45bf8973a8746.zip | |
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.
| -rw-r--r-- | ltable.c | 12 | ||||
| -rw-r--r-- | ltable.h | 36 | ||||
| -rw-r--r-- | ltests.c | 4 | ||||
| -rw-r--r-- | lvm.c | 2 |
4 files changed, 30 insertions, 24 deletions
| @@ -384,7 +384,7 @@ int luaH_next (lua_State *L, Table *t, StkId key) { | |||
| 384 | int tag = *getArrTag(t, i); | 384 | int tag = *getArrTag(t, i); |
| 385 | if (!tagisempty(tag)) { /* a non-empty entry? */ | 385 | if (!tagisempty(tag)) { /* a non-empty entry? */ |
| 386 | setivalue(s2v(key), i + 1); | 386 | setivalue(s2v(key), i + 1); |
| 387 | farr2val(t, i + 1, tag, s2v(key + 1)); | 387 | farr2val(t, i, tag, s2v(key + 1)); |
| 388 | return 1; | 388 | return 1; |
| 389 | } | 389 | } |
| 390 | } | 390 | } |
| @@ -692,7 +692,7 @@ static void reinsertOldSlice (lua_State *L, Table *t, unsigned oldasize, | |||
| 692 | int tag = *getArrTag(t, i); | 692 | int tag = *getArrTag(t, i); |
| 693 | if (!tagisempty(tag)) { /* a non-empty entry? */ | 693 | if (!tagisempty(tag)) { /* a non-empty entry? */ |
| 694 | TValue aux; | 694 | TValue aux; |
| 695 | farr2val(t, i + 1, tag, &aux); /* copy entry into 'aux' */ | 695 | farr2val(t, i, tag, &aux); /* copy entry into 'aux' */ |
| 696 | luaH_setint(L, t, i + 1, &aux); /* re-insert it into the table */ | 696 | luaH_setint(L, t, i + 1, &aux); /* re-insert it into the table */ |
| 697 | } | 697 | } |
| 698 | } | 698 | } |
| @@ -937,7 +937,7 @@ int luaH_getint (Table *t, lua_Integer key, TValue *res) { | |||
| 937 | if (keyinarray(t, key)) { | 937 | if (keyinarray(t, key)) { |
| 938 | int tag = *getArrTag(t, key - 1); | 938 | int tag = *getArrTag(t, key - 1); |
| 939 | if (!tagisempty(tag)) | 939 | if (!tagisempty(tag)) |
| 940 | farr2val(t, key, tag, res); | 940 | farr2val(t, key - 1, tag, res); |
| 941 | return tag; | 941 | return tag; |
| 942 | } | 942 | } |
| 943 | else | 943 | else |
| @@ -1048,11 +1048,11 @@ int luaH_psetint (Table *t, lua_Integer key, TValue *val) { | |||
| 1048 | if (keyinarray(t, key)) { | 1048 | if (keyinarray(t, key)) { |
| 1049 | lu_byte *tag = getArrTag(t, key - 1); | 1049 | lu_byte *tag = getArrTag(t, key - 1); |
| 1050 | if (!tagisempty(*tag) || checknoTM(t->metatable, TM_NEWINDEX)) { | 1050 | if (!tagisempty(*tag) || checknoTM(t->metatable, TM_NEWINDEX)) { |
| 1051 | fval2arr(t, key, tag, val); | 1051 | fval2arr(t, key - 1, tag, val); |
| 1052 | return HOK; /* success */ | 1052 | return HOK; /* success */ |
| 1053 | } | 1053 | } |
| 1054 | else | 1054 | else |
| 1055 | return ~cast_int(key); /* empty slot in the array part */ | 1055 | return ~cast_int(key - 1); /* empty slot in the array part */ |
| 1056 | } | 1056 | } |
| 1057 | else | 1057 | else |
| 1058 | return finishnodeset(t, getintfromhash(t, key), val); | 1058 | return finishnodeset(t, getintfromhash(t, key), val); |
| @@ -1126,7 +1126,7 @@ void luaH_set (lua_State *L, Table *t, const TValue *key, TValue *value) { | |||
| 1126 | */ | 1126 | */ |
| 1127 | void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { | 1127 | void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { |
| 1128 | if (keyinarray(t, key)) | 1128 | if (keyinarray(t, key)) |
| 1129 | obj2arr(t, key, value); | 1129 | obj2arr(t, key - 1, value); |
| 1130 | else { | 1130 | else { |
| 1131 | int ok = rawfinishnodeset(getintfromhash(t, key), value); | 1131 | int ok = rawfinishnodeset(getintfromhash(t, key), value); |
| 1132 | if (!ok) { | 1132 | if (!ok) { |
| @@ -47,20 +47,20 @@ | |||
| 47 | 47 | ||
| 48 | 48 | ||
| 49 | #define luaH_fastgeti(t,k,res,tag) \ | 49 | #define luaH_fastgeti(t,k,res,tag) \ |
| 50 | { Table *h = t; lua_Unsigned u = l_castS2U(k); \ | 50 | { Table *h = t; lua_Unsigned u = l_castS2U(k) - 1u; \ |
| 51 | if ((u - 1u < h->alimit)) { \ | 51 | if ((u < h->alimit)) { \ |
| 52 | tag = *getArrTag(h,(u)-1u); \ | 52 | tag = *getArrTag(h, u); \ |
| 53 | if (!tagisempty(tag)) { farr2val(h, u, tag, res); }} \ | 53 | if (!tagisempty(tag)) { farr2val(h, u, tag, res); }} \ |
| 54 | else { tag = luaH_getint(h, u, res); }} | 54 | else { tag = luaH_getint(h, (k), res); }} |
| 55 | 55 | ||
| 56 | 56 | ||
| 57 | #define luaH_fastseti(t,k,val,hres) \ | 57 | #define luaH_fastseti(t,k,val,hres) \ |
| 58 | { Table *h = t; lua_Unsigned u = l_castS2U(k); \ | 58 | { Table *h = t; lua_Unsigned u = l_castS2U(k) - 1u; \ |
| 59 | if ((u - 1u < h->alimit)) { \ | 59 | if ((u < h->alimit)) { \ |
| 60 | lu_byte *tag = getArrTag(h,(u)-1u); \ | 60 | lu_byte *tag = getArrTag(h, u); \ |
| 61 | if (tagisempty(*tag)) hres = ~cast_int(u); \ | 61 | if (tagisempty(*tag)) hres = ~cast_int(u); \ |
| 62 | else { fval2arr(h, u, tag, val); hres = HOK; }} \ | 62 | else { fval2arr(h, u, tag, val); hres = HOK; }} \ |
| 63 | else { hres = luaH_psetint(h, u, val); }} | 63 | else { hres = luaH_psetint(h, k, val); }} |
| 64 | 64 | ||
| 65 | 65 | ||
| 66 | /* results from pset */ | 66 | /* results from pset */ |
| @@ -82,6 +82,12 @@ | |||
| 82 | ** in the array part, the encoding is (~array index), a negative value. | 82 | ** in the array part, the encoding is (~array index), a negative value. |
| 83 | ** The value HNOTATABLE is used by the fast macros to signal that the | 83 | ** The value HNOTATABLE is used by the fast macros to signal that the |
| 84 | ** value being indexed is not a table. | 84 | ** 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.) | ||
| 85 | */ | 91 | */ |
| 86 | 92 | ||
| 87 | 93 | ||
| @@ -102,21 +108,21 @@ | |||
| 102 | ** and 'getArrVal'. | 108 | ** and 'getArrVal'. |
| 103 | */ | 109 | */ |
| 104 | 110 | ||
| 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' */ |
| 106 | #define getArrTag(t,k) (cast(lu_byte*, (t)->array) + (k)) | 112 | #define getArrTag(t,k) (cast(lu_byte*, (t)->array) + (k)) |
| 107 | 113 | ||
| 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' */ |
| 109 | #define getArrVal(t,k) ((t)->array - 1 - (k)) | 115 | #define getArrVal(t,k) ((t)->array - 1 - (k)) |
| 110 | 116 | ||
| 111 | 117 | ||
| 112 | /* | 118 | /* |
| 113 | ** Move TValues to/from arrays, using Lua indices | 119 | ** Move TValues to/from arrays, using C indices |
| 114 | */ | 120 | */ |
| 115 | #define arr2obj(h,k,val) \ | 121 | #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))) |
| 117 | 123 | ||
| 118 | #define obj2arr(h,k,val) \ | 124 | #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_) |
| 120 | 126 | ||
| 121 | 127 | ||
| 122 | /* | 128 | /* |
| @@ -125,10 +131,10 @@ | |||
| 125 | ** precomputed tag value or address as an extra argument. | 131 | ** precomputed tag value or address as an extra argument. |
| 126 | */ | 132 | */ |
| 127 | #define farr2val(h,k,tag,res) \ | 133 | #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))) |
| 129 | 135 | ||
| 130 | #define fval2arr(h,k,tag,val) \ | 136 | #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_) |
| 132 | 138 | ||
| 133 | 139 | ||
| 134 | LUAI_FUNC int luaH_get (Table *t, const TValue *key, TValue *res); | 140 | LUAI_FUNC int luaH_get (Table *t, const TValue *key, TValue *res); |
| @@ -365,7 +365,7 @@ static void checktable (global_State *g, Table *h) { | |||
| 365 | checkobjrefN(g, hgc, h->metatable); | 365 | checkobjrefN(g, hgc, h->metatable); |
| 366 | for (i = 0; i < asize; i++) { | 366 | for (i = 0; i < asize; i++) { |
| 367 | TValue aux; | 367 | TValue aux; |
| 368 | arr2obj(h, i + 1, &aux); | 368 | arr2obj(h, i, &aux); |
| 369 | checkvalref(g, hgc, &aux); | 369 | checkvalref(g, hgc, &aux); |
| 370 | } | 370 | } |
| 371 | for (n = gnode(h, 0); n < limit; n++) { | 371 | for (n = gnode(h, 0); n < limit; n++) { |
| @@ -1010,7 +1010,7 @@ static int table_query (lua_State *L) { | |||
| 1010 | } | 1010 | } |
| 1011 | else if (cast_uint(i) < asize) { | 1011 | else if (cast_uint(i) < asize) { |
| 1012 | lua_pushinteger(L, i); | 1012 | lua_pushinteger(L, i); |
| 1013 | arr2obj(t, i + 1, s2v(L->top.p)); | 1013 | arr2obj(t, i, s2v(L->top.p)); |
| 1014 | api_incr_top(L); | 1014 | api_incr_top(L); |
| 1015 | lua_pushnil(L); | 1015 | lua_pushnil(L); |
| 1016 | } | 1016 | } |
| @@ -1857,7 +1857,7 @@ void luaV_execute (lua_State *L, CallInfo *ci) { | |||
| 1857 | luaH_resizearray(L, h, last); /* preallocate it at once */ | 1857 | luaH_resizearray(L, h, last); /* preallocate it at once */ |
| 1858 | for (; n > 0; n--) { | 1858 | for (; n > 0; n--) { |
| 1859 | TValue *val = s2v(ra + n); | 1859 | TValue *val = s2v(ra + n); |
| 1860 | obj2arr(h, last, val); | 1860 | obj2arr(h, last - 1, val); |
| 1861 | last--; | 1861 | last--; |
| 1862 | luaC_barrierback(L, obj2gco(h), val); | 1862 | luaC_barrierback(L, obj2gco(h), val); |
| 1863 | } | 1863 | } |
