[pypy-svn] r17466 - pypy/dist/pypy/rpython
arigo at codespeak.net
arigo at codespeak.net
Sun Sep 11 18:07:48 CEST 2005
Author: arigo
Date: Sun Sep 11 18:07:47 2005
New Revision: 17466
Modified:
pypy/dist/pypy/rpython/rdict.py
Log:
Ported from CPython the protection against custom eq functions
that mutate a dict.
Modified: pypy/dist/pypy/rpython/rdict.py
==============================================================================
--- pypy/dist/pypy/rpython/rdict.py (original)
+++ pypy/dist/pypy/rpython/rdict.py Sun Sep 11 18:07:47 2005
@@ -361,18 +361,20 @@
entries = d.entries
mask = len(entries) - 1
i = r_uint(hash & mask)
-
- """XXX MUTATION PROTECTION!"""
-
# do the first try before any looping
entry = entries[i]
if entry.valid:
- if entry.key == key:
+ checkingkey = entry.key
+ if checkingkey == key:
return entry # found the entry
if dictrepr.custom_eq_hash:
- res = hlinvoke(dictrepr.r_rdict_eqfn, d.fnkeyeq, entry.key, key)
+ res = hlinvoke(dictrepr.r_rdict_eqfn, d.fnkeyeq, checkingkey, key)
+ if (entries != d.entries or
+ not entry.valid or entry.key != checkingkey):
+ # the compare did major nasty stuff to the dict: start over
+ return ll_dict_lookup(d, key, dictrepr)
else:
- res = dictrepr.ll_keyeq is not None and dictrepr.ll_keyeq(entry.key, key)
+ res = dictrepr.ll_keyeq is not None and dictrepr.ll_keyeq(checkingkey, key)
if res:
return entry # found the entry
freeslot = lltype.nullptr(lltype.typeOf(entry).TO)
@@ -390,12 +392,17 @@
if not entry.everused:
return freeslot or entry
elif entry.valid:
- if entry.key == key:
+ checkingkey = entry.key
+ if checkingkey == key:
return entry
if dictrepr.custom_eq_hash:
- res = hlinvoke(dictrepr.r_rdict_eqfn, d.fnkeyeq, entry.key, key)
+ res = hlinvoke(dictrepr.r_rdict_eqfn, d.fnkeyeq, checkingkey, key)
+ if (entries != d.entries or
+ not entry.valid or entry.key != checkingkey):
+ # the compare did major nasty stuff to the dict: start over
+ return ll_dict_lookup(d, key, dictrepr)
else:
- res = dictrepr.ll_keyeq is not None and dictrepr.ll_keyeq(entry.key, key)
+ res = dictrepr.ll_keyeq is not None and dictrepr.ll_keyeq(checkingkey, key)
if res:
return entry
elif not freeslot:
More information about the Pypy-commit
mailing list