
/* Integer object implementation */

#include "Python.h"
#include <ctype.h>
#include <float.h>

static PyObject *int_int(PyIntObject *v);

long
PyInt_GetMax(void)
{
    return LONG_MAX;            /* To initialize sys.maxint */
}

/* Integers are quite normal objects, to make object handling uniform.
   (Using odd pointers to represent integers would save much space
   but require extra checks for this special case throughout the code.)
   Since a typical Python program spends much of its time allocating
   and deallocating integers, these operations should be very fast.
   Therefore we use a dedicated allocation scheme with a much lower
   overhead (in space and time) than straight malloc(): a simple
   dedicated free list, filled when necessary with memory from malloc().

   block_list is a singly-linked list of all PyIntBlocks ever allocated,
   linked via their next members.  PyIntBlocks are never returned to the
   system before shutdown (PyInt_Fini).

   free_list is a singly-linked list of available PyIntObjects, linked
   via abuse of their ob_type members.
*/

#define BLOCK_SIZE      1000    /* 1K less typical malloc overhead */
#define BHEAD_SIZE      8       /* Enough for a 64-bit pointer */
#define N_INTOBJECTS    ((BLOCK_SIZE - BHEAD_SIZE) / sizeof(PyIntObject))

struct _intblock {
    struct _intblock *next;
    PyIntObject objects[N_INTOBJECTS];
};

typedef struct _intblock PyIntBlock;

static PyIntBlock *block_list = NULL;
static PyIntObject *free_list = NULL;

static PyIntObject *
fill_free_list(void)
{
    PyIntObject *p, *q;
    /* Python's object allocator isn't appropriate for large blocks. */
    p = (PyIntObject *) PyMem_MALLOC(sizeof(PyIntBlock));
    if (p == NULL)
        return (PyIntObject *) PyErr_NoMemory();
    ((PyIntBlock *)p)->next = block_list;
    block_list = (PyIntBlock *)p;
    /* Link the int objects together, from rear to front, then return
       the address of the last int object in the block. */
    p = &((PyIntBlock *)p)->objects[0];
    q = p + N_INTOBJECTS;
    while (--q > p)
        Py_TYPE(q) = (struct _typeobject *)(q-1);
    Py_TYPE(q) = NULL;
    return p + N_INTOBJECTS - 1;
}

#ifndef NSMALLPOSINTS
#define NSMALLPOSINTS           257
#endif
#ifndef NSMALLNEGINTS
#define NSMALLNEGINTS           5
#endif
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
/* References to small integers are saved in this array so that they
   can be shared.
   The integers that are saved are those in the range
   -NSMALLNEGINTS (inclusive) to NSMALLPOSINTS (not inclusive).
*/
static PyIntObject *small_ints[NSMALLNEGINTS + NSMALLPOSINTS];
#endif
#ifdef COUNT_ALLOCS
Py_ssize_t quick_int_allocs;
Py_ssize_t quick_neg_int_allocs;
#endif

PyObject *
PyInt_FromLong(long ival)
{
    register PyIntObject *v;
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
    if (-NSMALLNEGINTS <= ival && ival < NSMALLPOSINTS) {
        v = small_ints[ival + NSMALLNEGINTS];
        Py_INCREF(v);
#ifdef COUNT_ALLOCS
        if (ival >= 0)
            quick_int_allocs++;
        else
            quick_neg_int_allocs++;
#endif
        return (PyObject *) v;
    }
#endif
    if (free_list == NULL) {
        if ((free_list = fill_free_list()) == NULL)
            return NULL;
    }
    /* Inline PyObject_New */
    v = free_list;
    free_list = (PyIntObject *)Py_TYPE(v);
    PyObject_INIT(v, &PyInt_Type);
    v->ob_ival = ival;
    return (PyObject *) v;
}

PyObject *
PyInt_FromSize_t(size_t ival)
{
    if (ival <= LONG_MAX)
        return PyInt_FromLong((long)ival);
    return _PyLong_FromSize_t(ival);
}

PyObject *
PyInt_FromSsize_t(Py_ssize_t ival)
{
    if (ival >= LONG_MIN && ival <= LONG_MAX)
        return PyInt_FromLong((long)ival);
    return _PyLong_FromSsize_t(ival);
}

static void
int_dealloc(PyIntObject *v)
{
    if (PyInt_CheckExact(v)) {
        Py_TYPE(v) = (struct _typeobject *)free_list;
        free_list = v;
    }
    else
        Py_TYPE(v)->tp_free((PyObject *)v);
}

static void
int_free(PyIntObject *v)
{
    Py_TYPE(v) = (struct _typeobject *)free_list;
    free_list = v;
}

long
PyInt_AsLong(register PyObject *op)
{
    PyNumberMethods *nb;
    PyIntObject *io;
    long val;

    if (op && PyInt_Check(op))
        return PyInt_AS_LONG((PyIntObject*) op);

    if (op == NULL || (nb = Py_TYPE(op)->tp_as_number) == NULL ||
        nb->nb_int == NULL) {
        PyErr_SetString(PyExc_TypeError, "an integer is required");
        return -1;
    }

    io = (PyIntObject*) (*nb->nb_int) (op);
    if (io == NULL)
        return -1;
    if (!PyInt_Check(io)) {
        if (PyLong_Check(io)) {
            /* got a long? => retry int conversion */
            val = PyLong_AsLong((PyObject *)io);
            Py_DECREF(io);
            if ((val == -1) && PyErr_Occurred())
                return -1;
            return val;
        }
        else
        {
            Py_DECREF(io);
            PyErr_SetString(PyExc_TypeError,
                        "__int__ method should return an integer");
            return -1;
        }
    }

    val = PyInt_AS_LONG(io);
    Py_DECREF(io);

    return val;
}

int
_PyInt_AsInt(PyObject *obj)
{
    long result = PyInt_AsLong(obj);
    if (result == -1 && PyErr_Occurred())
        return -1;
    if (result > INT_MAX || result < INT_MIN) {
        PyErr_SetString(PyExc_OverflowError,
                        "Python int too large to convert to C int");
        return -1;
    }
    return (int)result;
}

