mirror of https://github.com/python/cpython.git
Consolidate the int and long sequence repeat code. Before the change,
integers checked for integer overflow but longs did not.
This commit is contained in:
parent
9911fc4a41
commit
0df295889c
|
@ -354,14 +354,6 @@ one that can lose catastrophic amounts of information, it's the native long
|
|||
product that must have overflowed.
|
||||
*/
|
||||
|
||||
/* Return true if the sq_repeat method should be used */
|
||||
#define USE_SQ_REPEAT(o) (!PyInt_Check(o) && \
|
||||
o->ob_type->tp_as_sequence && \
|
||||
o->ob_type->tp_as_sequence->sq_repeat && \
|
||||
!(o->ob_type->tp_as_number && \
|
||||
o->ob_type->tp_flags & Py_TPFLAGS_CHECKTYPES && \
|
||||
o->ob_type->tp_as_number->nb_multiply))
|
||||
|
||||
static PyObject *
|
||||
int_mul(PyObject *v, PyObject *w)
|
||||
{
|
||||
|
@ -370,44 +362,6 @@ int_mul(PyObject *v, PyObject *w)
|
|||
double doubled_longprod; /* (double)longprod */
|
||||
double doubleprod; /* (double)a * (double)b */
|
||||
|
||||
if (USE_SQ_REPEAT(v)) {
|
||||
repeat:
|
||||
/* sequence * int */
|
||||
a = PyInt_AsLong(w);
|
||||
#if LONG_MAX != INT_MAX
|
||||
if (a > INT_MAX) {
|
||||
PyErr_SetString(PyExc_ValueError,
|
||||
"sequence repeat count too large");
|
||||
return NULL;
|
||||
}
|
||||
else if (a < INT_MIN)
|
||||
a = INT_MIN;
|
||||
/* XXX Why don't I either
|
||||
|
||||
- set a to -1 whenever it's negative (after all,
|
||||
sequence repeat usually treats negative numbers
|
||||
as zero(); or
|
||||
|
||||
- raise an exception when it's less than INT_MIN?
|
||||
|
||||
I'm thinking about a hypothetical use case where some
|
||||
sequence type might use a negative value as a flag of
|
||||
some kind. In those cases I don't want to break the
|
||||
code by mapping all negative values to -1. But I also
|
||||
don't want to break e.g. []*(-sys.maxint), which is
|
||||
perfectly safe, returning []. As a compromise, I do
|
||||
map out-of-range negative values.
|
||||
*/
|
||||
#endif
|
||||
return (*v->ob_type->tp_as_sequence->sq_repeat)(v, a);
|
||||
}
|
||||
if (USE_SQ_REPEAT(w)) {
|
||||
PyObject *tmp = v;
|
||||
v = w;
|
||||
w = tmp;
|
||||
goto repeat;
|
||||
}
|
||||
|
||||
CONVERT_TO_LONG(v, a);
|
||||
CONVERT_TO_LONG(w, b);
|
||||
longprod = a * b;
|
||||
|
|
|
@ -1508,17 +1508,6 @@ long_sub(PyLongObject *v, PyLongObject *w)
|
|||
return (PyObject *)z;
|
||||
}
|
||||
|
||||
static PyObject *
|
||||
long_repeat(PyObject *v, PyLongObject *w)
|
||||
{
|
||||
/* sequence * long */
|
||||
long n = PyLong_AsLong((PyObject *) w);
|
||||
if (n == -1 && PyErr_Occurred())
|
||||
return NULL;
|
||||
else
|
||||
return (*v->ob_type->tp_as_sequence->sq_repeat)(v, n);
|
||||
}
|
||||
|
||||
/* Grade school multiplication, ignoring the signs.
|
||||
* Returns the absolute value of the product, or NULL if error.
|
||||
*/
|
||||
|
@ -1868,14 +1857,6 @@ long_mul(PyLongObject *v, PyLongObject *w)
|
|||
PyLongObject *a, *b, *z;
|
||||
|
||||
if (!convert_binop((PyObject *)v, (PyObject *)w, &a, &b)) {
|
||||
if (!PyLong_Check(v) &&
|
||||
v->ob_type->tp_as_sequence &&
|
||||
v->ob_type->tp_as_sequence->sq_repeat)
|
||||
return long_repeat((PyObject *)v, w);
|
||||
if (!PyLong_Check(w) &&
|
||||
w->ob_type->tp_as_sequence &&
|
||||
w->ob_type->tp_as_sequence->sq_repeat)
|
||||
return long_repeat((PyObject *)w, v);
|
||||
Py_INCREF(Py_NotImplemented);
|
||||
return Py_NotImplemented;
|
||||
}
|
||||
|
|
Loading…
Reference in New Issue