diff options
Diffstat (limited to 'Objects/tupleobject.c')
| -rw-r--r-- | Objects/tupleobject.c | 74 | 
1 files changed, 58 insertions, 16 deletions
| diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index b345460..9c843fa 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -45,6 +45,22 @@ show_track(void)  }  #endif +/* Print summary info about the state of the optimized allocator */ +void +_PyTuple_DebugMallocStats(FILE *out) +{ +#if PyTuple_MAXSAVESIZE > 0 +    int i; +    char buf[128]; +    for (i = 1; i < PyTuple_MAXSAVESIZE; i++) { +        PyOS_snprintf(buf, sizeof(buf), +                      "free %d-sized PyTupleObject", i); +        _PyDebugAllocatorStats(out, +                               buf, +                               numfree[i], _PyObject_VAR_SIZE(&PyTuple_Type, i)); +    } +#endif +}  PyObject *  PyTuple_New(register Py_ssize_t size) @@ -80,15 +96,11 @@ PyTuple_New(register Py_ssize_t size)      else  #endif      { -        Py_ssize_t nbytes = size * sizeof(PyObject *);          /* Check for overflow */ -        if (nbytes / sizeof(PyObject *) != (size_t)size || -            (nbytes > PY_SSIZE_T_MAX - sizeof(PyTupleObject) - sizeof(PyObject *))) -        { +        if (size > (PY_SSIZE_T_MAX - sizeof(PyTupleObject) - +                    sizeof(PyObject *)) / sizeof(PyObject *)) {              return PyErr_NoMemory();          } -        nbytes += sizeof(PyTupleObject) - sizeof(PyObject *); -          op = PyObject_GC_NewVar(PyTupleObject, &PyTuple_Type, size);          if (op == NULL)              return NULL; @@ -315,11 +327,12 @@ error:  static Py_hash_t  tuplehash(PyTupleObject *v)  { -    register Py_hash_t x, y; +    register Py_uhash_t x; +    register Py_hash_t y;      register Py_ssize_t len = Py_SIZE(v);      register PyObject **p; -    Py_hash_t mult = _PyHASH_MULTIPLIER; -    x = 0x345678L; +    Py_uhash_t mult = _PyHASH_MULTIPLIER; +    x = 0x345678;      p = v->ob_item;      while (--len >= 0) {          y = PyObject_Hash(*p++); @@ -330,7 +343,7 @@ tuplehash(PyTupleObject *v)          mult += (Py_hash_t)(82520L + len + len);      }      x += 97531L; -    if (x == -1) +    if (x == (Py_uhash_t)-1)          x = -2;      return x;  } @@ -464,9 +477,9 @@ tuplerepeat(PyTupleObject *a, Py_ssize_t n)          if (Py_SIZE(a) == 0)              return PyTuple_New(0);      } -    size = Py_SIZE(a) * n; -    if (size/Py_SIZE(a) != n) +    if (n > PY_SSIZE_T_MAX / Py_SIZE(a))          return PyErr_NoMemory(); +    size = Py_SIZE(a) * n;      np = (PyTupleObject *) PyTuple_New(size);      if (np == NULL)          return NULL; @@ -546,10 +559,8 @@ tuplerichcompare(PyObject *v, PyObject *w, int op)      Py_ssize_t i;      Py_ssize_t vlen, wlen; -    if (!PyTuple_Check(v) || !PyTuple_Check(w)) { -        Py_INCREF(Py_NotImplemented); -        return Py_NotImplemented; -    } +    if (!PyTuple_Check(v) || !PyTuple_Check(w)) +        Py_RETURN_NOTIMPLEMENTED;      vt = (PyTupleObject *)v;      wt = (PyTupleObject *)w; @@ -970,8 +981,39 @@ tupleiter_len(tupleiterobject *it)  PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); +static PyObject * +tupleiter_reduce(tupleiterobject *it) +{ +    if (it->it_seq) +        return Py_BuildValue("N(O)l", _PyObject_GetBuiltin("iter"), +                             it->it_seq, it->it_index); +    else +        return Py_BuildValue("N(())", _PyObject_GetBuiltin("iter")); +} + +static PyObject * +tupleiter_setstate(tupleiterobject *it, PyObject *state) +{ +    long index = PyLong_AsLong(state); +    if (index == -1 && PyErr_Occurred()) +        return NULL; +    if (it->it_seq != NULL) { +        if (index < 0) +            index = 0; +        else if (it->it_seq != NULL && index > PyTuple_GET_SIZE(it->it_seq)) +            index = PyTuple_GET_SIZE(it->it_seq); +        it->it_index = index; +    } +    Py_RETURN_NONE; +} + +PyDoc_STRVAR(reduce_doc, "Return state information for pickling."); +PyDoc_STRVAR(setstate_doc, "Set state information for unpickling."); +  static PyMethodDef tupleiter_methods[] = {      {"__length_hint__", (PyCFunction)tupleiter_len, METH_NOARGS, length_hint_doc}, +    {"__reduce__", (PyCFunction)tupleiter_reduce, METH_NOARGS, reduce_doc}, +    {"__setstate__", (PyCFunction)tupleiter_setstate, METH_O, setstate_doc},      {NULL,              NULL}           /* sentinel */  }; | 
