diff options
Diffstat (limited to 'Objects/structseq.c')
-rw-r--r-- | Objects/structseq.c | 86 |
1 files changed, 60 insertions, 26 deletions
diff --git a/Objects/structseq.c b/Objects/structseq.c index c3b9a72..664344b 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -11,17 +11,20 @@ static char unnamed_fields_key[] = "n_unnamed_fields"; /* Fields with this name have only a field index, not a field name. They are only allowed for indices < n_visible_fields. */ char *PyStructSequence_UnnamedField = "unnamed field"; +_Py_IDENTIFIER(n_sequence_fields); +_Py_IDENTIFIER(n_fields); +_Py_IDENTIFIER(n_unnamed_fields); #define VISIBLE_SIZE(op) Py_SIZE(op) #define VISIBLE_SIZE_TP(tp) PyLong_AsLong( \ - PyDict_GetItemString((tp)->tp_dict, visible_length_key)) + _PyDict_GetItemId((tp)->tp_dict, &PyId_n_sequence_fields)) #define REAL_SIZE_TP(tp) PyLong_AsLong( \ - PyDict_GetItemString((tp)->tp_dict, real_length_key)) + _PyDict_GetItemId((tp)->tp_dict, &PyId_n_fields)) #define REAL_SIZE(op) REAL_SIZE_TP(Py_TYPE(op)) #define UNNAMED_FIELDS_TP(tp) PyLong_AsLong( \ - PyDict_GetItemString((tp)->tp_dict, unnamed_fields_key)) + _PyDict_GetItemId((tp)->tp_dict, &PyId_n_unnamed_fields)) #define UNNAMED_FIELDS(op) UNNAMED_FIELDS_TP(Py_TYPE(op)) @@ -59,7 +62,7 @@ static void structseq_dealloc(PyStructSequence *obj) { Py_ssize_t i, size; - + size = REAL_SIZE(obj); for (i = 0; i < size; ++i) { Py_XDECREF(obj->ob_item[i]); @@ -230,8 +233,8 @@ structseq_repr(PyStructSequence *obj) static PyObject * structseq_reduce(PyStructSequence* self) { - PyObject* tup; - PyObject* dict; + PyObject* tup = NULL; + PyObject* dict = NULL; PyObject* result; Py_ssize_t n_fields, n_visible_fields, n_unnamed_fields; int i; @@ -240,15 +243,12 @@ structseq_reduce(PyStructSequence* self) n_visible_fields = VISIBLE_SIZE(self); n_unnamed_fields = UNNAMED_FIELDS(self); tup = PyTuple_New(n_visible_fields); - if (!tup) { - return NULL; - } + if (!tup) + goto error; dict = PyDict_New(); - if (!dict) { - Py_DECREF(tup); - return NULL; - } + if (!dict) + goto error; for (i = 0; i < n_visible_fields; i++) { Py_INCREF(self->ob_item[i]); @@ -257,8 +257,8 @@ structseq_reduce(PyStructSequence* self) for (; i < n_fields; i++) { char *n = Py_TYPE(self)->tp_members[i-n_unnamed_fields].name; - PyDict_SetItemString(dict, n, - self->ob_item[i]); + if (PyDict_SetItemString(dict, n, self->ob_item[i]) < 0) + goto error; } result = Py_BuildValue("(O(OO))", Py_TYPE(self), tup, dict); @@ -267,6 +267,11 @@ structseq_reduce(PyStructSequence* self) Py_DECREF(dict); return result; + +error: + Py_XDECREF(tup); + Py_XDECREF(dict); + return NULL; } static PyMethodDef structseq_methods[] = { @@ -315,12 +320,13 @@ static PyTypeObject _struct_sequence_template = { structseq_new, /* tp_new */ }; -void -PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc) +int +PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc) { PyObject *dict; PyMemberDef* members; int n_members, n_unnamed_members, i, k; + PyObject *v; #ifdef Py_TRACE_REFS /* if the type object was chained, unchain it first @@ -342,8 +348,10 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc) type->tp_doc = desc->doc; members = PyMem_NEW(PyMemberDef, n_members-n_unnamed_members+1); - if (members == NULL) - return; + if (members == NULL) { + PyErr_NoMemory(); + return -1; + } for (i = k = 0; i < n_members; ++i) { if (desc->fields[i].name == PyStructSequence_UnnamedField) @@ -361,30 +369,56 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc) type->tp_members = members; if (PyType_Ready(type) < 0) - return; + return -1; Py_INCREF(type); dict = type->tp_dict; #define SET_DICT_FROM_INT(key, value) \ do { \ - PyObject *v = PyLong_FromLong((long) value); \ - if (v != NULL) { \ - PyDict_SetItemString(dict, key, v); \ + v = PyLong_FromLong((long) value); \ + if (v == NULL) \ + return -1; \ + if (PyDict_SetItemString(dict, key, v) < 0) { \ Py_DECREF(v); \ + return -1; \ } \ + Py_DECREF(v); \ } while (0) SET_DICT_FROM_INT(visible_length_key, desc->n_in_sequence); SET_DICT_FROM_INT(real_length_key, n_members); SET_DICT_FROM_INT(unnamed_fields_key, n_unnamed_members); + + return 0; +} + +void +PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc) +{ + (void)PyStructSequence_InitType2(type, desc); } PyTypeObject* PyStructSequence_NewType(PyStructSequence_Desc *desc) { - PyTypeObject *result = (PyTypeObject*)PyType_GenericAlloc(&PyType_Type, 0); - if (result != NULL) { - PyStructSequence_InitType(result, desc); + PyTypeObject *result; + + result = (PyTypeObject*)PyType_GenericAlloc(&PyType_Type, 0); + if (result == NULL) + return NULL; + if (PyStructSequence_InitType2(result, desc) < 0) { + Py_DECREF(result); + return NULL; } return result; } + +int _PyStructSequence_Init(void) +{ + if (_PyUnicode_FromId(&PyId_n_sequence_fields) == NULL + || _PyUnicode_FromId(&PyId_n_fields) == NULL + || _PyUnicode_FromId(&PyId_n_unnamed_fields) == NULL) + return -1; + + return 0; +} |