aboutsummaryrefslogtreecommitdiff
path: root/ltable.c
diff options
context:
space:
mode:
Diffstat (limited to '')
-rw-r--r--ltable.c132
1 files changed, 81 insertions, 51 deletions
diff --git a/ltable.c b/ltable.c
index 0b3ec176..4017d8c7 100644
--- a/ltable.c
+++ b/ltable.c
@@ -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*/
253static int equalkey (const TValue *k1, const Node *n2, int deadok) { 252static 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*/
1216static lua_Unsigned hash_search (Table *t, lua_Unsigned j) { 1239static 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*/
1271lua_Unsigned luaH_getn (Table *t) { 1301lua_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