Py_ssize_t
PyInt_AsSsize_t(register PyObject *op)
{
#if SIZEOF_SIZE_T != SIZEOF_LONG
    PyNumberMethods *nb;
    PyIntObject *io;
    Py_ssize_t val;
#endif

    if (op == NULL) {
        PyErr_SetString(PyExc_TypeError, "an integer is required");
        return -1;
    }

    if (PyInt_Check(op))
        return PyInt_AS_LONG((PyIntObject*) op);
    if (PyLong_Check(op))
        return _PyLong_AsSsize_t(op);
#if SIZEOF_SIZE_T == SIZEOF_LONG
    return PyInt_AsLong(op);
#else

    if ((nb = Py_TYPE(op)->tp_as_number) == NULL ||
        (nb->nb_int == NULL && nb->nb_long == 0)) {
        PyErr_SetString(PyExc_TypeError, "an integer is required");
        return -1;
    }

    if (nb->nb_long != 0)
        io = (PyIntObject*) (*nb->nb_long) (op);
    else
        io = (PyIntObject*) (*nb->nb_int) (op);
    if (io == NULL)
        return -1;
    if (!PyInt_Check(io)) {
        if (PyLong_Check(io)) {
            /* got a long? => retry int conversion */
            val = _PyLong_AsSsize_t((PyObject *)io);
            Py_DECREF(io);
            if ((val == -1) && PyErr_Occurred())
                return -1;
            return val;
        }
        else
        {
            Py_DECREF(io);
            PyErr_SetString(PyExc_TypeError,
                        "__int__ method should return an integer");
            return -1;
        }
    }

    val = PyInt_AS_LONG(io);
    Py_DECREF(io);

    return val;
#endif
}

unsigned long
PyInt_AsUnsignedLongMask(register PyObject *op)
{
    PyNumberMethods *nb;
    PyIntObject *io;
    unsigned long val;

    if (op && PyInt_Check(op))
        return PyInt_AS_LONG((PyIntObject*) op);
    if (op && PyLong_Check(op))
        return PyLong_AsUnsignedLongMask(op);

    if (op == NULL || (nb = Py_TYPE(op)->tp_as_number) == NULL ||
        nb->nb_int == NULL) {
        PyErr_SetString(PyExc_TypeError, "an integer is required");
        return (unsigned long)-1;
    }

    io = (PyIntObject*) (*nb->nb_int) (op);
    if (io == NULL)
        return (unsigned long)-1;
    if (!PyInt_Check(io)) {
        if (PyLong_Check(io)) {
            val = PyLong_AsUnsignedLongMask((PyObject *)io);
            Py_DECREF(io);
            if (PyErr_Occurred())
                return (unsigned long)-1;
            return val;
        }
        else
        {
            Py_DECREF(io);
            PyErr_SetString(PyExc_TypeError,
                        "__int__ method should return an integer");
            return (unsigned long)-1;
        }
    }

    val = PyInt_AS_LONG(io);
    Py_DECREF(io);

    return val;
}

#ifdef HAVE_LONG_LONG
unsigned PY_LONG_LONG
PyInt_AsUnsignedLongLongMask(register PyObject *op)
{
    PyNumberMethods *nb;
    PyIntObject *io;
    unsigned PY_LONG_LONG val;

    if (op && PyInt_Check(op))
        return PyInt_AS_LONG((PyIntObject*) op);
    if (op && PyLong_Check(op))
        return PyLong_AsUnsignedLongLongMask(op);

    if (op == NULL || (nb = Py_TYPE(op)->tp_as_number) == NULL ||
        nb->nb_int == NULL) {
        PyErr_SetString(PyExc_TypeError, "an integer is required");
        return (unsigned PY_LONG_LONG)-1;
    }

    io = (PyIntObject*) (*nb->nb_int) (op);
    if (io == NULL)
        return (unsigned PY_LONG_LONG)-1;
    if (!PyInt_Check(io)) {
        if (PyLong_Check(io)) {
            val = PyLong_AsUnsignedLongLongMask((PyObject *)io);
            Py_DECREF(io);
            if (PyErr_Occurred())
                return (unsigned PY_LONG_LONG)-1;
            return val;
        }
        else
        {
            Py_DECREF(io);
            PyErr_SetString(PyExc_TypeError,
                        "__int__ method should return an integer");
            return (unsigned PY_LONG_LONG)-1;
        }
    }

    val = PyInt_AS_LONG(io);
    Py_DECREF(io);

    return val;
}
#endif

PyObject *
PyInt_FromString(char *s, char **pend, int base)
{
    char *end;
    long x;
    Py_ssize_t slen;
    PyObject *sobj, *srepr;

    if ((base != 0 && base < 2) || base > 36) {
        PyErr_SetString(PyExc_ValueError,
                        "int() base must be >= 2 and <= 36");
        return NULL;
    }

    while (*s && isspace(Py_CHARMASK(*s)))
        s++;
    errno = 0;
    if (base == 0 && s[0] == '0') {
        x = (long) PyOS_strtoul(s, &end, base);
        if (x < 0)
            return PyLong_FromString(s, pend, base);
    }
    else
        x = PyOS_strtol(s, &end, base);
    if (end == s || !isalnum(Py_CHARMASK(end[-1])))
        goto bad;
    while (*end && isspace(Py_CHARMASK(*end)))
        end++;
    if (*end != '\0') {
  bad:
        slen = strlen(s) < 200 ? strlen(s) : 200;
        sobj = PyString_FromStringAndSize(s, slen);
        if (sobj == NULL)
            return NULL;
        srepr = PyObject_Repr(sobj);
        Py_DECREF(sobj);
        if (srepr == NULL)
            return NULL;
        PyErr_Format(PyExc_ValueError,
                     "invalid literal for int() with base %d: %s",
                     base, PyString_AS_STRING(srepr));
        Py_DECREF(srepr);
        return NULL;
    }
    else if (errno != 0)
        return PyLong_FromString(s, pend, base);
    if (pend)
        *pend = end;
    return PyInt_FromLong(x);
}

#ifdef Py_USING_UNICODE
PyObject *
PyInt_FromUnicode(Py_UNICODE *s, Py_ssize_t length, int base)
{
    PyObject *result;
    char *buffer = (char *)PyMem_MALLOC(length+1);

    if (buffer == NULL)
        return PyErr_NoMemory();

    if (PyUnicode_EncodeDecimal(s, length, buffer, NULL)) {
        PyMem_FREE(buffer);
        return NULL;
    }
    result = PyInt_FromString(buffer, NULL, base);
    PyMem_FREE(buffer);
    return result;
}
#endif

/* Methods */

/* Integers are seen as the "smallest" of all numeric types and thus
   don't have any knowledge about conversion of other types to
   integers. */

