diff options
author | Eric Snow <ericsnowcurrently@gmail.com> | 2022-07-25 18:47:31 (GMT) |
---|---|---|
committer | GitHub <noreply@github.com> | 2022-07-25 18:47:31 (GMT) |
commit | 4a1dd734311891662a6fc3394f93db98c93e7219 (patch) | |
tree | 2f85a419478553aeedd1622cb53dd5b302f77785 /Objects | |
parent | c5140945c723ae6c4b7ee81ff720ac8ea4b52cfd (diff) | |
download | cpython-4a1dd734311891662a6fc3394f93db98c93e7219.zip cpython-4a1dd734311891662a6fc3394f93db98c93e7219.tar.gz cpython-4a1dd734311891662a6fc3394f93db98c93e7219.tar.bz2 |
gh-94673: Add _PyStaticType_InitBuiltin() (#95152)
This is the first of several precursors to storing tp_subclasses (and tp_weaklist) on the interpreter state for static builtin types.
We do the following:
* add `_PyStaticType_InitBuiltin()`
* add `_Py_TPFLAGS_STATIC_BUILTIN`
* set it on all static builtin types in `_PyStaticType_InitBuiltin()`
* shuffle some code around to be able to use _PyStaticType_InitBuiltin()
* rename `_PyStructSequence_InitType()` to `_PyStructSequence_InitBuiltinWithFlags()`
* add `_PyStructSequence_InitBuiltin()`.
Diffstat (limited to 'Objects')
-rw-r--r-- | Objects/exceptions.c | 3 | ||||
-rw-r--r-- | Objects/floatobject.c | 3 | ||||
-rw-r--r-- | Objects/longobject.c | 2 | ||||
-rw-r--r-- | Objects/object.c | 4 | ||||
-rw-r--r-- | Objects/structseq.c | 122 | ||||
-rw-r--r-- | Objects/typeobject.c | 8 | ||||
-rw-r--r-- | Objects/unicodeobject.c | 6 |
7 files changed, 99 insertions, 49 deletions
diff --git a/Objects/exceptions.c b/Objects/exceptions.c index 9aab683..e06a8f4 100644 --- a/Objects/exceptions.c +++ b/Objects/exceptions.c @@ -3556,8 +3556,7 @@ _PyExc_InitTypes(PyInterpreterState *interp) for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) { PyTypeObject *exc = static_exceptions[i].exc; - - if (PyType_Ready(exc) < 0) { + if (_PyStaticType_InitBuiltin(exc) < 0) { return -1; } } diff --git a/Objects/floatobject.c b/Objects/floatobject.c index 47d308b..4b1b24f 100644 --- a/Objects/floatobject.c +++ b/Objects/floatobject.c @@ -1992,7 +1992,8 @@ _PyFloat_InitTypes(PyInterpreterState *interp) /* Init float info */ if (FloatInfoType.tp_name == NULL) { - if (PyStructSequence_InitType2(&FloatInfoType, &floatinfo_desc) < 0) { + if (_PyStructSequence_InitBuiltin(&FloatInfoType, + &floatinfo_desc) < 0) { return _PyStatus_ERR("can't init float info type"); } } diff --git a/Objects/longobject.c b/Objects/longobject.c index 4a1e5ca..90ed02b 100644 --- a/Objects/longobject.c +++ b/Objects/longobject.c @@ -6135,7 +6135,7 @@ _PyLong_InitTypes(PyInterpreterState *interp) /* initialize int_info */ if (Int_InfoType.tp_name == NULL) { - if (PyStructSequence_InitType2(&Int_InfoType, &int_info_desc) < 0) { + if (_PyStructSequence_InitBuiltin(&Int_InfoType, &int_info_desc) < 0) { return _PyStatus_ERR("can't init int info type"); } } diff --git a/Objects/object.c b/Objects/object.c index 75aee90..758b79e 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -1975,8 +1975,8 @@ _PyTypes_InitTypes(PyInterpreterState *interp) // All other static types (unless initialized elsewhere) for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) { PyTypeObject *type = static_types[i]; - if (PyType_Ready(type) < 0) { - return _PyStatus_ERR("Can't initialize types"); + if (_PyStaticType_InitBuiltin(type) < 0) { + return _PyStatus_ERR("Can't initialize builtin type"); } if (type == &PyType_Type) { // Sanitify checks of the two most important types diff --git a/Objects/structseq.c b/Objects/structseq.c index 229e3d8..24cd0e7 100644 --- a/Objects/structseq.c +++ b/Objects/structseq.c @@ -432,11 +432,21 @@ error: return -1; } -static void -initialize_members(PyStructSequence_Desc *desc, PyMemberDef* members, - Py_ssize_t n_members) { - Py_ssize_t i, k; +static PyMemberDef * +initialize_members(PyStructSequence_Desc *desc, + Py_ssize_t *pn_members, Py_ssize_t *pn_unnamed_members) +{ + PyMemberDef *members; + Py_ssize_t n_members, n_unnamed_members; + + n_members = count_members(desc, &n_unnamed_members); + members = PyMem_NEW(PyMemberDef, n_members - n_unnamed_members + 1); + if (members == NULL) { + PyErr_NoMemory(); + return NULL; + } + Py_ssize_t i, k; for (i = k = 0; i < n_members; ++i) { if (desc->fields[i].name == PyStructSequence_UnnamedField) { continue; @@ -453,30 +463,17 @@ initialize_members(PyStructSequence_Desc *desc, PyMemberDef* members, k++; } members[k].name = NULL; + + *pn_members = n_members; + *pn_unnamed_members = n_unnamed_members; + return members; } -int -_PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc, - unsigned long tp_flags) +static void +initialize_static_fields(PyTypeObject *type, PyStructSequence_Desc *desc, + PyMemberDef *tp_members, unsigned long tp_flags) { - PyMemberDef *members; - Py_ssize_t n_members, n_unnamed_members; - -#ifdef Py_TRACE_REFS - /* if the type object was chained, unchain it first - before overwriting its storage */ - if (type->ob_base.ob_base._ob_next) { - _Py_ForgetReference((PyObject *)type); - } -#endif - - /* PyTypeObject has already been initialized */ - if (Py_REFCNT(type) != 0) { - PyErr_BadInternalCall(); - return -1; - } - type->tp_name = desc->name; type->tp_basicsize = sizeof(PyStructSequence) - sizeof(PyObject *); type->tp_itemsize = sizeof(PyObject *); @@ -488,25 +485,20 @@ _PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc, type->tp_new = structseq_new; type->tp_flags = Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_GC | tp_flags; type->tp_traverse = (traverseproc) structseq_traverse; + type->tp_members = tp_members; +} - n_members = count_members(desc, &n_unnamed_members); - members = PyMem_NEW(PyMemberDef, n_members - n_unnamed_members + 1); - if (members == NULL) { - PyErr_NoMemory(); - return -1; - } - initialize_members(desc, members, n_members); - type->tp_members = members; - +static int +initialize_static_type(PyTypeObject *type, PyStructSequence_Desc *desc, + Py_ssize_t n_members, Py_ssize_t n_unnamed_members) { + /* initialize_static_fields() should have been called already. */ if (PyType_Ready(type) < 0) { - PyMem_Free(members); return -1; } Py_INCREF(type); if (initialize_structseq_dict( desc, type->tp_dict, n_members, n_unnamed_members) < 0) { - PyMem_Free(members); Py_DECREF(type); return -1; } @@ -515,9 +507,62 @@ _PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc, } int +_PyStructSequence_InitBuiltinWithFlags(PyTypeObject *type, + PyStructSequence_Desc *desc, + unsigned long tp_flags) +{ + PyMemberDef *members; + Py_ssize_t n_members, n_unnamed_members; + + members = initialize_members(desc, &n_members, &n_unnamed_members); + if (members == NULL) { + return -1; + } + initialize_static_fields(type, desc, members, tp_flags); + if (_PyStaticType_InitBuiltin(type) < 0) { + PyMem_Free(members); + PyErr_Format(PyExc_RuntimeError, + "Can't initialize builtin type %s", + desc->name); + return -1; + } + if (initialize_static_type(type, desc, n_members, n_unnamed_members) < 0) { + PyMem_Free(members); + return -1; + } + return 0; +} + +int PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc) { - return _PyStructSequence_InitType(type, desc, 0); + PyMemberDef *members; + Py_ssize_t n_members, n_unnamed_members; + +#ifdef Py_TRACE_REFS + /* if the type object was chained, unchain it first + before overwriting its storage */ + if (type->ob_base.ob_base._ob_next) { + _Py_ForgetReference((PyObject *)type); + } +#endif + + /* PyTypeObject has already been initialized */ + if (Py_REFCNT(type) != 0) { + PyErr_BadInternalCall(); + return -1; + } + + members = initialize_members(desc, &n_members, &n_unnamed_members); + if (members == NULL) { + return -1; + } + initialize_static_fields(type, desc, members, 0); + if (initialize_static_type(type, desc, n_members, n_unnamed_members) < 0) { + PyMem_Free(members); + return -1; + } + return 0; } void @@ -569,13 +614,10 @@ _PyStructSequence_NewType(PyStructSequence_Desc *desc, unsigned long tp_flags) Py_ssize_t n_members, n_unnamed_members; /* Initialize MemberDefs */ - n_members = count_members(desc, &n_unnamed_members); - members = PyMem_NEW(PyMemberDef, n_members - n_unnamed_members + 1); + members = initialize_members(desc, &n_members, &n_unnamed_members); if (members == NULL) { - PyErr_NoMemory(); return NULL; } - initialize_members(desc, members, n_members); /* Initialize Slots */ slots[0] = (PyType_Slot){Py_tp_dealloc, (destructor)structseq_dealloc}; diff --git a/Objects/typeobject.c b/Objects/typeobject.c index 5ebff60..8510196 100644 --- a/Objects/typeobject.c +++ b/Objects/typeobject.c @@ -6650,6 +6650,14 @@ PyType_Ready(PyTypeObject *type) return 0; } +int +_PyStaticType_InitBuiltin(PyTypeObject *self) +{ + self->tp_flags = self->tp_flags | _Py_TPFLAGS_STATIC_BUILTIN; + + return PyType_Ready(self); +} + static int add_subclass(PyTypeObject *base, PyTypeObject *type) diff --git a/Objects/unicodeobject.c b/Objects/unicodeobject.c index 669ffe7..7e3caf1 100644 --- a/Objects/unicodeobject.c +++ b/Objects/unicodeobject.c @@ -14604,13 +14604,13 @@ _PyUnicode_InitTypes(PyInterpreterState *interp) return _PyStatus_OK(); } - if (PyType_Ready(&EncodingMapType) < 0) { + if (_PyStaticType_InitBuiltin(&EncodingMapType) < 0) { goto error; } - if (PyType_Ready(&PyFieldNameIter_Type) < 0) { + if (_PyStaticType_InitBuiltin(&PyFieldNameIter_Type) < 0) { goto error; } - if (PyType_Ready(&PyFormatterIter_Type) < 0) { + if (_PyStaticType_InitBuiltin(&PyFormatterIter_Type) < 0) { goto error; } return _PyStatus_OK(); |