diff options
author | Guido van Rossum <guido@python.org> | 2007-01-14 03:31:43 (GMT) |
---|---|---|
committer | Guido van Rossum <guido@python.org> | 2007-01-14 03:31:43 (GMT) |
commit | ddefaf31b366ea84250fc5090837c2b764a04102 (patch) | |
tree | ab3d7b5172f4e6a064165468fc70beb41bdca1d3 /Objects/longobject.c | |
parent | 5b787e8bc2dbda5583eee039cb6a6e47c8d8a034 (diff) | |
download | cpython-ddefaf31b366ea84250fc5090837c2b764a04102.zip cpython-ddefaf31b366ea84250fc5090837c2b764a04102.tar.gz cpython-ddefaf31b366ea84250fc5090837c2b764a04102.tar.bz2 |
Merged the int/long unification branch, by very crude means (sorry Thomas!).
I banged on the code (beyond what's in that branch) to make fewer tests fail;
the only tests that fail now are:
test_descr -- can't pickle ints?!
test_pickletools -- ???
test_socket -- See python.org/sf/1619659
test_sqlite -- ???
I'll deal with those later.
Diffstat (limited to 'Objects/longobject.c')
-rw-r--r-- | Objects/longobject.c | 520 |
1 files changed, 402 insertions, 118 deletions
diff --git a/Objects/longobject.c b/Objects/longobject.c index f68656b..03d22f5 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -7,6 +7,53 @@ #include <ctype.h> +#ifndef NSMALLPOSINTS +#define NSMALLPOSINTS 257 +#endif +#ifndef NSMALLNEGINTS +#define NSMALLNEGINTS 5 +#endif +#if NSMALLNEGINTS + NSMALLPOSINTS > 0 +/* Small integers are preallocated in this array so that they + can be shared. + The integers that are preallocated are those in the range + -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive). +*/ +static PyLongObject small_ints[NSMALLNEGINTS + NSMALLPOSINTS]; +#ifdef COUNT_ALLOCS +int quick_int_allocs, quick_neg_int_allocs; +#endif + +static inline PyObject * +get_small_int(int ival) +{ + PyObject *v = (PyObject*)(small_ints + ival + NSMALLNEGINTS); + Py_INCREF(v); +#ifdef COUNT_ALLOCS + if (ival >= 0) + quick_int_allocs++; + else + quick_neg_int_allocs++; +#endif + return v; +} +#define CHECK_SMALL_INT(ival) \ + do if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) { \ + return get_small_int(ival); \ + } while(0) + +#else +#define CHECK_SMALL_INT(ival) +#endif + +#define MEDIUM_VALUE(x) ((x)->ob_size < 0 ? -(x)->ob_digit[0] : ((x)->ob_size == 0 ? 0 : (x)->ob_digit[0])) +/* If a freshly-allocated long is already shared, it must + be a small integer, so negating it must go to PyLong_FromLong */ +#define NEGATE(x) \ + do if ((x)->ob_refcnt == 1) (x)->ob_size = -(x)->ob_size; \ + else { PyObject* tmp=PyInt_FromLong(-MEDIUM_VALUE(x)); \ + Py_DECREF(x); (x) = (PyLongObject*)tmp; } \ + while(0) /* For long multiplication, use the O(N**2) school algorithm unless * both operands contain more than KARATSUBA_CUTOFF digits (this * being an internal Python long digit, in base BASE). @@ -64,11 +111,21 @@ long_normalize(register PyLongObject *v) PyLongObject * _PyLong_New(Py_ssize_t size) { - if (size > PY_SSIZE_T_MAX) { + PyLongObject *result; + /* Can't use sizeof(PyLongObject) here, since the + compiler takes padding at the end into account. + As the consequence, this would waste 2 bytes on + a 32-bit system, and 6 bytes on a 64-bit system. + This computation would be incorrect on systems + which have padding before the digits; with 16-bit + digits this should not happen. */ + result = PyObject_MALLOC(sizeof(PyVarObject) + + size*sizeof(digit)); + if (!result) { PyErr_NoMemory(); return NULL; } - return PyObject_NEW_VAR(PyLongObject, &PyLong_Type, size); + return (PyLongObject*)PyObject_INIT_VAR(result, &PyLong_Type, size); } PyObject * @@ -81,6 +138,12 @@ _PyLong_Copy(PyLongObject *src) i = src->ob_size; if (i < 0) i = -(i); + if (i < 2) { + int ival = src->ob_digit[0]; + if (src->ob_size < 0) + ival = -ival; + CHECK_SMALL_INT(ival); + } result = _PyLong_New(i); if (result != NULL) { result->ob_size = src->ob_size; @@ -98,17 +161,37 @@ PyLong_FromLong(long ival) PyLongObject *v; unsigned long t; /* unsigned so >> doesn't propagate sign bit */ int ndigits = 0; - int negative = 0; + int sign = 1; + + CHECK_SMALL_INT(ival); if (ival < 0) { ival = -ival; - negative = 1; + sign = -1; } - /* Count the number of Python digits. - We used to pick 5 ("big enough for anything"), but that's a - waste of time and space given that 5*15 = 75 bits are rarely - needed. */ + /* Fast path for single-digits ints */ + if (!(ival>>SHIFT)) { + v = _PyLong_New(1); + if (v) { + v->ob_size = sign; + v->ob_digit[0] = ival; + } + return (PyObject*)v; + } + + /* 2 digits */ + if (!(ival >> 2*SHIFT)) { + v = _PyLong_New(2); + if (v) { + v->ob_size = 2*sign; + v->ob_digit[0] = (digit)ival & MASK; + v->ob_digit[1] = ival >> SHIFT; + } + return (PyObject*)v; + } + + /* Larger numbers: loop to determine number of digits */ t = (unsigned long)ival; while (t) { ++ndigits; @@ -117,7 +200,7 @@ PyLong_FromLong(long ival) v = _PyLong_New(ndigits); if (v != NULL) { digit *p = v->ob_digit; - v->ob_size = negative ? -ndigits : ndigits; + v->ob_size = ndigits*sign; t = (unsigned long)ival; while (t) { *p++ = (digit)(t & MASK); @@ -136,6 +219,8 @@ PyLong_FromUnsignedLong(unsigned long ival) unsigned long t; int ndigits = 0; + if (ival < BASE) + return PyLong_FromLong(ival); /* Count the number of Python digits. */ t = (unsigned long)ival; while (t) { @@ -165,9 +250,10 @@ PyLong_FromDouble(double dval) neg = 0; if (Py_IS_INFINITY(dval)) { PyErr_SetString(PyExc_OverflowError, - "cannot convert float infinity to long"); + "cannot convert float infinity to int"); return NULL; } + CHECK_SMALL_INT((int)dval); if (dval < 0.0) { neg = 1; dval = -dval; @@ -214,15 +300,39 @@ PyLong_AsLong(PyObject *vv) unsigned long x, prev; Py_ssize_t i; int sign; + int do_decref = 0; /* if nb_int was called */ - if (vv == NULL || !PyLong_Check(vv)) { - if (vv != NULL && PyInt_Check(vv)) - return PyInt_AsLong(vv); + if (vv == NULL) { PyErr_BadInternalCall(); return -1; } + + if (!PyLong_Check(vv)) { + PyNumberMethods *nb; + if ((nb = vv->ob_type->tp_as_number) == NULL || + nb->nb_int == NULL) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return -1; + } + vv = (*nb->nb_int) (vv); + if (vv == NULL) + return -1; + do_decref = 1; + if (!PyLong_Check(vv)) { + Py_DECREF(vv); + PyErr_SetString(PyExc_TypeError, + "nb_int should return int object"); + return -1; + } + } + v = (PyLongObject *)vv; i = v->ob_size; + switch (i) { + case -1: return -v->ob_digit[0]; + case 0: return 0; + case 1: return v->ob_digit[0]; + } sign = 1; x = 0; if (i < 0) { @@ -235,6 +345,9 @@ PyLong_AsLong(PyObject *vv) if ((x >> SHIFT) != prev) goto overflow; } + if (do_decref) { + Py_DECREF(vv); + } /* Haven't lost any bits, but casting to long requires extra care * (see comment above). */ @@ -247,16 +360,32 @@ PyLong_AsLong(PyObject *vv) /* else overflow */ overflow: + if (do_decref) { + Py_DECREF(vv); + } PyErr_SetString(PyExc_OverflowError, - "long int too large to convert to int"); + "int too large to convert to int"); return -1; } +int +_PyLong_FitsInLong(PyObject *vv) +{ + int size; + if (!PyLong_CheckExact(vv)) { + PyErr_BadInternalCall(); + return 0; + } + /* conservative estimate */ + size = ((PyLongObject*)vv)->ob_size; + return -2 <= size && size <= 2; +} + /* Get a Py_ssize_t from a long int object. Returns -1 and sets an error condition if overflow occurs. */ Py_ssize_t -_PyLong_AsSsize_t(PyObject *vv) { +PyLong_AsSsize_t(PyObject *vv) { register PyLongObject *v; size_t x, prev; Py_ssize_t i; @@ -268,6 +397,11 @@ _PyLong_AsSsize_t(PyObject *vv) { } v = (PyLongObject *)vv; i = v->ob_size; + switch (i) { + case -1: return -v->ob_digit[0]; + case 0: return 0; + case 1: return v->ob_digit[0]; + } sign = 1; x = 0; if (i < 0) { @@ -293,7 +427,7 @@ _PyLong_AsSsize_t(PyObject *vv) { overflow: PyErr_SetString(PyExc_OverflowError, - "long int too large to convert to int"); + "int too large to convert to "); return -1; } @@ -308,15 +442,6 @@ PyLong_AsUnsignedLong(PyObject *vv) Py_ssize_t i; if (vv == NULL || !PyLong_Check(vv)) { - if (vv != NULL && PyInt_Check(vv)) { - long val = PyInt_AsLong(vv); - if (val < 0) { - PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to unsigned long"); - return (unsigned long) -1; - } - return val; - } PyErr_BadInternalCall(); return (unsigned long) -1; } @@ -325,15 +450,57 @@ PyLong_AsUnsignedLong(PyObject *vv) x = 0; if (i < 0) { PyErr_SetString(PyExc_OverflowError, - "can't convert negative value to unsigned long"); + "can't convert negative value to unsigned int"); return (unsigned long) -1; } + switch (i) { + case 0: return 0; + case 1: return v->ob_digit[0]; + } + while (--i >= 0) { + prev = x; + x = (x << SHIFT) + v->ob_digit[i]; + if ((x >> SHIFT) != prev) { + PyErr_SetString(PyExc_OverflowError, + "int too large to convert"); + return (unsigned long) -1; + } + } + return x; +} + +/* Get a C unsigned long int from a long int object. + Returns -1 and sets an error condition if overflow occurs. */ + +size_t +PyLong_AsSize_t(PyObject *vv) +{ + register PyLongObject *v; + size_t x, prev; + Py_ssize_t i; + + if (vv == NULL || !PyLong_Check(vv)) { + PyErr_BadInternalCall(); + return (unsigned long) -1; + } + v = (PyLongObject *)vv; + i = v->ob_size; + x = 0; + if (i < 0) { + PyErr_SetString(PyExc_OverflowError, + "can't convert negative value to size_t"); + return (size_t) -1; + } + switch (i) { + case 0: return 0; + case 1: return v->ob_digit[0]; + } while (--i >= 0) { prev = x; x = (x << SHIFT) + v->ob_digit[i]; if ((x >> SHIFT) != prev) { PyErr_SetString(PyExc_OverflowError, - "long int too large to convert"); + "int too large to convert"); return (unsigned long) -1; } } @@ -343,8 +510,8 @@ PyLong_AsUnsignedLong(PyObject *vv) /* Get a C unsigned long int from a long int object, ignoring the high bits. Returns -1 and sets an error condition if an error occurs. */ -unsigned long -PyLong_AsUnsignedLongMask(PyObject *vv) +static unsigned long +_PyLong_AsUnsignedLongMask(PyObject *vv) { register PyLongObject *v; unsigned long x; @@ -352,13 +519,15 @@ PyLong_AsUnsignedLongMask(PyObject *vv) int sign; if (vv == NULL || !PyLong_Check(vv)) { - if (vv != NULL && PyInt_Check(vv)) - return PyInt_AsUnsignedLongMask(vv); PyErr_BadInternalCall(); return (unsigned long) -1; } v = (PyLongObject *)vv; i = v->ob_size; + switch (i) { + case 0: return 0; + case 1: return v->ob_digit[0]; + } sign = 1; x = 0; if (i < 0) { @@ -371,6 +540,41 @@ PyLong_AsUnsignedLongMask(PyObject *vv) return x * sign; } +unsigned long +PyLong_AsUnsignedLongMask(register PyObject *op) +{ + PyNumberMethods *nb; + PyLongObject *lo; + unsigned long val; + + if (op && PyLong_Check(op)) + return _PyLong_AsUnsignedLongMask(op); + + if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL || + nb->nb_int == NULL) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return (unsigned long)-1; + } + + lo = (PyLongObject*) (*nb->nb_int) (op); + if (lo == NULL) + return (unsigned long)-1; + if (PyLong_Check(lo)) { + val = _PyLong_AsUnsignedLongMask((PyObject *)lo); + Py_DECREF(lo); + if (PyErr_Occurred()) + return (unsigned long)-1; + return val; + } + else + { + Py_DECREF(lo); + PyErr_SetString(PyExc_TypeError, + "nb_int should return int object"); + return (unsigned long)-1; + } +} + int _PyLong_Sign(PyObject *vv) { @@ -409,7 +613,7 @@ _PyLong_NumBits(PyObject *vv) return result; Overflow: - PyErr_SetString(PyExc_OverflowError, "long has too many bits " + PyErr_SetString(PyExc_OverflowError, "int has too many bits " "to express in a platform size_t"); return (size_t)-1; } @@ -542,7 +746,7 @@ _PyLong_AsByteArray(PyLongObject* v, ndigits = -(v->ob_size); if (!is_signed) { PyErr_SetString(PyExc_TypeError, - "can't convert negative long to unsigned"); + "can't convert negative int to unsigned"); return -1; } do_twos_comp = 1; @@ -653,7 +857,7 @@ _PyLong_AsByteArray(PyLongObject* v, return 0; Overflow: - PyErr_SetString(PyExc_OverflowError, "long too big to convert"); + PyErr_SetString(PyExc_OverflowError, "int too big to convert"); return -1; } @@ -739,7 +943,7 @@ PyLong_AsDouble(PyObject *vv) overflow: PyErr_SetString(PyExc_OverflowError, - "long int too large to convert to float"); + "int too large to convert to float"); return -1.0; } @@ -748,24 +952,17 @@ overflow: PyObject * PyLong_FromVoidPtr(void *p) { -#if SIZEOF_VOID_P <= SIZEOF_LONG - if ((long)p < 0) - return PyLong_FromUnsignedLong((unsigned long)p); - return PyInt_FromLong((long)p); -#else - #ifndef HAVE_LONG_LONG # error "PyLong_FromVoidPtr: sizeof(void*) > sizeof(long), but no long long" #endif #if SIZEOF_LONG_LONG < SIZEOF_VOID_P # error "PyLong_FromVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)" #endif - /* optimize null pointers */ - if (p == NULL) + /* special-case null pointer */ + if (!p) return PyInt_FromLong(0); - return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)p); + return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)(Py_uintptr_t)p); -#endif /* SIZEOF_VOID_P <= SIZEOF_LONG */ } /* Get a C pointer from a long object (or an int object in some cases) */ @@ -780,9 +977,7 @@ PyLong_AsVoidPtr(PyObject *vv) #if SIZEOF_VOID_P <= SIZEOF_LONG long x; - if (PyInt_Check(vv)) - x = PyInt_AS_LONG(vv); - else if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0) + if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0) x = PyLong_AsLong(vv); else x = PyLong_AsUnsignedLong(vv); @@ -796,9 +991,7 @@ PyLong_AsVoidPtr(PyObject *vv) #endif PY_LONG_LONG x; - if (PyInt_Check(vv)) - x = PyInt_AS_LONG(vv); - else if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0) + if (PyLong_Check(vv) && _PyLong_Sign(vv) < 0) x = PyLong_AsLongLong(vv); else x = PyLong_AsUnsignedLongLong(vv); @@ -828,6 +1021,7 @@ PyLong_FromLongLong(PY_LONG_LONG ival) int ndigits = 0; int negative = 0; + CHECK_SMALL_INT(ival); if (ival < 0) { ival = -ival; negative = 1; @@ -864,6 +1058,8 @@ PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG ival) unsigned PY_LONG_LONG t; int ndigits = 0; + if (ival < BASE) + return PyLong_FromLong(ival); /* Count the number of Python digits. */ t = (unsigned PY_LONG_LONG)ival; while (t) { @@ -885,22 +1081,26 @@ PyLong_FromUnsignedLongLong(unsigned PY_LONG_LONG ival) /* Create a new long int object from a C Py_ssize_t. */ PyObject * -_PyLong_FromSsize_t(Py_ssize_t ival) +PyLong_FromSsize_t(Py_ssize_t ival) { Py_ssize_t bytes = ival; int one = 1; + if (ival < BASE) + return PyLong_FromLong(ival); return _PyLong_FromByteArray( (unsigned char *)&bytes, - SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 0); + SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 1); } /* Create a new long int object from a C size_t. */ PyObject * -_PyLong_FromSize_t(size_t ival) +PyLong_FromSize_t(size_t ival) { size_t bytes = ival; int one = 1; + if (ival < BASE) + return PyLong_FromLong(ival); return _PyLong_FromByteArray( (unsigned char *)&bytes, SIZEOF_SIZE_T, IS_LITTLE_ENDIAN, 0); @@ -912,6 +1112,7 @@ _PyLong_FromSize_t(size_t ival) PY_LONG_LONG PyLong_AsLongLong(PyObject *vv) { + PyLongObject *v; PY_LONG_LONG bytes; int one = 1; int res; @@ -923,8 +1124,6 @@ PyLong_AsLongLong(PyObject *vv) if (!PyLong_Check(vv)) { PyNumberMethods *nb; PyObject *io; - if (PyInt_Check(vv)) - return (PY_LONG_LONG)PyInt_AsLong(vv); if ((nb = vv->ob_type->tp_as_number) == NULL || nb->nb_int == NULL) { PyErr_SetString(PyExc_TypeError, "an integer is required"); @@ -933,11 +1132,6 @@ PyLong_AsLongLong(PyObject *vv) io = (*nb->nb_int) (vv); if (io == NULL) return -1; - if (PyInt_Check(io)) { - bytes = PyInt_AsLong(io); - Py_DECREF(io); - return bytes; - } if (PyLong_Check(io)) { bytes = PyLong_AsLongLong(io); Py_DECREF(io); @@ -948,6 +1142,12 @@ PyLong_AsLongLong(PyObject *vv) return -1; } + v = (PyLongObject*)vv; + switch(v->ob_size) { + case -1: return -v->ob_digit[0]; + case 0: return 0; + case 1: return v->ob_digit[0]; + } res = _PyLong_AsByteArray( (PyLongObject *)vv, (unsigned char *)&bytes, SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1); @@ -965,6 +1165,7 @@ PyLong_AsLongLong(PyObject *vv) unsigned PY_LONG_LONG PyLong_AsUnsignedLongLong(PyObject *vv) { + PyLongObject *v; unsigned PY_LONG_LONG bytes; int one = 1; int res; @@ -974,6 +1175,12 @@ PyLong_AsUnsignedLongLong(PyObject *vv) return (unsigned PY_LONG_LONG)-1; } + v = (PyLongObject*)vv; + switch(v->ob_size) { + case 0: return 0; + case 1: return v->ob_digit[0]; + } + res = _PyLong_AsByteArray( (PyLongObject *)vv, (unsigned char *)&bytes, SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0); @@ -988,8 +1195,8 @@ PyLong_AsUnsignedLongLong(PyObject *vv) /* Get a C unsigned long int from a long int object, ignoring the high bits. Returns -1 and sets an error condition if an error occurs. */ -unsigned PY_LONG_LONG -PyLong_AsUnsignedLongLongMask(PyObject *vv) +static unsigned PY_LONG_LONG +_PyLong_AsUnsignedLongLongMask(PyObject *vv) { register PyLongObject *v; unsigned PY_LONG_LONG x; @@ -1001,6 +1208,10 @@ PyLong_AsUnsignedLongLongMask(PyObject *vv) return (unsigned long) -1; } v = (PyLongObject *)vv; + switch(v->ob_size) { + case 0: return 0; + case 1: return v->ob_digit[0]; + } i = v->ob_size; sign = 1; x = 0; @@ -1013,6 +1224,41 @@ PyLong_AsUnsignedLongLongMask(PyObject *vv) } return x * sign; } + +unsigned PY_LONG_LONG +PyLong_AsUnsignedLongLongMask(register PyObject *op) +{ + PyNumberMethods *nb; + PyLongObject *lo; + unsigned PY_LONG_LONG val; + + if (op && PyLong_Check(op)) + return _PyLong_AsUnsignedLongLongMask(op); + + if (op == NULL || (nb = op->ob_type->tp_as_number) == NULL || + nb->nb_int == NULL) { + PyErr_SetString(PyExc_TypeError, "an integer is required"); + return (unsigned PY_LONG_LONG)-1; + } + + lo = (PyLongObject*) (*nb->nb_int) (op); + if (lo == NULL) + return (unsigned PY_LONG_LONG)-1; + if (PyLong_Check(lo)) { + val = _PyLong_AsUnsignedLongLongMask((PyObject *)lo); + Py_DECREF(lo); + if (PyErr_Occurred()) + return (unsigned PY_LONG_LONG)-1; + return val; + } + else + { + Py_DECREF(lo); + PyErr_SetString(PyExc_TypeError, + "nb_int should return int object"); + return (unsigned PY_LONG_LONG)-1; + } +} #undef IS_LITTLE_ENDIAN #endif /* HAVE_LONG_LONG */ @@ -1024,9 +1270,6 @@ convert_binop(PyObject *v, PyObject *w, PyLongObject **a, PyLongObject **b) { *a = (PyLongObject *) v; Py_INCREF(v); } - else if (PyInt_Check(v)) { - *a = (PyLongObject *) PyLong_FromLong(PyInt_AS_LONG(v)); - } else { return 0; } @@ -1034,9 +1277,6 @@ convert_binop(PyObject *v, PyObject *w, PyLongObject **a, PyLongObject **b) { *b = (PyLongObject *) w; Py_INCREF(w); } - else if (PyInt_Check(w)) { - *b = (PyLongObject *) PyLong_FromLong(PyInt_AS_LONG(w)); - } else { Py_DECREF(*a); return 0; @@ -1206,7 +1446,7 @@ long_format(PyObject *aa, int base) sz = i + j / bits; if (j / SHIFT < size_a || sz < i) { PyErr_SetString(PyExc_OverflowError, - "long is too large to format"); + "int is too large to format"); return NULL; } str = (PyStringObject *) PyString_FromStringAndSize((char *)0, sz); @@ -1386,7 +1626,7 @@ long_from_binary_base(char **str, int base) n = (p - start) * bits_per_char + SHIFT - 1; if (n / bits_per_char < p - start) { PyErr_SetString(PyExc_ValueError, - "long string too large to convert"); + "int string too large to convert"); return NULL; } n = n / SHIFT; @@ -1433,7 +1673,7 @@ PyLong_FromString(char *str, char **pend, int base) if ((base != 0 && base < 2) || base > 36) { PyErr_SetString(PyExc_ValueError, - "long() arg 2 must be >= 2 and <= 36"); + "int() arg 2 must be >= 2 and <= 36"); return NULL; } while (*str != '\0' && isspace(Py_CHARMASK(*str))) @@ -1683,7 +1923,7 @@ digit beyond the first. if (strrepr == NULL) return NULL; PyErr_Format(PyExc_ValueError, - "invalid literal for long() with base %d: %s", + "invalid literal for int() with base %d: %s", base, PyString_AS_STRING(strrepr)); Py_DECREF(strrepr); return NULL; @@ -1727,14 +1967,14 @@ long_divrem(PyLongObject *a, PyLongObject *b, if (size_b == 0) { PyErr_SetString(PyExc_ZeroDivisionError, - "long division or modulo by zero"); + "integer division or modulo by zero"); return -1; } if (size_a < size_b || (size_a == size_b && a->ob_digit[size_a-1] < b->ob_digit[size_b-1])) { /* |a| < |b|. */ - *pdiv = _PyLong_New(0); + *pdiv = (PyLongObject*)PyLong_FromLong(0); Py_INCREF(a); *prem = (PyLongObject *) a; return 0; @@ -1756,9 +1996,9 @@ long_divrem(PyLongObject *a, PyLongObject *b, the remainder r has the sign of a, so a = b*z + r. */ if ((a->ob_size < 0) != (b->ob_size < 0)) - z->ob_size = -(z->ob_size); + NEGATE(z); if (a->ob_size < 0 && (*prem)->ob_size != 0) - (*prem)->ob_size = -((*prem)->ob_size); + NEGATE(*prem); *pdiv = z; return 0; } @@ -1922,6 +2162,11 @@ long_hash(PyLongObject *v) same value hash to the same value, otherwise comparisons of mapping keys will turn out weird */ i = v->ob_size; + switch(i) { + case -1: return v->ob_digit[0]==1 ? -2 : -v->ob_digit[0]; + case 0: return 0; + case 1: return v->ob_digit[0]; + } sign = 1; x = 0; if (i < 0) { @@ -2027,7 +2272,7 @@ x_sub(PyLongObject *a, PyLongObject *b) } assert(borrow == 0); if (sign < 0) - z->ob_size = -(z->ob_size); + NEGATE(z); return long_normalize(z); } @@ -2038,6 +2283,9 @@ long_add(PyLongObject *v, PyLongObject *w) CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b); + if (ABS(a->ob_size) <= 1 && ABS(b->ob_size) <= 1) + return PyInt_FromLong(MEDIUM_VALUE(a) + + MEDIUM_VALUE(b)); if (a->ob_size < 0) { if (b->ob_size < 0) { z = x_add(a, b); @@ -2065,6 +2313,8 @@ long_sub(PyLongObject *v, PyLongObject *w) CONVERT_BINOP((PyObject *)v, (PyObject *)w, &a, &b); + if (ABS(a->ob_size) <= 1 && ABS(b->ob_size) <= 1) + return PyLong_FromLong(MEDIUM_VALUE(a)-MEDIUM_VALUE(b)); if (a->ob_size < 0) { if (b->ob_size < 0) z = x_sub(a, b); @@ -2494,10 +2744,13 @@ long_mul(PyLongObject *v, PyLongObject *w) return Py_NotImplemented; } + if (ABS(v->ob_size) <= 1 && ABS(w->ob_size) <= 1) + return PyLong_FromLong(MEDIUM_VALUE(v)*MEDIUM_VALUE(w)); + z = k_mul(a, b); /* Negate if exactly one of the inputs is negative. */ if (((a->ob_size ^ b->ob_size) < 0) && z) - z->ob_size = -(z->ob_size); + NEGATE(z); Py_DECREF(a); Py_DECREF(b); return (PyObject *)z; @@ -2603,7 +2856,7 @@ long_true_divide(PyObject *v, PyObject *w) if (bd == 0.0) { PyErr_SetString(PyExc_ZeroDivisionError, - "long division or modulo by zero"); + "int division or modulo by zero"); return NULL; } @@ -2622,7 +2875,7 @@ long_true_divide(PyObject *v, PyObject *w) overflow: PyErr_SetString(PyExc_OverflowError, - "long/long too large for a float"); + "int/int too large for a float"); return NULL; } @@ -2691,11 +2944,6 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) c = (PyLongObject *)x; Py_INCREF(x); } - else if (PyInt_Check(x)) { - c = (PyLongObject *)PyLong_FromLong(PyInt_AS_LONG(x)); - if (c == NULL) - goto Error; - } else if (x == Py_None) c = NULL; else { @@ -2741,7 +2989,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) Py_DECREF(c); c = temp; temp = NULL; - c->ob_size = - c->ob_size; + NEGATE(c); } /* if modulus == 1: @@ -2862,6 +3110,8 @@ long_invert(PyLongObject *v) /* Implement ~x as -(x+1) */ PyLongObject *x; PyLongObject *w; + if (ABS(v->ob_size) <=1) + return PyLong_FromLong(-(MEDIUM_VALUE(v)+1)); w = (PyLongObject *)PyLong_FromLong(1L); if (w == NULL) return NULL; @@ -2888,11 +3138,8 @@ static PyObject * long_neg(PyLongObject *v) { PyLongObject *z; - if (v->ob_size == 0 && PyLong_CheckExact(v)) { - /* -0 == 0 */ - Py_INCREF(v); - return (PyObject *) v; - } + if (ABS(v->ob_size) <= 1) + return PyLong_FromLong(-MEDIUM_VALUE(v)); z = (PyLongObject *)_PyLong_Copy(v); if (z != NULL) z->ob_size = -(v->ob_size); @@ -3016,7 +3263,7 @@ long_lshift(PyObject *v, PyObject *w) if (z == NULL) goto lshift_error; if (a->ob_size < 0) - z->ob_size = -(z->ob_size); + NEGATE(z); for (i = 0; i < wordshift; i++) z->ob_digit[i] = 0; accum = 0; @@ -3194,22 +3441,7 @@ long_long(PyObject *v) static PyObject * long_int(PyObject *v) { - long x; - x = PyLong_AsLong(v); - if (PyErr_Occurred()) { - if (PyErr_ExceptionMatches(PyExc_OverflowError)) { - PyErr_Clear(); - if (PyLong_CheckExact(v)) { - Py_INCREF(v); - return v; - } - else - return _PyLong_Copy((PyLongObject *)v); - } - else - return NULL; - } - return PyInt_FromLong(x); + return long_long(v); } static PyObject * @@ -3246,15 +3478,25 @@ long_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (type != &PyLong_Type) return long_subtype_new(type, args, kwds); /* Wimp out */ - if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:long", kwlist, + if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist, &x, &base)) return NULL; if (x == NULL) return PyLong_FromLong(0L); if (base == -909) return PyNumber_Long(x); - else if (PyString_Check(x)) - return PyLong_FromString(PyString_AS_STRING(x), NULL, base); + else if (PyString_Check(x)) { + char *s = PyString_AS_STRING(x); + char *end; + PyObject *r = PyLong_FromString(s, &end, base); + if (r != NULL && end != s + PyString_GET_SIZE(x)) { + PyErr_SetString(PyExc_ValueError, + "null byte in argument for int()"); + Py_DECREF(r); + r = NULL; + } + return r; + } #ifdef Py_USING_UNICODE else if (PyUnicode_Check(x)) return PyLong_FromUnicode(PyUnicode_AS_UNICODE(x), @@ -3263,7 +3505,7 @@ long_new(PyTypeObject *type, PyObject *args, PyObject *kwds) #endif else { PyErr_SetString(PyExc_TypeError, - "long() can't convert non-string with explicit base"); + "int() can't convert non-string with explicit base"); return NULL; } } @@ -3312,9 +3554,9 @@ static PyMethodDef long_methods[] = { }; PyDoc_STRVAR(long_doc, -"long(x[, base]) -> integer\n\ +"int(x[, base]) -> integer\n\ \n\ -Convert a string or number to a long integer, if possible. A floating\n\ +Convert a string or number to an integer, if possible. A floating\n\ point argument will be truncated towards zero (this does not include a\n\ string representation of a floating point number!) When converting a\n\ string, use the optional base. It is an error to supply a base when\n\ @@ -3363,8 +3605,10 @@ static PyNumberMethods long_as_number = { PyTypeObject PyLong_Type = { PyObject_HEAD_INIT(&PyType_Type) 0, /* ob_size */ - "long", /* tp_name */ - sizeof(PyLongObject) - sizeof(digit), /* tp_basicsize */ + "int", /* tp_name */ + /* See _PyLong_New for why this isn't + sizeof(PyLongObject) - sizeof(digit) */ + sizeof(PyVarObject), /* tp_basicsize */ sizeof(digit), /* tp_itemsize */ long_dealloc, /* tp_dealloc */ 0, /* tp_print */ @@ -3377,7 +3621,7 @@ PyTypeObject PyLong_Type = { 0, /* tp_as_mapping */ (hashfunc)long_hash, /* tp_hash */ 0, /* tp_call */ - 0, /* tp_str */ + long_repr, /* tp_str */ PyObject_GenericGetAttr, /* tp_getattro */ 0, /* tp_setattro */ 0, /* tp_as_buffer */ @@ -3402,3 +3646,43 @@ PyTypeObject PyLong_Type = { long_new, /* tp_new */ PyObject_Del, /* tp_free */ }; + +int +_PyLong_Init(void) +{ +#if NSMALLNEGINTS + NSMALLPOSINTS > 0 + int ival; + PyLongObject *v = small_ints; + for (ival = -NSMALLNEGINTS; ival < 0; ival++, v++) { + PyObject_INIT(v, &PyLong_Type); + v->ob_size = -1; + v->ob_digit[0] = -ival; + } + for (; ival < NSMALLPOSINTS; ival++, v++) { + PyObject_INIT(v, &PyLong_Type); + v->ob_size = ival ? 1 : 0; + v->ob_digit[0] = ival; + } +#endif + return 1; +} + +void +PyLong_Fini(void) +{ +#if 0 + int i; + /* This is currently not needed; the small integers + are statically allocated */ +#if NSMALLNEGINTS + NSMALLPOSINTS > 0 + PyIntObject **q; + + i = NSMALLNEGINTS + NSMALLPOSINTS; + q = small_ints; + while (--i >= 0) { + Py_XDECREF(*q); + *q++ = NULL; + } +#endif +#endif +} |