#define CONVERT_TO_LONG(obj, lng)               \
    if (PyInt_Check(obj)) {                     \
        lng = PyInt_AS_LONG(obj);               \
    }                                           \
    else {                                      \
        Py_INCREF(Py_NotImplemented);           \
        return Py_NotImplemented;               \
    }

/* ARGSUSED */
static int
int_print(PyIntObject *v, FILE *fp, int flags)
     /* flags -- not used but required by interface */
{
    long int_val = v->ob_ival;
    Py_BEGIN_ALLOW_THREADS
    fprintf(fp, "%ld", int_val);
    Py_END_ALLOW_THREADS
    return 0;
}

static int
int_compare(PyIntObject *v, PyIntObject *w)
{
    register long i = v->ob_ival;
    register long j = w->ob_ival;
    return (i < j) ? -1 : (i > j) ? 1 : 0;
}

static long
int_hash(PyIntObject *v)
{
    /* XXX If this is changed, you also need to change the way
       Python's long, float and complex types are hashed. */
    long x = v -> ob_ival;
    if (x == -1)
        x = -2;
    return x;
}

static PyObject *
int_add(PyIntObject *v, PyIntObject *w)
{
    register long a, b, x;
    CONVERT_TO_LONG(v, a);
    CONVERT_TO_LONG(w, b);
    /* casts in the line below avoid undefined behaviour on overflow */
    x = (long)((unsigned long)a + b);
    if ((x^a) >= 0 || (x^b) >= 0)
        return PyInt_FromLong(x);
    return PyLong_Type.tp_as_number->nb_add((PyObject *)v, (PyObject *)w);
}

static PyObject *
int_sub(PyIntObject *v, PyIntObject *w)
{
    register long a, b, x;
    CONVERT_TO_LONG(v, a);
    CONVERT_TO_LONG(w, b);
    /* casts in the line below avoid undefined behaviour on overflow */
    x = (long)((unsigned long)a - b);
    if ((x^a) >= 0 || (x^~b) >= 0)
        return PyInt_FromLong(x);
    return PyLong_Type.tp_as_number->nb_subtract((PyObject *)v,
                                                 (PyObject *)w);
}

/*
Integer overflow checking for * is painful:  Python tried a couple ways, but
they didn't work on all platforms, or failed in endcases (a product of
-sys.maxint-1 has been a particular pain).

Here's another way:

The native long product x*y is either exactly right or *way* off, being
just the last n bits of the true product, where n is the number of bits
in a long (the delivered product is the true product plus i*2**n for
some integer i).

The native double product (double)x * (double)y is subject to three
rounding errors:  on a sizeof(long)==8 box, each cast to double can lose
info, and even on a sizeof(long)==4 box, the multiplication can lose info.
But, unlike the native long product, it's not in *range* trouble:  even
if sizeof(long)==32 (256-bit longs), the product easily fits in the
dynamic range of a double.  So the leading 50 (or so) bits of the double
product are correct.

We check these two ways against each other, and declare victory if they're
approximately the same.  Else, because the native long product is the only
one that can lose catastrophic amounts of information, it's the native long
product that must have overflowed.
*/

static PyObject *
int_mul(PyObject *v, PyObject *w)
{
    long a, b;
    long longprod;                      /* a*b in native long arithmetic */
    double doubled_longprod;            /* (double)longprod */
    double doubleprod;                  /* (double)a * (double)b */

    CONVERT_TO_LONG(v, a);
    CONVERT_TO_LONG(w, b);
    /* casts in the next line avoid undefined behaviour on overflow */
    longprod = (long)((unsigned long)a * b);
    doubleprod = (double)a * (double)b;
    doubled_longprod = (double)longprod;

    /* Fast path for normal case:  small multiplicands, and no info
       is lost in either method. */
    if (doubled_longprod == doubleprod)
        return PyInt_FromLong(longprod);

    /* Somebody somewhere lost info.  Close enough, or way off?  Note
       that a != 0 and b != 0 (else doubled_longprod == doubleprod == 0).
       The difference either is or isn't significant compared to the
       true value (of which doubleprod is a good approximation).
    */
    {
        const double diff = doubled_longprod - doubleprod;
        const double absdiff = diff >= 0.0 ? diff : -diff;
        const double absprod = doubleprod >= 0.0 ? doubleprod :
                              -doubleprod;
        /* absdiff/absprod <= 1/32 iff
           32 * absdiff <= absprod -- 5 good bits is "close enough" */
        if (32.0 * absdiff <= absprod)
            return PyInt_FromLong(longprod);
        else
            return PyLong_Type.tp_as_number->nb_multiply(v, w);
    }
}

/* Integer overflow checking for unary negation: on a 2's-complement
 * box, -x overflows iff x is the most negative long.  In this case we
 * get -x == x.  However, -x is undefined (by C) if x /is/ the most
 * negative long (it's a signed overflow case), and some compilers care.
 * So we cast x to unsigned long first.  However, then other compilers
 * warn about applying unary minus to an unsigned operand.  Hence the
 * weird "0-".
 */
#define UNARY_NEG_WOULD_OVERFLOW(x)     \
    ((x) < 0 && (unsigned long)(x) == 0-(unsigned long)(x))

/* Return type of i_divmod */
enum divmod_result {
    DIVMOD_OK,                  /* Correct result */
    DIVMOD_OVERFLOW,            /* Overflow, try again using longs */
    DIVMOD_ERROR                /* Exception raised */
};

static enum divmod_result
i_divmod(register long x, register long y,
         long *p_xdivy, long *p_xmody)
{
    long xdivy, xmody;

    if (y == 0) {
        PyErr_SetString(PyExc_ZeroDivisionError,
                        "integer division or modulo by zero");
        return DIVMOD_ERROR;
    }
    /* (-sys.maxint-1)/-1 is the only overflow case. */
    if (y == -1 && UNARY_NEG_WOULD_OVERFLOW(x))
        return DIVMOD_OVERFLOW;
    xdivy = x / y;
    /* xdiv*y can overflow on platforms where x/y gives floor(x/y)
     * for x and y with differing signs. (This is unusual
     * behaviour, and C99 prohibits it, but it's allowed by C89;
     * for an example of overflow, take x = LONG_MIN, y = 5 or x =
     * LONG_MAX, y = -5.)  However, x - xdivy*y is always
     * representable as a long, since it lies strictly between
     * -abs(y) and abs(y).  We add casts to avoid intermediate
     * overflow.
     */
    xmody = (long)(x - (unsigned long)xdivy * y);
    /* If the signs of x and y differ, and the remainder is non-0,
     * C89 doesn't define whether xdivy is now the floor or the
     * ceiling of the infinitely precise quotient.  We want the floor,
     * and we have it iff the remainder's sign matches y's.
     */
    if (xmody && ((y ^ xmody) < 0) /* i.e. and signs differ */) {
        xmody += y;
        --xdivy;
        assert(xmody && ((y ^ xmody) >= 0));
    }
    *p_xdivy = xdivy;
    *p_xmody = xmody;
    return DIVMOD_OK;
}

