Commit 7b5d0afb authored by Tim Peters's avatar Tim Peters

lookdict: Reduce obfuscating code duplication with a judicious goto.

This code is likely to get even hairier to squash core dumps due to
mutating comparisons, and it's hard enough to follow without that.
parent 00d0cb6e
...@@ -251,8 +251,8 @@ lookdict(dictobject *mp, PyObject *key, register long hash) ...@@ -251,8 +251,8 @@ lookdict(dictobject *mp, PyObject *key, register long hash)
register unsigned int mask = mp->ma_size-1; register unsigned int mask = mp->ma_size-1;
dictentry *ep0 = mp->ma_table; dictentry *ep0 = mp->ma_table;
register dictentry *ep; register dictentry *ep;
register int restore_error = 0; register int restore_error;
register int checked_error = 0; register int checked_error;
register int cmp; register int cmp;
PyObject *err_type, *err_value, *err_tb; PyObject *err_type, *err_value, *err_tb;
...@@ -260,6 +260,8 @@ lookdict(dictobject *mp, PyObject *key, register long hash) ...@@ -260,6 +260,8 @@ lookdict(dictobject *mp, PyObject *key, register long hash)
ep = &ep0[i]; ep = &ep0[i];
if (ep->me_key == NULL || ep->me_key == key) if (ep->me_key == NULL || ep->me_key == key)
return ep; return ep;
restore_error = checked_error = 0;
if (ep->me_key == dummy) if (ep->me_key == dummy)
freeslot = ep; freeslot = ep;
else { else {
...@@ -271,13 +273,9 @@ lookdict(dictobject *mp, PyObject *key, register long hash) ...@@ -271,13 +273,9 @@ lookdict(dictobject *mp, PyObject *key, register long hash)
PyErr_Fetch(&err_type, &err_value, &err_tb); PyErr_Fetch(&err_type, &err_value, &err_tb);
} }
cmp = PyObject_RichCompareBool(ep->me_key, key, Py_EQ); cmp = PyObject_RichCompareBool(ep->me_key, key, Py_EQ);
if (cmp > 0) { if (cmp > 0)
if (restore_error) goto Done;
PyErr_Restore(err_type, err_value, if (cmp < 0)
err_tb);
return ep;
}
else if (cmp < 0)
PyErr_Clear(); PyErr_Clear();
} }
freeslot = NULL; freeslot = NULL;
...@@ -289,16 +287,13 @@ lookdict(dictobject *mp, PyObject *key, register long hash) ...@@ -289,16 +287,13 @@ lookdict(dictobject *mp, PyObject *key, register long hash)
i = (i << 2) + i + perturb + 1; i = (i << 2) + i + perturb + 1;
ep = &ep0[i & mask]; ep = &ep0[i & mask];
if (ep->me_key == NULL) { if (ep->me_key == NULL) {
if (restore_error) if (freeslot != NULL)
PyErr_Restore(err_type, err_value, err_tb); ep = freeslot;
return freeslot == NULL ? ep : freeslot; break;
} }
if (ep->me_key == key) { if (ep->me_key == key)
if (restore_error) break;
PyErr_Restore(err_type, err_value, err_tb); if (ep->me_hash == hash && ep->me_key != dummy) {
return ep;
}
else if (ep->me_hash == hash && ep->me_key != dummy) {
if (!checked_error) { if (!checked_error) {
checked_error = 1; checked_error = 1;
if (PyErr_Occurred()) { if (PyErr_Occurred()) {
...@@ -308,18 +303,19 @@ lookdict(dictobject *mp, PyObject *key, register long hash) ...@@ -308,18 +303,19 @@ lookdict(dictobject *mp, PyObject *key, register long hash)
} }
} }
cmp = PyObject_RichCompareBool(ep->me_key, key, Py_EQ); cmp = PyObject_RichCompareBool(ep->me_key, key, Py_EQ);
if (cmp > 0) { if (cmp > 0)
if (restore_error) break;
PyErr_Restore(err_type, err_value, if (cmp < 0)
err_tb);
return ep;
}
else if (cmp < 0)
PyErr_Clear(); PyErr_Clear();
} }
else if (ep->me_key == dummy && freeslot == NULL) else if (ep->me_key == dummy && freeslot == NULL)
freeslot = ep; freeslot = ep;
} }
Done:
if (restore_error)
PyErr_Restore(err_type, err_value, err_tb);
return ep;
} }
/* /*
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment