From: Petr Viktorin Date: Sun, 2 Jun 2019 23:31:12 +0000 (+0200) Subject: bpo-37012: Clean up special cases in PyType_FromSpecWithBases slot assignments (GH... X-Git-Tag: v3.8.0b1~42 X-Git-Url: http://git.ipfire.org/gitweb.cgi?a=commitdiff_plain;h=7f4ae1b2cc60cb69938e7c88793b9e9a2dd36d93;p=thirdparty%2FPython%2Fcpython.git bpo-37012: Clean up special cases in PyType_FromSpecWithBases slot assignments (GH-13496) The main slot assignment loop is now if-else if ladder, making the control flow clearer. Based on suggestion by Victor Stinner in: https://github.com/python/cpython/pull/10304/#issuecomment-491123026 --- diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 76e06aa31d64..beb0ddd82400 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -2941,14 +2941,13 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) PyErr_SetString(PyExc_RuntimeError, "invalid slot offset"); goto fail; } - if (slot->slot == Py_tp_base || slot->slot == Py_tp_bases) + else if (slot->slot == Py_tp_base || slot->slot == Py_tp_bases) { /* Processed above */ continue; - *(void**)(res_start + slotoffsets[slot->slot]) = slot->pfunc; - - /* need to make a copy of the docstring slot, which usually - points to a static string literal */ - if (slot->slot == Py_tp_doc) { + } + else if (slot->slot == Py_tp_doc) { + /* For the docstring slot, which usually points to a static string + literal, we need to make a copy */ const char *old_doc = _PyType_DocWithoutSignature(type->tp_name, slot->pfunc); size_t len = strlen(old_doc)+1; char *tp_doc = PyObject_MALLOC(len); @@ -2960,13 +2959,16 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) memcpy(tp_doc, old_doc, len); type->tp_doc = tp_doc; } - - /* Move the slots to the heap type itself */ - if (slot->slot == Py_tp_members) { + else if (slot->slot == Py_tp_members) { + /* Move the slots to the heap type itself */ size_t len = Py_TYPE(type)->tp_itemsize * nmembers; memcpy(PyHeapType_GET_MEMBERS(res), slot->pfunc, len); type->tp_members = PyHeapType_GET_MEMBERS(res); } + else { + /* Copy other slots directly */ + *(void**)(res_start + slotoffsets[slot->slot]) = slot->pfunc; + } } if (type->tp_dealloc == NULL) { /* It's a heap type, so needs the heap types' dealloc.