static PyObject *
int_div(PyIntObject *x, PyIntObject *y)
{
    long xi, yi;
    long d, m;
    CONVERT_TO_LONG(x, xi);
    CONVERT_TO_LONG(y, yi);
    switch (i_divmod(xi, yi, &d, &m)) {
    case DIVMOD_OK:
        return PyInt_FromLong(d);
    case DIVMOD_OVERFLOW:
        return PyLong_Type.tp_as_number->nb_divide((PyObject *)x,
                                                   (PyObject *)y);
    default:
        return NULL;
    }
}

static PyObject *
int_classic_div(PyIntObject *x, PyIntObject *y)
{
    long xi, yi;
    long d, m;
    CONVERT_TO_LONG(x, xi);
    CONVERT_TO_LONG(y, yi);
    if (Py_DivisionWarningFlag &&
        PyErr_Warn(PyExc_DeprecationWarning, "classic int division") < 0)
        return NULL;
    switch (i_divmod(xi, yi, &d, &m)) {
    case DIVMOD_OK:
        return PyInt_FromLong(d);
    case DIVMOD_OVERFLOW:
        return PyLong_Type.tp_as_number->nb_divide((PyObject *)x,
                                                   (PyObject *)y);
    default:
        return NULL;
    }
}

static PyObject *
int_true_divide(PyIntObject *x, PyIntObject *y)
{
    long xi, yi;
    /* If they aren't both ints, give someone else a chance.  In
       particular, this lets int/long get handled by longs, which
       underflows to 0 gracefully if the long is too big to convert
       to float. */
    CONVERT_TO_LONG(x, xi);
    CONVERT_TO_LONG(y, yi);
    if (yi == 0) {
        PyErr_SetString(PyExc_ZeroDivisionError,
                        "division by zero");
        return NULL;
    }
    if (xi == 0)
        return PyFloat_FromDouble(yi < 0 ? -0.0 : 0.0);

#define WIDTH_OF_ULONG (CHAR_BIT*SIZEOF_LONG)
#if DBL_MANT_DIG < WIDTH_OF_ULONG
    if ((xi >= 0 ? 0UL + xi : 0UL - xi) >> DBL_MANT_DIG ||
        (yi >= 0 ? 0UL + yi : 0UL - yi) >> DBL_MANT_DIG)
        /* Large x or y.  Use long integer arithmetic. */
        return PyLong_Type.tp_as_number->nb_true_divide(
            (PyObject *)x, (PyObject *)y);
    else
#endif
        /* Both ints can be exactly represented as doubles.  Do a
           floating-point division. */
        return PyFloat_FromDouble((double)xi / (double)yi);
}

static PyObject *
int_mod(PyIntObject *x, PyIntObject *y)
{
    long xi, yi;
    long d, m;
    CONVERT_TO_LONG(x, xi);
    CONVERT_TO_LONG(y, yi);
    switch (i_divmod(xi, yi, &d, &m)) {
    case DIVMOD_OK:
        return PyInt_FromLong(m);
    case DIVMOD_OVERFLOW:
        return PyLong_Type.tp_as_number->nb_remainder((PyObject *)x,
                                                      (PyObject *)y);
    default:
        return NULL;
    }
}

static PyObject *
int_divmod(PyIntObject *x, PyIntObject *y)
{
    long xi, yi;
    long d, m;
    CONVERT_TO_LONG(x, xi);
    CONVERT_TO_LONG(y, yi);
    switch (i_divmod(xi, yi, &d, &m)) {
    case DIVMOD_OK:
        return Py_BuildValue("(ll)", d, m);
    case DIVMOD_OVERFLOW:
        return PyLong_Type.tp_as_number->nb_divmod((PyObject *)x,
                                                   (PyObject *)y);
    default:
        return NULL;
    }
}

static PyObject *
int_pow(PyIntObject *v, PyIntObject *w, PyIntObject *z)
{
    register long iv, iw, iz=0, ix, temp, prev;
    CONVERT_TO_LONG(v, iv);
    CONVERT_TO_LONG(w, iw);
    if (iw < 0) {
        if ((PyObject *)z != Py_None) {
            PyErr_SetString(PyExc_TypeError, "pow() 2nd argument "
                 "cannot be negative when 3rd argument specified");
            return NULL;
        }
        /* Return a float.  This works because we know that
           this calls float_pow() which converts its
           arguments to double. */
        return PyFloat_Type.tp_as_number->nb_power(
            (PyObject *)v, (PyObject *)w, (PyObject *)z);
    }
    if ((PyObject *)z != Py_None) {
        CONVERT_TO_LONG(z, iz);
        if (iz == 0) {
            PyErr_SetString(PyExc_ValueError,
                            "pow() 3rd argument cannot be 0");
            return NULL;
        }
    }
    /*
     * XXX: The original exponentiation code stopped looping
     * when temp hit zero; this code will continue onwards
     * unnecessarily, but at least it won't cause any errors.
     * Hopefully the speed improvement from the fast exponentiation
     * will compensate for the slight inefficiency.
     * XXX: Better handling of overflows is desperately needed.
     */
    temp = iv;
    ix = 1;
    while (iw > 0) {
        prev = ix;              /* Save value for overflow check */
        if (iw & 1) {
            /*
             * The (unsigned long) cast below ensures that the multiplication
             * is interpreted as an unsigned operation rather than a signed one
             * (C99 6.3.1.8p1), thus avoiding the perils of undefined behaviour
             * from signed arithmetic overflow (C99 6.5p5).  See issue #12973.
             */
            ix = (unsigned long)ix * temp;
            if (temp == 0)
                break; /* Avoid ix / 0 */
            if (ix / temp != prev) {
                return PyLong_Type.tp_as_number->nb_power(
                    (PyObject *)v,
                    (PyObject *)w,
                    (PyObject *)z);
            }
        }
        iw >>= 1;               /* Shift exponent down by 1 bit */
        if (iw==0) break;
        prev = temp;
        temp = (unsigned long)temp * temp;  /* Square the value of temp */
        if (prev != 0 && temp / prev != prev) {
            return PyLong_Type.tp_as_number->nb_power(
                (PyObject *)v, (PyObject *)w, (PyObject *)z);
        }
        if (iz) {
            /* If we did a multiplication, perform a modulo */
            ix = ix % iz;
            temp = temp % iz;
        }
    }
    if (iz) {
        long div, mod;
        switch (i_divmod(ix, iz, &div, &mod)) {
        case DIVMOD_OK:
            ix = mod;
            break;
        case DIVMOD_OVERFLOW:
            return PyLong_Type.tp_as_number->nb_power(
                (PyObject *)v, (PyObject *)w, (PyObject *)z);
        default:
            return NULL;
        }
    }
    return PyInt_FromLong(ix);
}

