diff options
Diffstat (limited to 'Objects/longobject.c')
-rw-r--r-- | Objects/longobject.c | 198 |
1 files changed, 108 insertions, 90 deletions
diff --git a/Objects/longobject.c b/Objects/longobject.c index 4ae22ef31b..9411216bcb 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -17,7 +17,8 @@ #endif /* convert a PyLong of size 1, 0 or -1 to an sdigit */ -#define MEDIUM_VALUE(x) (Py_SIZE(x) < 0 ? -(sdigit)(x)->ob_digit[0] : \ +#define MEDIUM_VALUE(x) (assert(-1 <= Py_SIZE(x) && Py_SIZE(x) <= 1), \ + Py_SIZE(x) < 0 ? -(sdigit)(x)->ob_digit[0] : \ (Py_SIZE(x) == 0 ? (sdigit)0 : \ (sdigit)(x)->ob_digit[0])) #define ABS(x) ((x) < 0 ? -(x) : (x)) @@ -70,11 +71,21 @@ maybe_small_long(PyLongObject *v) /* If a freshly-allocated int is already shared, it must be a small integer, so negating it must go to PyLong_FromLong */ -#define NEGATE(x) \ - do if (Py_REFCNT(x) == 1) Py_SIZE(x) = -Py_SIZE(x); \ - else { PyObject* tmp=PyLong_FromLong(-MEDIUM_VALUE(x)); \ - Py_DECREF(x); (x) = (PyLongObject*)tmp; } \ - while(0) +Py_LOCAL_INLINE(void) +_PyLong_Negate(PyLongObject **x_p) +{ + PyLongObject *x; + + x = (PyLongObject *)*x_p; + if (Py_REFCNT(x) == 1) { + Py_SIZE(x) = -Py_SIZE(x); + return; + } + + *x_p = (PyLongObject *)PyLong_FromLong(-MEDIUM_VALUE(x)); + Py_DECREF(x); +} + /* For int multiplication, use the O(N**2) school algorithm unless * both operands contain more than KARATSUBA_CUTOFF digits (this * being an internal Python int digit, in base BASE). @@ -89,11 +100,6 @@ maybe_small_long(PyLongObject *v) */ #define FIVEARY_CUTOFF 8 -#undef MIN -#undef MAX -#define MAX(x, y) ((x) < (y) ? (y) : (x)) -#define MIN(x, y) ((x) > (y) ? (y) : (x)) - #define SIGCHECK(PyTryBlock) \ do { \ if (PyErr_CheckSignals()) PyTryBlock \ @@ -104,7 +110,7 @@ maybe_small_long(PyLongObject *v) of the algorithms used, this could save at most be one word anyway. */ static PyLongObject * -long_normalize(register PyLongObject *v) +long_normalize(PyLongObject *v) { Py_ssize_t j = ABS(Py_SIZE(v)); Py_ssize_t i = j; @@ -153,6 +159,15 @@ _PyLong_FromNbInt(PyObject *integral) Py_DECREF(result); return NULL; } + /* Issue #17576: warn if 'result' not of exact type int. */ + if (PyErr_WarnFormat(PyExc_DeprecationWarning, 1, + "__int__ returned non-int (type %.200s). " + "The ability to return an instance of a strict subclass of int " + "is deprecated, and may be removed in a future version of Python.", + result->ob_type->tp_name)) { + Py_DECREF(result); + return NULL; + } return (PyLongObject *)result; } @@ -375,7 +390,7 @@ long PyLong_AsLongAndOverflow(PyObject *vv, int *overflow) { /* This version by Tim Peters */ - register PyLongObject *v; + PyLongObject *v; unsigned long x, prev; long res; Py_ssize_t i; @@ -487,7 +502,7 @@ _PyLong_AsInt(PyObject *obj) Py_ssize_t PyLong_AsSsize_t(PyObject *vv) { - register PyLongObject *v; + PyLongObject *v; size_t x, prev; Py_ssize_t i; int sign; @@ -543,7 +558,7 @@ PyLong_AsSsize_t(PyObject *vv) { unsigned long PyLong_AsUnsignedLong(PyObject *vv) { - register PyLongObject *v; + PyLongObject *v; unsigned long x, prev; Py_ssize_t i; @@ -573,7 +588,7 @@ PyLong_AsUnsignedLong(PyObject *vv) x = (x << PyLong_SHIFT) | v->ob_digit[i]; if ((x >> PyLong_SHIFT) != prev) { PyErr_SetString(PyExc_OverflowError, - "python int too large to convert " + "Python int too large to convert " "to C unsigned long"); return (unsigned long) -1; } @@ -587,7 +602,7 @@ PyLong_AsUnsignedLong(PyObject *vv) size_t PyLong_AsSize_t(PyObject *vv) { - register PyLongObject *v; + PyLongObject *v; size_t x, prev; Py_ssize_t i; @@ -630,7 +645,7 @@ PyLong_AsSize_t(PyObject *vv) static unsigned long _PyLong_AsUnsignedLongMask(PyObject *vv) { - register PyLongObject *v; + PyLongObject *v; unsigned long x; Py_ssize_t i; int sign; @@ -658,7 +673,7 @@ _PyLong_AsUnsignedLongMask(PyObject *vv) } unsigned long -PyLong_AsUnsignedLongMask(register PyObject *op) +PyLong_AsUnsignedLongMask(PyObject *op) { PyLongObject *lo; unsigned long val; @@ -973,9 +988,6 @@ PyObject * PyLong_FromVoidPtr(void *p) { #if SIZEOF_VOID_P <= SIZEOF_LONG - /* special-case null pointer */ - if (!p) - return PyLong_FromLong(0); return PyLong_FromUnsignedLong((unsigned long)(Py_uintptr_t)p); #else @@ -985,9 +997,6 @@ PyLong_FromVoidPtr(void *p) #if SIZEOF_LONG_LONG < SIZEOF_VOID_P # error "PyLong_FromVoidPtr: sizeof(PY_LONG_LONG) < sizeof(void*)" #endif - /* special-case null pointer */ - if (!p) - return PyLong_FromLong(0); return PyLong_FromUnsignedLongLong((unsigned PY_LONG_LONG)(Py_uintptr_t)p); #endif /* SIZEOF_VOID_P <= SIZEOF_LONG */ @@ -1033,7 +1042,6 @@ PyLong_AsVoidPtr(PyObject *vv) * rewritten to use the newer PyLong_{As,From}ByteArray API. */ -#define IS_LITTLE_ENDIAN (int)*(unsigned char*)&one #define PY_ABS_LLONG_MIN (0-(unsigned PY_LONG_LONG)PY_LLONG_MIN) /* Create a new int object from a C PY_LONG_LONG int. */ @@ -1186,7 +1194,6 @@ PyLong_AsLongLong(PyObject *vv) { PyLongObject *v; PY_LONG_LONG bytes; - int one = 1; int res; int do_decref = 0; /* if nb_int was called */ @@ -1218,7 +1225,7 @@ PyLong_AsLongLong(PyObject *vv) break; default: res = _PyLong_AsByteArray((PyLongObject *)v, (unsigned char *)&bytes, - SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 1); + SIZEOF_LONG_LONG, PY_LITTLE_ENDIAN, 1); } if (do_decref) { Py_DECREF(v); @@ -1239,7 +1246,6 @@ PyLong_AsUnsignedLongLong(PyObject *vv) { PyLongObject *v; unsigned PY_LONG_LONG bytes; - int one = 1; int res; if (vv == NULL) { @@ -1258,7 +1264,7 @@ PyLong_AsUnsignedLongLong(PyObject *vv) } res = _PyLong_AsByteArray((PyLongObject *)vv, (unsigned char *)&bytes, - SIZEOF_LONG_LONG, IS_LITTLE_ENDIAN, 0); + SIZEOF_LONG_LONG, PY_LITTLE_ENDIAN, 0); /* Plan 9 can't handle PY_LONG_LONG in ? : expressions */ if (res < 0) @@ -1273,7 +1279,7 @@ PyLong_AsUnsignedLongLong(PyObject *vv) static unsigned PY_LONG_LONG _PyLong_AsUnsignedLongLongMask(PyObject *vv) { - register PyLongObject *v; + PyLongObject *v; unsigned PY_LONG_LONG x; Py_ssize_t i; int sign; @@ -1301,7 +1307,7 @@ _PyLong_AsUnsignedLongLongMask(PyObject *vv) } unsigned PY_LONG_LONG -PyLong_AsUnsignedLongLongMask(register PyObject *op) +PyLong_AsUnsignedLongLongMask(PyObject *op) { PyLongObject *lo; unsigned PY_LONG_LONG val; @@ -1323,7 +1329,6 @@ PyLong_AsUnsignedLongLongMask(register PyObject *op) Py_DECREF(lo); return val; } -#undef IS_LITTLE_ENDIAN /* Get a C long long int from an int object or any object that has an __int__ method. @@ -1339,7 +1344,7 @@ PY_LONG_LONG PyLong_AsLongLongAndOverflow(PyObject *vv, int *overflow) { /* This version by Tim Peters */ - register PyLongObject *v; + PyLongObject *v; unsigned PY_LONG_LONG x, prev; PY_LONG_LONG res; Py_ssize_t i; @@ -1604,7 +1609,7 @@ long_to_decimal_string_internal(PyObject *aa, */ if (size_a > PY_SSIZE_T_MAX / PyLong_SHIFT) { PyErr_SetString(PyExc_OverflowError, - "long is too large to format"); + "int too large to format"); return -1; } /* the expression size_a * PyLong_SHIFT is now safe from overflow */ @@ -1674,7 +1679,6 @@ long_to_decimal_string_internal(PyObject *aa, else \ p = (TYPE*)PyUnicode_DATA(str) + strlen; \ \ - *p = '\0'; \ /* pout[0] through pout[size-2] contribute exactly \ _PyLong_DECIMAL_SHIFT digits each */ \ for (i=0; i < size - 1; i++) { \ @@ -1747,7 +1751,7 @@ static int long_format_binary(PyObject *aa, int base, int alternate, PyObject **p_output, _PyUnicodeWriter *writer) { - register PyLongObject *a = (PyLongObject *)aa; + PyLongObject *a = (PyLongObject *)aa; PyObject *v; Py_ssize_t sz; Py_ssize_t size_a; @@ -1788,7 +1792,7 @@ long_format_binary(PyObject *aa, int base, int alternate, /* Ensure overflow doesn't occur during computation of sz. */ if (size_a > (PY_SSIZE_T_MAX - 3) / PyLong_SHIFT) { PyErr_SetString(PyExc_OverflowError, - "int is too large to format"); + "int too large to format"); return -1; } size_a_in_bits = (size_a - 1) * PyLong_SHIFT + @@ -1944,10 +1948,10 @@ unsigned char _PyLong_DigitValue[256] = { * string characters. */ static PyLongObject * -long_from_binary_base(char **str, int base) +long_from_binary_base(const char **str, int base) { - char *p = *str; - char *start = p; + const char *p = *str; + const char *start = p; int bits_per_char; Py_ssize_t n; PyLongObject *z; @@ -2012,10 +2016,10 @@ long_from_binary_base(char **str, int base) * If unsuccessful, NULL will be returned. */ PyObject * -PyLong_FromString(char *str, char **pend, int base) +PyLong_FromString(const char *str, char **pend, int base) { int sign = 1, error_if_nonzero = 0; - char *start, *orig_str = str; + const char *start, *orig_str = str; PyLongObject *z = NULL; PyObject *strobj; Py_ssize_t slen; @@ -2144,13 +2148,13 @@ that triggers it(!). Instead the code was tested by artificially allocating just 1 digit at the start, so that the copying code was exercised for every digit beyond the first. ***/ - register twodigits c; /* current input character */ + twodigits c; /* current input character */ Py_ssize_t size_z; int i; int convwidth; twodigits convmultmax, convmult; digit *pz, *pzstop; - char* scan; + const char* scan; static double log_base_BASE[37] = {0.0e0,}; static int convwidth_base[37] = {0,}; @@ -2278,19 +2282,19 @@ digit beyond the first. if (z == NULL) return NULL; if (pend != NULL) - *pend = str; + *pend = (char *)str; return (PyObject *) z; onError: if (pend != NULL) - *pend = str; + *pend = (char *)str; Py_XDECREF(z); slen = strlen(orig_str) < 200 ? strlen(orig_str) : 200; strobj = PyUnicode_FromStringAndSize(orig_str, slen); if (strobj == NULL) return NULL; PyErr_Format(PyExc_ValueError, - "invalid literal for int() with base %d: %R", + "invalid literal for int() with base %d: %.200R", base, strobj); Py_DECREF(strobj); return NULL; @@ -2314,7 +2318,7 @@ _PyLong_FromBytes(const char *s, Py_ssize_t len, int base) strobj = PyBytes_FromStringAndSize(s, Py_MIN(len, 200)); if (strobj != NULL) { PyErr_Format(PyExc_ValueError, - "invalid literal for int() with base %d: %R", + "invalid literal for int() with base %d: %.200R", base, strobj); Py_DECREF(strobj); } @@ -2335,7 +2339,7 @@ PyLong_FromUnicode(Py_UNICODE *u, Py_ssize_t length, int base) PyObject * PyLong_FromUnicodeObject(PyObject *u, int base) { - PyObject *result, *asciidig, *strobj; + PyObject *result, *asciidig; char *buffer, *end = NULL; Py_ssize_t buflen; @@ -2357,13 +2361,9 @@ PyLong_FromUnicodeObject(PyObject *u, int base) Py_DECREF(asciidig); Py_XDECREF(result); } - strobj = PySequence_GetSlice(u, 0, 200); - if (strobj != NULL) { - PyErr_Format(PyExc_ValueError, - "invalid literal for int() with base %d: %R", - base, strobj); - Py_DECREF(strobj); - } + PyErr_Format(PyExc_ValueError, + "invalid literal for int() with base %d: %.200R", + base, u); return NULL; } @@ -2417,10 +2417,21 @@ long_divrem(PyLongObject *a, PyLongObject *b, The quotient z has the sign of a*b; the remainder r has the sign of a, so a = b*z + r. */ - if ((Py_SIZE(a) < 0) != (Py_SIZE(b) < 0)) - NEGATE(z); - if (Py_SIZE(a) < 0 && Py_SIZE(*prem) != 0) - NEGATE(*prem); + if ((Py_SIZE(a) < 0) != (Py_SIZE(b) < 0)) { + _PyLong_Negate(&z); + if (z == NULL) { + Py_CLEAR(*prem); + return -1; + } + } + if (Py_SIZE(a) < 0 && Py_SIZE(*prem) != 0) { + _PyLong_Negate(prem); + if (*prem == NULL) { + Py_DECREF(z); + Py_CLEAR(*prem); + return -1; + } + } *pdiv = maybe_small_long(z); return 0; } @@ -2696,7 +2707,7 @@ PyLong_AsDouble(PyObject *v) x = _PyLong_Frexp((PyLongObject *)v, &exponent); if ((x == -1.0 && PyErr_Occurred()) || exponent > DBL_MAX_EXP) { PyErr_SetString(PyExc_OverflowError, - "long int too large to convert to float"); + "int too large to convert to float"); return -1.0; } return ldexp(x, (int)exponent); @@ -2916,8 +2927,11 @@ x_sub(PyLongObject *a, PyLongObject *b) borrow &= 1; /* Keep only one sign bit */ } assert(borrow == 0); - if (sign < 0) - NEGATE(z); + if (sign < 0) { + _PyLong_Negate(&z); + if (z == NULL) + return NULL; + } return long_normalize(z); } @@ -3084,7 +3098,7 @@ kmul_split(PyLongObject *n, Py_ssize_t size_lo, size_hi; const Py_ssize_t size_n = ABS(Py_SIZE(n)); - size_lo = MIN(size_n, size); + size_lo = Py_MIN(size_n, size); size_hi = size_n - size_lo; if ((hi = _PyLong_New(size_hi)) == NULL) @@ -3355,7 +3369,7 @@ k_lopsided_mul(PyLongObject *a, PyLongObject *b) nbdone = 0; while (bsize > 0) { PyLongObject *product; - const Py_ssize_t nbtouse = MIN(bsize, asize); + const Py_ssize_t nbtouse = Py_MIN(bsize, asize); /* Multiply the next slice of b by a. */ memcpy(bslice->ob_digit, b->ob_digit + nbdone, @@ -3408,8 +3422,11 @@ long_mul(PyLongObject *a, PyLongObject *b) z = k_mul(a, b); /* Negate if exactly one of the inputs is negative. */ - if (((Py_SIZE(a) ^ Py_SIZE(b)) < 0) && z) - NEGATE(z); + if (((Py_SIZE(a) ^ Py_SIZE(b)) < 0) && z) { + _PyLong_Negate(&z); + if (z == NULL) + return NULL; + } return (PyObject *)z; } @@ -3646,7 +3663,7 @@ long_true_divide(PyObject *v, PyObject *w) goto underflow_or_zero; /* Choose value for shift; see comments for step 1 above. */ - shift = MAX(diff, DBL_MIN_EXP) - DBL_MANT_DIG - 2; + shift = Py_MAX(diff, DBL_MIN_EXP) - DBL_MANT_DIG - 2; inexact = 0; @@ -3717,7 +3734,7 @@ long_true_divide(PyObject *v, PyObject *w) x_bits = (x_size-1)*PyLong_SHIFT+bits_in_digit(x->ob_digit[x_size-1]); /* The number of extra bits that have to be rounded away. */ - extra_bits = MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG; + extra_bits = Py_MAX(x_bits, DBL_MIN_EXP - shift) - DBL_MANT_DIG; assert(extra_bits == 2 || extra_bits == 3); /* Round by directly modifying the low digit of x. */ @@ -3856,7 +3873,9 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) Py_DECREF(c); c = temp; temp = NULL; - NEGATE(c); + _PyLong_Negate(&c); + if (c == NULL) + goto Error; } /* if modulus == 1: @@ -3962,10 +3981,7 @@ long_pow(PyObject *v, PyObject *w, PyObject *x) goto Done; Error: - if (z != NULL) { - Py_DECREF(z); - z = NULL; - } + Py_CLEAR(z); /* fall through */ Done: if (Py_SIZE(b) > FIVEARY_CUTOFF) { @@ -4095,10 +4111,10 @@ long_lshift(PyObject *v, PyObject *w) shiftby = PyLong_AsSsize_t((PyObject *)b); if (shiftby == -1L && PyErr_Occurred()) - goto lshift_error; + return NULL; if (shiftby < 0) { PyErr_SetString(PyExc_ValueError, "negative shift count"); - goto lshift_error; + return NULL; } /* wordshift, remshift = divmod(shiftby, PyLong_SHIFT) */ wordshift = shiftby / PyLong_SHIFT; @@ -4110,9 +4126,11 @@ long_lshift(PyObject *v, PyObject *w) ++newsize; z = _PyLong_New(newsize); if (z == NULL) - goto lshift_error; - if (Py_SIZE(a) < 0) - NEGATE(z); + return NULL; + if (Py_SIZE(a) < 0) { + assert(Py_REFCNT(z) == 1); + Py_SIZE(z) = -Py_SIZE(z); + } for (i = 0; i < wordshift; i++) z->ob_digit[i] = 0; accum = 0; @@ -4126,7 +4144,6 @@ long_lshift(PyObject *v, PyObject *w) else assert(!accum); z = long_normalize(z); - lshift_error: return (PyObject *) maybe_small_long(z); } @@ -4151,7 +4168,7 @@ v_complement(digit *z, digit *a, Py_ssize_t m) static PyObject * long_bitwise(PyLongObject *a, - int op, /* '&', '|', '^' */ + char op, /* '&', '|', '^' */ PyLongObject *b) { int nega, negb, negz; @@ -4326,8 +4343,7 @@ static PyObject * long_new(PyTypeObject *type, PyObject *args, PyObject *kwds) { PyObject *obase = NULL, *x = NULL; - long base; - int overflow; + Py_ssize_t base; static char *kwlist[] = {"x", "base", 0}; if (type != &PyLong_Type) @@ -4346,10 +4362,10 @@ long_new(PyTypeObject *type, PyObject *args, PyObject *kwds) if (obase == NULL) return PyNumber_Long(x); - base = PyLong_AsLongAndOverflow(obase, &overflow); + base = PyNumber_AsSsize_t(obase, NULL); if (base == -1 && PyErr_Occurred()) return NULL; - if (overflow || (base != 0 && base < 2) || base > 36) { + if ((base != 0 && base < 2) || base > 36) { PyErr_SetString(PyExc_ValueError, "int() base must be >= 2 and <= 36"); return NULL; @@ -4430,7 +4446,7 @@ long__format__(PyObject *self, PyObject *args) if (!PyArg_ParseTuple(args, "U:__format__", &format_spec)) return NULL; - _PyUnicodeWriter_Init(&writer, 0); + _PyUnicodeWriter_Init(&writer); ret = _PyLong_FormatAdvancedWriter( &writer, self, @@ -5080,15 +5096,17 @@ _PyLong_Init(void) assert(v->ob_digit[0] == abs(ival)); } else { - PyObject_INIT(v, &PyLong_Type); + (void)PyObject_INIT(v, &PyLong_Type); } Py_SIZE(v) = size; v->ob_digit[0] = abs(ival); } #endif /* initialize int_info */ - if (Int_InfoType.tp_name == 0) - PyStructSequence_InitType(&Int_InfoType, &int_info_desc); + if (Int_InfoType.tp_name == NULL) { + if (PyStructSequence_InitType2(&Int_InfoType, &int_info_desc) < 0) + return 0; + } return 1; } |