Mercurial > hg
changeset 40598:fa33196088c4
revlog: replace PyInt_AS_LONG with a more portable helper function
PyInt_AS_LONG disappears on Python, and our previous #define was
producing some problems on Python 3. Let's give up and make an inline
helper function that makes this more sane.
Differential Revision: https://phab.mercurial-scm.org/D5235
author | Augie Fackler <augie@google.com> |
---|---|
date | Tue, 06 Nov 2018 11:12:56 -0500 |
parents | 04d08f17ce7a |
children | 9eeda7199181 |
files | mercurial/cext/revlog.c mercurial/cext/util.h |
diffstat | 2 files changed, 46 insertions(+), 10 deletions(-) [+] |
line wrap: on
line diff
--- a/mercurial/cext/revlog.c Mon Nov 12 22:51:36 2018 +0900 +++ b/mercurial/cext/revlog.c Tue Nov 06 11:12:56 2018 -0500 @@ -24,7 +24,6 @@ #define PyInt_Check PyLong_Check #define PyInt_FromLong PyLong_FromLong #define PyInt_FromSsize_t PyLong_FromSsize_t -#define PyInt_AS_LONG PyLong_AS_LONG #define PyInt_AsLong PyLong_AsLong #endif @@ -161,10 +160,17 @@ int maxrev) { if (rev >= self->length) { + long tmp; PyObject *tuple = PyList_GET_ITEM(self->added, rev - self->length); - ps[0] = (int)PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, 5)); - ps[1] = (int)PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, 6)); + if (!pylong_to_long(PyTuple_GET_ITEM(tuple, 5), &tmp)) { + return -1; + } + ps[0] = (int)tmp; + if (!pylong_to_long(PyTuple_GET_ITEM(tuple, 6), &tmp)) { + return -1; + } + ps[1] = (int)tmp; } else { const char *data = index_deref(self, rev); ps[0] = getbe32(data + 24); @@ -464,7 +470,10 @@ if (iter == NULL) return -2; while ((iter_item = PyIter_Next(iter))) { - iter_item_long = PyInt_AS_LONG(iter_item); + if (!pylong_to_long(iter_item, &iter_item_long)) { + Py_DECREF(iter_item); + return -2; + } Py_DECREF(iter_item); if (iter_item_long < min_idx) min_idx = iter_item_long; @@ -853,7 +862,11 @@ if (rev >= self->length) { PyObject *tuple = PyList_GET_ITEM(self->added, rev - self->length); - return (int)PyInt_AS_LONG(PyTuple_GET_ITEM(tuple, 3)); + long ret; + if (!pylong_to_long(PyTuple_GET_ITEM(tuple, 3), &ret)) { + return -2; + } + return (int)ret; } else { data = index_deref(self, rev); if (data == NULL) { @@ -1384,8 +1397,13 @@ char *node; int rev; - if (PyInt_Check(value)) - return index_get(self, PyInt_AS_LONG(value)); + if (PyInt_Check(value)) { + long idx; + if (!pylong_to_long(value, &idx)) { + return NULL; + } + return index_get(self, idx); + } if (node_check(value, &node) == -1) return NULL; @@ -1516,7 +1534,10 @@ char *node; if (PyInt_Check(value)) { - long rev = PyInt_AS_LONG(value); + long rev; + if (!pylong_to_long(value, &rev)) { + return -1; + } return rev >= -1 && rev < index_length(self); } @@ -2404,10 +2425,12 @@ static int rustla_contains(rustlazyancestorsObject *self, PyObject *rev) { - if (!(PyInt_Check(rev))) { + long lrev; + if (!pylong_to_long(rev, &lrev)) { + PyErr_Clear(); return 0; } - return rustlazyancestors_contains(self->iter, PyInt_AS_LONG(rev)); + return rustlazyancestors_contains(self->iter, lrev); } static PySequenceMethods rustla_sequence_methods = {
--- a/mercurial/cext/util.h Mon Nov 12 22:51:36 2018 +0900 +++ b/mercurial/cext/util.h Tue Nov 06 11:12:56 2018 -0500 @@ -58,4 +58,17 @@ return _PyDict_NewPresized(((1 + expected_size) / 2) * 3); } +/* Convert a PyInt or PyLong to a long. Returns false if there is an + error, in which case an exception will already have been set. */ +static inline bool pylong_to_long(PyObject *pylong, long *out) +{ + *out = PyLong_AsLong(pylong); + /* Fast path to avoid hitting PyErr_Occurred if the value was obviously + * not an error. */ + if (*out != -1) { + return true; + } + return PyErr_Occurred() == NULL; +} + #endif /* _HG_UTIL_H_ */