diff options
Diffstat (limited to '')
-rw-r--r-- | ltable.c | 132 |
1 files changed, 81 insertions, 51 deletions
@@ -234,41 +234,51 @@ l_sinline Node *mainpositionfromnode (const Table *t, Node *nd) { | |||
234 | ** Check whether key 'k1' is equal to the key in node 'n2'. This | 234 | ** Check whether key 'k1' is equal to the key in node 'n2'. This |
235 | ** equality is raw, so there are no metamethods. Floats with integer | 235 | ** equality is raw, so there are no metamethods. Floats with integer |
236 | ** values have been normalized, so integers cannot be equal to | 236 | ** values have been normalized, so integers cannot be equal to |
237 | ** floats. It is assumed that 'eqshrstr' is simply pointer equality, so | 237 | ** floats. It is assumed that 'eqshrstr' is simply pointer equality, |
238 | ** that short strings are handled in the default case. | 238 | ** so that short strings are handled in the default case. The flag |
239 | ** A true 'deadok' means to accept dead keys as equal to their original | 239 | ** 'deadok' means to accept dead keys as equal to their original values. |
240 | ** values. All dead keys are compared in the default case, by pointer | 240 | ** (Only collectable objects can produce dead keys.) Note that dead |
241 | ** identity. (Only collectable objects can produce dead keys.) Note that | 241 | ** long strings are also compared by identity. Once a key is dead, |
242 | ** dead long strings are also compared by identity. | 242 | ** its corresponding value may be collected, and then another value |
243 | ** Once a key is dead, its corresponding value may be collected, and | 243 | ** can be created with the same address. If this other value is given |
244 | ** then another value can be created with the same address. If this | 244 | ** to 'next', 'equalkey' will signal a false positive. In a regular |
245 | ** other value is given to 'next', 'equalkey' will signal a false | 245 | ** traversal, this situation should never happen, as all keys given to |
246 | ** positive. In a regular traversal, this situation should never happen, | 246 | ** 'next' came from the table itself, and therefore could not have been |
247 | ** as all keys given to 'next' came from the table itself, and therefore | 247 | ** collected. Outside a regular traversal, we have garbage in, garbage |
248 | ** could not have been collected. Outside a regular traversal, we | 248 | ** out. What is relevant is that this false positive does not break |
249 | ** have garbage in, garbage out. What is relevant is that this false | 249 | ** anything. (In particular, 'next' will return some other valid item |
250 | ** positive does not break anything. (In particular, 'next' will return | 250 | ** on the table or nil.) |
251 | ** some other valid item on the table or nil.) | ||
252 | */ | 251 | */ |
253 | static int equalkey (const TValue *k1, const Node *n2, int deadok) { | 252 | static int equalkey (const TValue *k1, const Node *n2, int deadok) { |
254 | if ((rawtt(k1) != keytt(n2)) && /* not the same variants? */ | 253 | if (rawtt(k1) != keytt(n2)) { /* not the same variants? */ |
255 | !(deadok && keyisdead(n2) && iscollectable(k1))) | 254 | if (keyisshrstr(n2) && ttislngstring(k1)) { |
256 | return 0; /* cannot be same key */ | 255 | /* an external string can be equal to a short-string key */ |
257 | switch (keytt(n2)) { | 256 | return luaS_eqstr(tsvalue(k1), keystrval(n2)); |
258 | case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE: | 257 | } |
259 | return 1; | 258 | else if (deadok && keyisdead(n2) && iscollectable(k1)) { |
260 | case LUA_VNUMINT: | 259 | /* a collectable value can be equal to a dead key */ |
261 | return (ivalue(k1) == keyival(n2)); | ||
262 | case LUA_VNUMFLT: | ||
263 | return luai_numeq(fltvalue(k1), fltvalueraw(keyval(n2))); | ||
264 | case LUA_VLIGHTUSERDATA: | ||
265 | return pvalue(k1) == pvalueraw(keyval(n2)); | ||
266 | case LUA_VLCF: | ||
267 | return fvalue(k1) == fvalueraw(keyval(n2)); | ||
268 | case ctb(LUA_VLNGSTR): | ||
269 | return luaS_eqlngstr(tsvalue(k1), keystrval(n2)); | ||
270 | default: | ||
271 | return gcvalue(k1) == gcvalueraw(keyval(n2)); | 260 | return gcvalue(k1) == gcvalueraw(keyval(n2)); |
261 | } | ||
262 | else | ||
263 | return 0; /* otherwise, different variants cannot be equal */ | ||
264 | } | ||
265 | else { /* equal variants */ | ||
266 | switch (keytt(n2)) { | ||
267 | case LUA_VNIL: case LUA_VFALSE: case LUA_VTRUE: | ||
268 | return 1; | ||
269 | case LUA_VNUMINT: | ||
270 | return (ivalue(k1) == keyival(n2)); | ||
271 | case LUA_VNUMFLT: | ||
272 | return luai_numeq(fltvalue(k1), fltvalueraw(keyval(n2))); | ||
273 | case LUA_VLIGHTUSERDATA: | ||
274 | return pvalue(k1) == pvalueraw(keyval(n2)); | ||
275 | case LUA_VLCF: | ||
276 | return fvalue(k1) == fvalueraw(keyval(n2)); | ||
277 | case ctb(LUA_VLNGSTR): | ||
278 | return luaS_eqstr(tsvalue(k1), keystrval(n2)); | ||
279 | default: | ||
280 | return gcvalue(k1) == gcvalueraw(keyval(n2)); | ||
281 | } | ||
272 | } | 282 | } |
273 | } | 283 | } |
274 | 284 | ||
@@ -1158,6 +1168,14 @@ void luaH_finishset (lua_State *L, Table *t, const TValue *key, | |||
1158 | else if (l_unlikely(luai_numisnan(f))) | 1168 | else if (l_unlikely(luai_numisnan(f))) |
1159 | luaG_runerror(L, "table index is NaN"); | 1169 | luaG_runerror(L, "table index is NaN"); |
1160 | } | 1170 | } |
1171 | else if (isextstr(key)) { /* external string? */ | ||
1172 | /* If string is short, must internalize it to be used as table key */ | ||
1173 | TString *ts = luaS_normstr(L, tsvalue(key)); | ||
1174 | setsvalue2s(L, L->top.p++, ts); /* anchor 'ts' (EXTRA_STACK) */ | ||
1175 | luaH_newkey(L, t, s2v(L->top.p - 1), value); | ||
1176 | L->top.p--; | ||
1177 | return; | ||
1178 | } | ||
1161 | luaH_newkey(L, t, key, value); | 1179 | luaH_newkey(L, t, key, value); |
1162 | } | 1180 | } |
1163 | else if (hres > 0) { /* regular Node? */ | 1181 | else if (hres > 0) { /* regular Node? */ |
@@ -1202,24 +1220,36 @@ void luaH_setint (lua_State *L, Table *t, lua_Integer key, TValue *value) { | |||
1202 | 1220 | ||
1203 | /* | 1221 | /* |
1204 | ** Try to find a boundary in the hash part of table 't'. From the | 1222 | ** Try to find a boundary in the hash part of table 't'. From the |
1205 | ** caller, we know that 'j' is zero or present and that 'j + 1' is | 1223 | ** caller, we know that 'asize + 1' is present. We want to find a larger |
1206 | ** present. We want to find a larger key that is absent from the | 1224 | ** key that is absent from the table, so that we can do a binary search |
1207 | ** table, so that we can do a binary search between the two keys to | 1225 | ** between the two keys to find a boundary. We keep doubling 'j' until |
1208 | ** find a boundary. We keep doubling 'j' until we get an absent index. | 1226 | ** we get an absent index. If the doubling would overflow, we try |
1209 | ** If the doubling would overflow, we try LUA_MAXINTEGER. If it is | 1227 | ** LUA_MAXINTEGER. If it is absent, we are ready for the binary search. |
1210 | ** absent, we are ready for the binary search. ('j', being max integer, | 1228 | ** ('j', being max integer, is larger or equal to 'i', but it cannot be |
1211 | ** is larger or equal to 'i', but it cannot be equal because it is | 1229 | ** equal because it is absent while 'i' is present.) Otherwise, 'j' is a |
1212 | ** absent while 'i' is present; so 'j > i'.) Otherwise, 'j' is a | 1230 | ** boundary. ('j + 1' cannot be a present integer key because it is not |
1213 | ** boundary. ('j + 1' cannot be a present integer key because it is | 1231 | ** a valid integer in Lua.) |
1214 | ** not a valid integer in Lua.) | 1232 | ** About 'rnd': If we used a fixed algorithm, a bad actor could fill |
1233 | ** a table with only the keys that would be probed, in such a way that | ||
1234 | ** a small table could result in a huge length. To avoid that, we use | ||
1235 | ** the state's seed as a source of randomness. For the first probe, | ||
1236 | ** we "randomly double" 'i' by adding to it a random number roughly its | ||
1237 | ** width. | ||
1215 | */ | 1238 | */ |
1216 | static lua_Unsigned hash_search (Table *t, lua_Unsigned j) { | 1239 | static lua_Unsigned hash_search (lua_State *L, Table *t, unsigned asize) { |
1217 | lua_Unsigned i; | 1240 | lua_Unsigned i = asize + 1; /* caller ensures t[i] is present */ |
1218 | if (j == 0) j++; /* the caller ensures 'j + 1' is present */ | 1241 | unsigned rnd = G(L)->seed; |
1219 | do { | 1242 | int n = (asize > 0) ? luaO_ceillog2(asize) : 0; /* width of 'asize' */ |
1243 | unsigned mask = (1u << n) - 1; /* 11...111 with the width of 'asize' */ | ||
1244 | unsigned incr = (rnd & mask) + 1; /* first increment (at least 1) */ | ||
1245 | lua_Unsigned j = (incr <= l_castS2U(LUA_MAXINTEGER) - i) ? i + incr : i + 1; | ||
1246 | rnd >>= n; /* used 'n' bits from 'rnd' */ | ||
1247 | while (!hashkeyisempty(t, j)) { /* repeat until an absent t[j] */ | ||
1220 | i = j; /* 'i' is a present index */ | 1248 | i = j; /* 'i' is a present index */ |
1221 | if (j <= l_castS2U(LUA_MAXINTEGER) / 2) | 1249 | if (j <= l_castS2U(LUA_MAXINTEGER)/2 - 1) { |
1222 | j *= 2; | 1250 | j = j*2 + (rnd & 1); /* try again with 2j or 2j+1 */ |
1251 | rnd >>= 1; | ||
1252 | } | ||
1223 | else { | 1253 | else { |
1224 | j = LUA_MAXINTEGER; | 1254 | j = LUA_MAXINTEGER; |
1225 | if (hashkeyisempty(t, j)) /* t[j] not present? */ | 1255 | if (hashkeyisempty(t, j)) /* t[j] not present? */ |
@@ -1227,7 +1257,7 @@ static lua_Unsigned hash_search (Table *t, lua_Unsigned j) { | |||
1227 | else /* weird case */ | 1257 | else /* weird case */ |
1228 | return j; /* well, max integer is a boundary... */ | 1258 | return j; /* well, max integer is a boundary... */ |
1229 | } | 1259 | } |
1230 | } while (!hashkeyisempty(t, j)); /* repeat until an absent t[j] */ | 1260 | } |
1231 | /* i < j && t[i] present && t[j] absent */ | 1261 | /* i < j && t[i] present && t[j] absent */ |
1232 | while (j - i > 1u) { /* do a binary search between them */ | 1262 | while (j - i > 1u) { /* do a binary search between them */ |
1233 | lua_Unsigned m = (i + j) / 2; | 1263 | lua_Unsigned m = (i + j) / 2; |
@@ -1268,7 +1298,7 @@ static lua_Unsigned newhint (Table *t, unsigned hint) { | |||
1268 | ** If there is no array part, or its last element is non empty, the | 1298 | ** If there is no array part, or its last element is non empty, the |
1269 | ** border may be in the hash part. | 1299 | ** border may be in the hash part. |
1270 | */ | 1300 | */ |
1271 | lua_Unsigned luaH_getn (Table *t) { | 1301 | lua_Unsigned luaH_getn (lua_State *L, Table *t) { |
1272 | unsigned asize = t->asize; | 1302 | unsigned asize = t->asize; |
1273 | if (asize > 0) { /* is there an array part? */ | 1303 | if (asize > 0) { /* is there an array part? */ |
1274 | const unsigned maxvicinity = 4; | 1304 | const unsigned maxvicinity = 4; |
@@ -1309,7 +1339,7 @@ lua_Unsigned luaH_getn (Table *t) { | |||
1309 | if (isdummy(t) || hashkeyisempty(t, asize + 1)) | 1339 | if (isdummy(t) || hashkeyisempty(t, asize + 1)) |
1310 | return asize; /* 'asize + 1' is empty */ | 1340 | return asize; /* 'asize + 1' is empty */ |
1311 | else /* 'asize + 1' is also non empty */ | 1341 | else /* 'asize + 1' is also non empty */ |
1312 | return hash_search(t, asize); | 1342 | return hash_search(L, t, asize); |
1313 | } | 1343 | } |
1314 | 1344 | ||
1315 | 1345 | ||