static PyObject *
int_neg(PyIntObject *v)
{
    register long a;
    a = v->ob_ival;
    /* check for overflow */
    if (UNARY_NEG_WOULD_OVERFLOW(a)) {
        PyObject *o = PyLong_FromLong(a);
        if (o != NULL) {
            PyObject *result = PyNumber_Negative(o);
            Py_DECREF(o);
            return result;
        }
        return NULL;
    }
    return PyInt_FromLong(-a);
}

static PyObject *
int_abs(PyIntObject *v)
{
    if (v->ob_ival >= 0)
        return int_int(v);
    else
        return int_neg(v);
}

static int
int_nonzero(PyIntObject *v)
{
    return v->ob_ival != 0;
}

static PyObject *
int_invert(PyIntObject *v)
{
    return PyInt_FromLong(~v->ob_ival);
}

static PyObject *
int_lshift(PyIntObject *v, PyIntObject *w)
{
    long a, b, c;
    PyObject *vv, *ww, *result;

    CONVERT_TO_LONG(v, a);
    CONVERT_TO_LONG(w, b);
    if (b < 0) {
        PyErr_SetString(PyExc_ValueError, "negative shift count");
        return NULL;
    }
    if (a == 0 || b == 0)
        return int_int(v);
    if (b >= LONG_BIT) {
        vv = PyLong_FromLong(PyInt_AS_LONG(v));
        if (vv == NULL)
            return NULL;
        ww = PyLong_FromLong(PyInt_AS_LONG(w));
        if (ww == NULL) {
            Py_DECREF(vv);
            return NULL;
        }
        result = PyNumber_Lshift(vv, ww);
        Py_DECREF(vv);
        Py_DECREF(ww);
        return result;
    }
    c = a << b;
    if (a != Py_ARITHMETIC_RIGHT_SHIFT(long, c, b)) {
        vv = PyLong_FromLong(PyInt_AS_LONG(v));
        if (vv == NULL)
            return NULL;
        ww = PyLong_FromLong(PyInt_AS_LONG(w));
        if (ww == NULL) {
            Py_DECREF(vv);
            return NULL;
        }
        result = PyNumber_Lshift(vv, ww);
        Py_DECREF(vv);
        Py_DECREF(ww);
        return result;
    }
    return PyInt_FromLong(c);
}

static PyObject *
int_rshift(PyIntObject *v, PyIntObject *w)
{
    register long a, b;
    CONVERT_TO_LONG(v, a);
    CONVERT_TO_LONG(w, b);
    if (b < 0) {
        PyErr_SetString(PyExc_ValueError, "negative shift count");
        return NULL;
    }
    if (a == 0 || b == 0)
        return int_int(v);
    if (b >= LONG_BIT) {
        if (a < 0)
            a = -1;
        else
            a = 0;
    }
    else {
        a = Py_ARITHMETIC_RIGHT_SHIFT(long, a, b);
    }
    return PyInt_FromLong(a);
}

static PyObject *
int_and(PyIntObject *v, PyIntObject *w)
{
    register long a, b;
    CONVERT_TO_LONG(v, a);
    CONVERT_TO_LONG(w, b);
    return PyInt_FromLong(a & b);
}

static PyObject *
int_xor(PyIntObject *v, PyIntObject *w)
{
    register long a, b;
    CONVERT_TO_LONG(v, a);
    CONVERT_TO_LONG(w, b);
    return PyInt_FromLong(a ^ b);
}

static PyObject *
int_or(PyIntObject *v, PyIntObject *w)
{
    register long a, b;
    CONVERT_TO_LONG(v, a);
    CONVERT_TO_LONG(w, b);
    return PyInt_FromLong(a | b);
}

static int
int_coerce(PyObject **pv, PyObject **pw)
{
    if (PyInt_Check(*pw)) {
        Py_INCREF(*pv);
        Py_INCREF(*pw);
        return 0;
    }
    return 1; /* Can't do it */
}

static PyObject *
int_int(PyIntObject *v)
{
    if (PyInt_CheckExact(v))
        Py_INCREF(v);
    else
        v = (PyIntObject *)PyInt_FromLong(v->ob_ival);
    return (PyObject *)v;
}

static PyObject *
int_long(PyIntObject *v)
{
    return PyLong_FromLong((v -> ob_ival));
}

static const unsigned char BitLengthTable[32] = {
    0, 1, 2, 2, 3, 3, 3, 3, 4, 4, 4, 4, 4, 4, 4, 4,
    5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5, 5
};

static int
bits_in_ulong(unsigned long d)
{
    int d_bits = 0;
    while (d >= 32) {
        d_bits += 6;
        d >>= 6;
    }
    d_bits += (int)BitLengthTable[d];
    return d_bits;
}

#if 8*SIZEOF_LONG-1 <= DBL_MANT_DIG
/* Every Python int can be exactly represented as a float. */

static PyObject *
int_float(PyIntObject *v)
{
    return PyFloat_FromDouble((double)(v -> ob_ival));
}

#else
/* Here not all Python ints are exactly representable as floats, so we may
   have to round.  We do this manually, since the C standards don't specify
   whether converting an integer to a float rounds up or down */

