Commit 7f4ae1b2 authored by Petr Viktorin's avatar Petr Viktorin Committed by GitHub

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
parent 0d70227e
...@@ -2941,14 +2941,13 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) ...@@ -2941,14 +2941,13 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
PyErr_SetString(PyExc_RuntimeError, "invalid slot offset"); PyErr_SetString(PyExc_RuntimeError, "invalid slot offset");
goto fail; 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 */ /* Processed above */
continue; continue;
*(void**)(res_start + slotoffsets[slot->slot]) = slot->pfunc; }
else if (slot->slot == Py_tp_doc) {
/* need to make a copy of the docstring slot, which usually /* For the docstring slot, which usually points to a static string
points to a static string literal */ literal, we need to make a copy */
if (slot->slot == Py_tp_doc) {
const char *old_doc = _PyType_DocWithoutSignature(type->tp_name, slot->pfunc); const char *old_doc = _PyType_DocWithoutSignature(type->tp_name, slot->pfunc);
size_t len = strlen(old_doc)+1; size_t len = strlen(old_doc)+1;
char *tp_doc = PyObject_MALLOC(len); char *tp_doc = PyObject_MALLOC(len);
...@@ -2960,13 +2959,16 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases) ...@@ -2960,13 +2959,16 @@ PyType_FromSpecWithBases(PyType_Spec *spec, PyObject *bases)
memcpy(tp_doc, old_doc, len); memcpy(tp_doc, old_doc, len);
type->tp_doc = tp_doc; type->tp_doc = tp_doc;
} }
else if (slot->slot == Py_tp_members) {
/* Move the slots to the heap type itself */ /* Move the slots to the heap type itself */
if (slot->slot == Py_tp_members) {
size_t len = Py_TYPE(type)->tp_itemsize * nmembers; size_t len = Py_TYPE(type)->tp_itemsize * nmembers;
memcpy(PyHeapType_GET_MEMBERS(res), slot->pfunc, len); memcpy(PyHeapType_GET_MEMBERS(res), slot->pfunc, len);
type->tp_members = PyHeapType_GET_MEMBERS(res); 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) { if (type->tp_dealloc == NULL) {
/* It's a heap type, so needs the heap types' dealloc. /* It's a heap type, so needs the heap types' dealloc.
......
Markdown is supported
0%
or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment