[ Web Proxy ]
URL:
Viewing: https://raw.githubusercontent.com/python-emscripten/cpython/2.7/Objects/intobject.c [Back]  [Original]

/* Integer object implementation */

#include "Python.h"
#include 
#include 

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 = 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);
    (void)PyObject_INIT(v, &PyInt_Type);
    v->ob_ival = ival;
    return (PyObject *) v;
}

PyObject *
PyInt_FromSize_t(size_t ival)
{
    if (ival = LONG_MIN && ival tp_free((PyObject *)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;
    }

    if (PyLong_CheckExact(op)) {
        /* avoid creating temporary int object */
        return PyLong_AsLong(op);
    }

    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);
            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;
    PyObject *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 = (*nb->nb_long)(op);
    else
        io = (*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(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 

Web Proxy Viewer  |  New URL  |  Original Page