static PyObject *
int_float(PyIntObject *v)
{
    unsigned long abs_ival, lsb;
    int round_up;

    if (v->ob_ival < 0)
        abs_ival = 0U-(unsigned long)v->ob_ival;
    else
        abs_ival = (unsigned long)v->ob_ival;
    if (abs_ival < (1L << DBL_MANT_DIG))
        /* small integer;  no need to round */
        return PyFloat_FromDouble((double)v->ob_ival);

    /* Round abs_ival to MANT_DIG significant bits, using the
       round-half-to-even rule.  abs_ival & lsb picks out the 'rounding'
       bit: the first bit after the most significant MANT_DIG bits of
       abs_ival.  We round up if this bit is set, provided that either:

         (1) abs_ival isn't exactly halfway between two floats, in which
         case at least one of the bits following the rounding bit must be
         set; i.e., abs_ival & lsb-1 != 0, or:

         (2) the resulting rounded value has least significant bit 0; or
         in other words the bit above the rounding bit is set (this is the
         'to-even' bit of round-half-to-even); i.e., abs_ival & 2*lsb != 0

       The condition "(1) or (2)" equates to abs_ival & 3*lsb-1 != 0. */

    lsb = 1L << (bits_in_ulong(abs_ival)-DBL_MANT_DIG-1);
    round_up = (abs_ival & lsb) && (abs_ival & (3*lsb-1));
    abs_ival &= -2*lsb;
    if (round_up)
        abs_ival += 2*lsb;
    return PyFloat_FromDouble(v->ob_ival < 0 ?
                              -(double)abs_ival :
                  (double)abs_ival);
}

#endif

static PyObject *
int_oct(PyIntObject *v)
{
    return _PyInt_Format(v, 8, 0);
}

static PyObject *
int_hex(PyIntObject *v)
{
    return _PyInt_Format(v, 16, 0);
}

static PyObject *
int_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds);

static PyObject *
int_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    PyObject *x = NULL;
    int base = -909;
    static char *kwlist[] = {"x", "base", 0};

    if (type != &PyInt_Type)
        return int_subtype_new(type, args, kwds); /* Wimp out */
    if (!PyArg_ParseTupleAndKeywords(args, kwds, "|Oi:int", kwlist,
                                     &x, &base))
        return NULL;
    if (x == NULL) {
        if (base != -909) {
            PyErr_SetString(PyExc_TypeError,
                            "int() missing string argument");
            return NULL;
        }
        return PyInt_FromLong(0L);
    }
    if (base == -909)
        return PyNumber_Int(x);
    if (PyString_Check(x)) {
        /* Since PyInt_FromString doesn't have a length parameter,
         * check here for possible NULs in the string. */
        char *string = PyString_AS_STRING(x);
        if (strlen(string) != PyString_Size(x)) {
            /* create a repr() of the input string,
             * just like PyInt_FromString does */
            PyObject *srepr;
            srepr = PyObject_Repr(x);
            if (srepr == NULL)
                return NULL;
            PyErr_Format(PyExc_ValueError,
                 "invalid literal for int() with base %d: %s",
                 base, PyString_AS_STRING(srepr));
            Py_DECREF(srepr);
            return NULL;
        }
        return PyInt_FromString(string, NULL, base);
    }
#ifdef Py_USING_UNICODE
    if (PyUnicode_Check(x))
        return PyInt_FromUnicode(PyUnicode_AS_UNICODE(x),
                                 PyUnicode_GET_SIZE(x),
                                 base);
#endif
    PyErr_SetString(PyExc_TypeError,
                    "int() can't convert non-string with explicit base");
    return NULL;
}

/* Wimpy, slow approach to tp_new calls for subtypes of int:
   first create a regular int from whatever arguments we got,
   then allocate a subtype instance and initialize its ob_ival
   from the regular int.  The regular int is then thrown away.
*/
static PyObject *
int_subtype_new(PyTypeObject *type, PyObject *args, PyObject *kwds)
{
    PyObject *tmp, *newobj;
    long ival;

    assert(PyType_IsSubtype(type, &PyInt_Type));
    tmp = int_new(&PyInt_Type, args, kwds);
    if (tmp == NULL)
        return NULL;
    if (!PyInt_Check(tmp)) {
        ival = PyLong_AsLong(tmp);
        if (ival == -1 && PyErr_Occurred()) {
            Py_DECREF(tmp);
            return NULL;
        }
    } else {
        ival = ((PyIntObject *)tmp)->ob_ival;
    }

    newobj = type->tp_alloc(type, 0);
    if (newobj == NULL) {
        Py_DECREF(tmp);
        return NULL;
    }
    ((PyIntObject *)newobj)->ob_ival = ival;
    Py_DECREF(tmp);
    return newobj;
}

static PyObject *
int_getnewargs(PyIntObject *v)
{
    return Py_BuildValue("(l)", v->ob_ival);
}

static PyObject *
int_get0(PyIntObject *v, void *context) {
    return PyInt_FromLong(0L);
}

static PyObject *
int_get1(PyIntObject *v, void *context) {
    return PyInt_FromLong(1L);
}

/* Convert an integer to a decimal string.  On many platforms, this
   will be significantly faster than the general arbitrary-base
   conversion machinery in _PyInt_Format, thanks to optimization
   opportunities offered by division by a compile-time constant. */
static PyObject *
int_to_decimal_string(PyIntObject *v) {
    char buf[sizeof(long)*CHAR_BIT/3+6], *p, *bufend;
    long n = v->ob_ival;
    unsigned long absn;
    p = bufend = buf + sizeof(buf);
    absn = n < 0 ? 0UL - n : n;
    do {
        *--p = '0' + (char)(absn % 10);
        absn /= 10;
    } while (absn);
    if (n < 0)
        *--p = '-';
    return PyString_FromStringAndSize(p, bufend - p);
}

/* Convert an integer to the given base.  Returns a string.
   If base is 2, 8 or 16, add the proper prefix '0b', '0o' or '0x'.
   If newstyle is zero, then use the pre-2.6 behavior of octal having
   a leading "0" */
