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 /ltable.h | |
| 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.
Diffstat (limited to 'ltable.h')
| -rw-r--r-- | ltable.h | 36 |
1 files changed, 21 insertions, 15 deletions
| @@ -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); |
