diff options
Diffstat (limited to 'Objects/tupleobject.c')
| -rw-r--r-- | Objects/tupleobject.c | 139 |
1 files changed, 57 insertions, 82 deletions
diff --git a/Objects/tupleobject.c b/Objects/tupleobject.c index 00f2e47..9e914cb 100644 --- a/Objects/tupleobject.c +++ b/Objects/tupleobject.c @@ -2,6 +2,7 @@ /* Tuple object implementation */ #include "Python.h" +#include "accu.h" /* Speed optimization to avoid frequent malloc/free of small tuples */ #ifndef PyTuple_MAXSAVESIZE @@ -86,6 +87,7 @@ PyTuple_New(register Py_ssize_t size) { return PyErr_NoMemory(); } + nbytes += sizeof(PyTupleObject) - sizeof(PyObject *); op = PyObject_GC_NewVar(PyTupleObject, &PyTuple_Type, size); if (op == NULL) @@ -237,41 +239,23 @@ done: Py_TRASHCAN_SAFE_END(op) } -static int -tupleprint(PyTupleObject *op, FILE *fp, int flags) -{ - Py_ssize_t i; - Py_BEGIN_ALLOW_THREADS - fprintf(fp, "("); - Py_END_ALLOW_THREADS - for (i = 0; i < Py_SIZE(op); i++) { - if (i > 0) { - Py_BEGIN_ALLOW_THREADS - fprintf(fp, ", "); - Py_END_ALLOW_THREADS - } - if (PyObject_Print(op->ob_item[i], fp, 0) != 0) - return -1; - } - i = Py_SIZE(op); - Py_BEGIN_ALLOW_THREADS - if (i == 1) - fprintf(fp, ","); - fprintf(fp, ")"); - Py_END_ALLOW_THREADS - return 0; -} - static PyObject * tuplerepr(PyTupleObject *v) { Py_ssize_t i, n; - PyObject *s, *temp; - PyObject *pieces, *result = NULL; + PyObject *s = NULL; + _PyAccu acc; + static PyObject *sep = NULL; n = Py_SIZE(v); if (n == 0) - return PyString_FromString("()"); + return PyUnicode_FromString("()"); + + if (sep == NULL) { + sep = PyUnicode_FromString(", "); + if (sep == NULL) + return NULL; + } /* While not mutable, it is still possible to end up with a cycle in a tuple through an object that stores itself within a tuple (and thus @@ -279,55 +263,45 @@ tuplerepr(PyTupleObject *v) possible within a type. */ i = Py_ReprEnter((PyObject *)v); if (i != 0) { - return i > 0 ? PyString_FromString("(...)") : NULL; + return i > 0 ? PyUnicode_FromString("(...)") : NULL; } - pieces = PyTuple_New(n); - if (pieces == NULL) - return NULL; + if (_PyAccu_Init(&acc)) + goto error; + + s = PyUnicode_FromString("("); + if (s == NULL || _PyAccu_Accumulate(&acc, s)) + goto error; + Py_CLEAR(s); /* Do repr() on each element. */ for (i = 0; i < n; ++i) { if (Py_EnterRecursiveCall(" while getting the repr of a tuple")) - goto Done; + goto error; s = PyObject_Repr(v->ob_item[i]); Py_LeaveRecursiveCall(); - if (s == NULL) - goto Done; - PyTuple_SET_ITEM(pieces, i, s); + if (i > 0 && _PyAccu_Accumulate(&acc, sep)) + goto error; + if (s == NULL || _PyAccu_Accumulate(&acc, s)) + goto error; + Py_CLEAR(s); } + if (n > 1) + s = PyUnicode_FromString(")"); + else + s = PyUnicode_FromString(",)"); + if (s == NULL || _PyAccu_Accumulate(&acc, s)) + goto error; + Py_CLEAR(s); - /* Add "()" decorations to the first and last items. */ - assert(n > 0); - s = PyString_FromString("("); - if (s == NULL) - goto Done; - temp = PyTuple_GET_ITEM(pieces, 0); - PyString_ConcatAndDel(&s, temp); - PyTuple_SET_ITEM(pieces, 0, s); - if (s == NULL) - goto Done; - - s = PyString_FromString(n == 1 ? ",)" : ")"); - if (s == NULL) - goto Done; - temp = PyTuple_GET_ITEM(pieces, n-1); - PyString_ConcatAndDel(&temp, s); - PyTuple_SET_ITEM(pieces, n-1, temp); - if (temp == NULL) - goto Done; - - /* Paste them all together with ", " between. */ - s = PyString_FromString(", "); - if (s == NULL) - goto Done; - result = _PyString_Join(s, pieces); - Py_DECREF(s); - -Done: - Py_DECREF(pieces); Py_ReprLeave((PyObject *)v); - return result; + return _PyAccu_Finish(&acc); + +error: + _PyAccu_Destroy(&acc); + Py_XDECREF(s); + Py_ReprLeave((PyObject *)v); + return NULL; } /* The addend 82520, was selected from the range(0, 1000000) for @@ -338,14 +312,15 @@ Done: 1330111, 1412633, 1165069, 1247599, 1495177, 1577699 */ -static long +static Py_hash_t tuplehash(PyTupleObject *v) { - register long x, y; + register Py_uhash_t x; /* Unsigned for defined overflow behavior. */ + register Py_hash_t y; register Py_ssize_t len = Py_SIZE(v); register PyObject **p; - long mult = 1000003L; - x = 0x345678L; + Py_uhash_t mult = _PyHASH_MULTIPLIER; + x = 0x345678UL; p = v->ob_item; while (--len >= 0) { y = PyObject_Hash(*p++); @@ -353,9 +328,9 @@ tuplehash(PyTupleObject *v) return -1; x = (x ^ y) * mult; /* the cast might truncate len; that doesn't change hash stability */ - mult += (long)(82520L + len + len); + mult += (Py_uhash_t)(82520UL + len + len); } - x += 97531L; + x += 97531UL; if (x == -1) x = -2; return x; @@ -531,7 +506,7 @@ tupleindex(PyTupleObject *self, PyObject *args) for (i = start; i < stop && i < Py_SIZE(self); i++) { int cmp = PyObject_RichCompareBool(self->ob_item[i], v, Py_EQ); if (cmp > 0) - return PyInt_FromSsize_t(i); + return PyLong_FromSsize_t(i); else if (cmp < 0) return NULL; } @@ -552,7 +527,7 @@ tuplecount(PyTupleObject *self, PyObject *v) else if (cmp < 0) return NULL; } - return PyInt_FromSsize_t(count); + return PyLong_FromSsize_t(count); } static int @@ -692,7 +667,7 @@ static PySequenceMethods tuple_as_sequence = { (binaryfunc)tupleconcat, /* sq_concat */ (ssizeargfunc)tuplerepeat, /* sq_repeat */ (ssizeargfunc)tupleitem, /* sq_item */ - (ssizessizeargfunc)tupleslice, /* sq_slice */ + 0, /* sq_slice */ 0, /* sq_ass_item */ 0, /* sq_ass_slice */ (objobjproc)tuplecontains, /* sq_contains */ @@ -715,7 +690,7 @@ tuplesubscript(PyTupleObject* self, PyObject* item) PyObject* it; PyObject **src, **dest; - if (PySlice_GetIndicesEx((PySliceObject*)item, + if (PySlice_GetIndicesEx(item, PyTuple_GET_SIZE(self), &start, &stop, &step, &slicelength) < 0) { return NULL; @@ -767,7 +742,7 @@ tuple_sizeof(PyTupleObject *self) Py_ssize_t res; res = PyTuple_Type.tp_basicsize + Py_SIZE(self) * sizeof(PyObject *); - return PyInt_FromSsize_t(res); + return PyLong_FromSsize_t(res); } PyDoc_STRVAR(index_doc, @@ -801,10 +776,10 @@ PyTypeObject PyTuple_Type = { sizeof(PyTupleObject) - sizeof(PyObject *), sizeof(PyObject *), (destructor)tupledealloc, /* tp_dealloc */ - (printfunc)tupleprint, /* tp_print */ + 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_compare */ + 0, /* tp_reserved */ (reprfunc)tuplerepr, /* tp_repr */ 0, /* tp_as_number */ &tuple_as_sequence, /* tp_as_sequence */ @@ -991,7 +966,7 @@ tupleiter_len(tupleiterobject *it) Py_ssize_t len = 0; if (it->it_seq) len = PyTuple_GET_SIZE(it->it_seq) - it->it_index; - return PyInt_FromSsize_t(len); + return PyLong_FromSsize_t(len); } PyDoc_STRVAR(length_hint_doc, "Private method returning an estimate of len(list(it))."); @@ -1003,7 +978,7 @@ static PyMethodDef tupleiter_methods[] = { PyTypeObject PyTupleIter_Type = { PyVarObject_HEAD_INIT(&PyType_Type, 0) - "tupleiterator", /* tp_name */ + "tuple_iterator", /* tp_name */ sizeof(tupleiterobject), /* tp_basicsize */ 0, /* tp_itemsize */ /* methods */ @@ -1011,7 +986,7 @@ PyTypeObject PyTupleIter_Type = { 0, /* tp_print */ 0, /* tp_getattr */ 0, /* tp_setattr */ - 0, /* tp_compare */ + 0, /* tp_reserved */ 0, /* tp_repr */ 0, /* tp_as_number */ 0, /* tp_as_sequence */ |