PyAPI_FUNC(PyObject*)
_PyInt_Format(PyIntObject *v, int base, int newstyle)
{
    /* There are no doubt many, many ways to optimize this, using code
       similar to _PyLong_Format */
    long n = v->ob_ival;
    int  negative = n < 0;
    int is_zero = n == 0;

    /* For the reasoning behind this size, see
       http://c-faq.com/misc/hexio.html. Then, add a few bytes for
       the possible sign and prefix "0[box]" */
    char buf[sizeof(n)*CHAR_BIT+6];

    /* Start by pointing to the end of the buffer.  We fill in from
       the back forward. */
    char* p = &buf[sizeof(buf)];

    assert(base >= 2 && base <= 36);

    /* Special case base 10, for speed */
    if (base == 10)
        return int_to_decimal_string(v);

    do {
        /* I'd use i_divmod, except it doesn't produce the results
           I want when n is negative.  So just duplicate the salient
           part here. */
        long div = n / base;
        long mod = n - div * base;

        /* convert abs(mod) to the right character in [0-9, a-z] */
        char cdigit = (char)(mod < 0 ? -mod : mod);
        cdigit += (cdigit < 10) ? '0' : 'a'-10;
        *--p = cdigit;

        n = div;
    } while(n);

    if (base == 2) {
        *--p = 'b';
        *--p = '0';
    }
    else if (base == 8) {
        if (newstyle) {
            *--p = 'o';
            *--p = '0';
        }
        else
            if (!is_zero)
                *--p = '0';
    }
    else if (base == 16) {
        *--p = 'x';
        *--p = '0';
    }
    else {
        *--p = '#';
        *--p = '0' + base%10;
        if (base > 10)
            *--p = '0' + base/10;
    }
    if (negative)
        *--p = '-';

    return PyString_FromStringAndSize(p, &buf[sizeof(buf)] - p);
}

static PyObject *
int__format__(PyObject *self, PyObject *args)
{
    PyObject *format_spec;

    if (!PyArg_ParseTuple(args, "O:__format__", &format_spec))
        return NULL;
    if (PyBytes_Check(format_spec))
        return _PyInt_FormatAdvanced(self,
                                     PyBytes_AS_STRING(format_spec),
                                     PyBytes_GET_SIZE(format_spec));
    if (PyUnicode_Check(format_spec)) {
        /* Convert format_spec to a str */
        PyObject *result;
        PyObject *str_spec = PyObject_Str(format_spec);

        if (str_spec == NULL)
            return NULL;

        result = _PyInt_FormatAdvanced(self,
                                       PyBytes_AS_STRING(str_spec),
                                       PyBytes_GET_SIZE(str_spec));

        Py_DECREF(str_spec);
        return result;
    }
    PyErr_SetString(PyExc_TypeError, "__format__ requires str or unicode");
    return NULL;
}

static PyObject *
int_bit_length(PyIntObject *v)
{
    unsigned long n;

    if (v->ob_ival < 0)
        /* avoid undefined behaviour when v->ob_ival == -LONG_MAX-1 */
        n = 0U-(unsigned long)v->ob_ival;
    else
        n = (unsigned long)v->ob_ival;

    return PyInt_FromLong(bits_in_ulong(n));
}

PyDoc_STRVAR(int_bit_length_doc,
"int.bit_length() -> int\n\
\n\
Number of bits necessary to represent self in binary.\n\
>>> bin(37)\n\
'0b100101'\n\
>>> (37).bit_length()\n\
6");

#if 0
static PyObject *
int_is_finite(PyObject *v)
{
    Py_RETURN_TRUE;
}
#endif

static PyMethodDef int_methods[] = {
    {"conjugate",       (PyCFunction)int_int,   METH_NOARGS,
     "Returns self, the complex conjugate of any int."},
    {"bit_length", (PyCFunction)int_bit_length, METH_NOARGS,
     int_bit_length_doc},
#if 0
    {"is_finite",       (PyCFunction)int_is_finite,     METH_NOARGS,
     "Returns always True."},
#endif
    {"__trunc__",       (PyCFunction)int_int,   METH_NOARGS,
     "Truncating an Integral returns itself."},
    {"__getnewargs__",          (PyCFunction)int_getnewargs,    METH_NOARGS},
    {"__format__", (PyCFunction)int__format__, METH_VARARGS},
    {NULL,              NULL}           /* sentinel */
};

static PyGetSetDef int_getset[] = {
    {"real",
     (getter)int_int, (setter)NULL,
     "the real part of a complex number",
     NULL},
    {"imag",
     (getter)int_get0, (setter)NULL,
     "the imaginary part of a complex number",
     NULL},
    {"numerator",
     (getter)int_int, (setter)NULL,
     "the numerator of a rational number in lowest terms",
     NULL},
    {"denominator",
     (getter)int_get1, (setter)NULL,
     "the denominator of a rational number in lowest terms",
     NULL},
    {NULL}  /* Sentinel */
};

PyDoc_STRVAR(int_doc,
"int(x=0) -> int or long\n\
int(x, base=10) -> int or long\n\
\n\
Convert a number or string to an integer, or return 0 if no arguments\n\
are given.  If x is floating point, the conversion truncates towards zero.\n\
If x is outside the integer range, the function returns a long instead.\n\
\n\
If x is not a number or if base is given, then x must be a string or\n\
Unicode object representing an integer literal in the given base.  The\n\
literal can be preceded by '+' or '-' and be surrounded by whitespace.\n\
The base defaults to 10.  Valid bases are 0 and 2-36.  Base 0 means to\n\
interpret the base from the string as an integer literal.\n\
>>> int('0b100', base=0)\n\
4");

static PyNumberMethods int_as_number = {
    (binaryfunc)int_add,        /*nb_add*/
    (binaryfunc)int_sub,        /*nb_subtract*/
    (binaryfunc)int_mul,        /*nb_multiply*/
    (binaryfunc)int_classic_div, /*nb_divide*/
    (binaryfunc)int_mod,        /*nb_remainder*/
    (binaryfunc)int_divmod,     /*nb_divmod*/
    (ternaryfunc)int_pow,       /*nb_power*/
    (unaryfunc)int_neg,         /*nb_negative*/
    (unaryfunc)int_int,         /*nb_positive*/
    (unaryfunc)int_abs,         /*nb_absolute*/
    (inquiry)int_nonzero,       /*nb_nonzero*/
    (unaryfunc)int_invert,      /*nb_invert*/
    (binaryfunc)int_lshift,     /*nb_lshift*/
    (binaryfunc)int_rshift,     /*nb_rshift*/
    (binaryfunc)int_and,        /*nb_and*/
    (binaryfunc)int_xor,        /*nb_xor*/
    (binaryfunc)int_or,         /*nb_or*/
    int_coerce,                 /*nb_coerce*/
    (unaryfunc)int_int,         /*nb_int*/
    (unaryfunc)int_long,        /*nb_long*/
    (unaryfunc)int_float,       /*nb_float*/
    (unaryfunc)int_oct,         /*nb_oct*/
    (unaryfunc)int_hex,         /*nb_hex*/
    0,                          /*nb_inplace_add*/
    0,                          /*nb_inplace_subtract*/
    0,                          /*nb_inplace_multiply*/
    0,                          /*nb_inplace_divide*/
    0,                          /*nb_inplace_remainder*/
    0,                          /*nb_inplace_power*/
    0,                          /*nb_inplace_lshift*/
    0,                          /*nb_inplace_rshift*/
    0,                          /*nb_inplace_and*/
    0,                          /*nb_inplace_xor*/
    0,                          /*nb_inplace_or*/
    (binaryfunc)int_div,        /* nb_floor_divide */
    (binaryfunc)int_true_divide, /* nb_true_divide */
    0,                          /* nb_inplace_floor_divide */
    0,                          /* nb_inplace_true_divide */
    (unaryfunc)int_int,         /* nb_index */
};

PyTypeObject PyInt_Type = {
    PyVarObject_HEAD_INIT(&PyType_Type, 0)
    "int",
    sizeof(PyIntObject),
    0,
    (destructor)int_dealloc,                    /* tp_dealloc */
    (printfunc)int_print,                       /* tp_print */
    0,                                          /* tp_getattr */
    0,                                          /* tp_setattr */
    (cmpfunc)int_compare,                       /* tp_compare */
    (reprfunc)int_to_decimal_string,            /* tp_repr */
    &int_as_number,                             /* tp_as_number */
    0,                                          /* tp_as_sequence */
    0,                                          /* tp_as_mapping */
    (hashfunc)int_hash,                         /* tp_hash */
    0,                                          /* tp_call */
    (reprfunc)int_to_decimal_string,            /* tp_str */
    PyObject_GenericGetAttr,                    /* tp_getattro */
    0,                                          /* tp_setattro */
    0,                                          /* tp_as_buffer */
    Py_TPFLAGS_DEFAULT | Py_TPFLAGS_CHECKTYPES |
        Py_TPFLAGS_BASETYPE | Py_TPFLAGS_INT_SUBCLASS,          /* tp_flags */
    int_doc,                                    /* tp_doc */
    0,                                          /* tp_traverse */
    0,                                          /* tp_clear */
    0,                                          /* tp_richcompare */
    0,                                          /* tp_weaklistoffset */
    0,                                          /* tp_iter */
    0,                                          /* tp_iternext */
    int_methods,                                /* tp_methods */
    0,                                          /* tp_members */
    int_getset,                                 /* tp_getset */
    0,                                          /* tp_base */
    0,                                          /* tp_dict */
    0,                                          /* tp_descr_get */
    0,                                          /* tp_descr_set */
    0,                                          /* tp_dictoffset */
    0,                                          /* tp_init */
    0,                                          /* tp_alloc */
    int_new,                                    /* tp_new */
    (freefunc)int_free,                         /* tp_free */
};

int
_PyInt_Init(void)
{
    PyIntObject *v;
    int ival;
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
    for (ival = -NSMALLNEGINTS; ival < NSMALLPOSINTS; ival++) {
          if (!free_list && (free_list = fill_free_list()) == NULL)
                    return 0;
        /* PyObject_New is inlined */
        v = free_list;
        free_list = (PyIntObject *)Py_TYPE(v);
        PyObject_INIT(v, &PyInt_Type);
        v->ob_ival = ival;
        small_ints[ival + NSMALLNEGINTS] = v;
    }
#endif
    return 1;
}

int
PyInt_ClearFreeList(void)
{
    PyIntObject *p;
    PyIntBlock *list, *next;
    int i;
    int u;                      /* remaining unfreed ints per block */
    int freelist_size = 0;

    list = block_list;
    block_list = NULL;
    free_list = NULL;
    while (list != NULL) {
        u = 0;
        for (i = 0, p = &list->objects[0];
             i < N_INTOBJECTS;
             i++, p++) {
            if (PyInt_CheckExact(p) && p->ob_refcnt != 0)
                u++;
        }
        next = list->next;
        if (u) {
            list->next = block_list;
            block_list = list;
            for (i = 0, p = &list->objects[0];
                 i < N_INTOBJECTS;
                 i++, p++) {
                if (!PyInt_CheckExact(p) ||
                    p->ob_refcnt == 0) {
                    Py_TYPE(p) = (struct _typeobject *)
                        free_list;
                    free_list = p;
                }
#if NSMALLNEGINTS + NSMALLPOSINTS > 0
                else if (-NSMALLNEGINTS <= p->ob_ival &&
                         p->ob_ival < NSMALLPOSINTS &&
                         small_ints[p->ob_ival +
                                    NSMALLNEGINTS] == NULL) {
                    Py_INCREF(p);
                    small_ints[p->ob_ival +
                               NSMALLNEGINTS] = p;
                }
#endif
            }
        }
        else {
            PyMem_FREE(list);
        }
        freelist_size += u;
        list = next;
    }

    return freelist_size;
}

void
PyInt_Fini(void)
{
    PyIntObject *p;
    PyIntBlock *list;
    int i;
    int u;                      /* total unfreed ints per block */

#if NSMALLNEGINTS + NSMALLPOSINTS > 0
    PyIntObject **q;

    i = NSMALLNEGINTS + NSMALLPOSINTS;
    q = small_ints;
    while (--i >= 0) {
        Py_XDECREF(*q);
        *q++ = NULL;
    }
#endif
    u = PyInt_ClearFreeList();
    if (!Py_VerboseFlag)
        return;
    fprintf(stderr, "# cleanup ints");
    if (!u) {
        fprintf(stderr, "\n");
    }
    else {
        fprintf(stderr,
            ": %d unfreed int%s\n",
            u, u == 1 ? "" : "s");
    }
    if (Py_VerboseFlag > 1) {
        list = block_list;
        while (list != NULL) {
            for (i = 0, p = &list->objects[0];
                 i < N_INTOBJECTS;
                 i++, p++) {
                if (PyInt_CheckExact(p) && p->ob_refcnt != 0)
                    /* XXX(twouters) cast refcount to
                       long until %zd is universally
                       available
                     */
                    fprintf(stderr,
                "#   <int at %p, refcnt=%ld, val=%ld>\n",
                                p, (long)p->ob_refcnt,
                                p->ob_ival);
            }
            list = list->next;
        }
    }
}
