mirror of https://github.com/python/cpython
gh-84436: Immortalize in _PyStructSequence_InitBuiltinWithFlags() (gh-104054)
This also does some cleanup.
This commit is contained in:
parent
d448fcb032
commit
59bc36aacd
|
@ -15,7 +15,7 @@ PyAPI_FUNC(PyTypeObject *) _PyStructSequence_NewType(
|
||||||
PyStructSequence_Desc *desc,
|
PyStructSequence_Desc *desc,
|
||||||
unsigned long tp_flags);
|
unsigned long tp_flags);
|
||||||
|
|
||||||
PyAPI_FUNC(int) _PyStructSequence_InitBuiltinWithFlags(
|
extern int _PyStructSequence_InitBuiltinWithFlags(
|
||||||
PyTypeObject *type,
|
PyTypeObject *type,
|
||||||
PyStructSequence_Desc *desc,
|
PyStructSequence_Desc *desc,
|
||||||
unsigned long tp_flags);
|
unsigned long tp_flags);
|
||||||
|
@ -27,7 +27,7 @@ _PyStructSequence_InitBuiltin(PyTypeObject *type,
|
||||||
return _PyStructSequence_InitBuiltinWithFlags(type, desc, 0);
|
return _PyStructSequence_InitBuiltinWithFlags(type, desc, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
extern void _PyStructSequence_FiniType(PyTypeObject *type);
|
extern void _PyStructSequence_FiniBuiltin(PyTypeObject *type);
|
||||||
|
|
||||||
#ifdef __cplusplus
|
#ifdef __cplusplus
|
||||||
}
|
}
|
||||||
|
|
|
@ -12,7 +12,7 @@
|
||||||
#include "pycore_object.h" // _PyObject_Init()
|
#include "pycore_object.h" // _PyObject_Init()
|
||||||
#include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR
|
#include "pycore_pymath.h" // _PY_SHORT_FLOAT_REPR
|
||||||
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
||||||
#include "pycore_structseq.h" // _PyStructSequence_FiniType()
|
#include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin()
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
@ -2029,7 +2029,7 @@ void
|
||||||
_PyFloat_FiniType(PyInterpreterState *interp)
|
_PyFloat_FiniType(PyInterpreterState *interp)
|
||||||
{
|
{
|
||||||
if (_Py_IsMainInterpreter(interp)) {
|
if (_Py_IsMainInterpreter(interp)) {
|
||||||
_PyStructSequence_FiniType(&FloatInfoType);
|
_PyStructSequence_FiniBuiltin(&FloatInfoType);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -9,7 +9,7 @@
|
||||||
#include "pycore_object.h" // _PyObject_Init()
|
#include "pycore_object.h" // _PyObject_Init()
|
||||||
#include "pycore_pystate.h" // _Py_IsMainInterpreter()
|
#include "pycore_pystate.h" // _Py_IsMainInterpreter()
|
||||||
#include "pycore_runtime.h" // _PY_NSMALLPOSINTS
|
#include "pycore_runtime.h" // _PY_NSMALLPOSINTS
|
||||||
#include "pycore_structseq.h" // _PyStructSequence_FiniType()
|
#include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin()
|
||||||
|
|
||||||
#include <ctype.h>
|
#include <ctype.h>
|
||||||
#include <float.h>
|
#include <float.h>
|
||||||
|
@ -6367,5 +6367,5 @@ _PyLong_FiniTypes(PyInterpreterState *interp)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_PyStructSequence_FiniType(&Int_InfoType);
|
_PyStructSequence_FiniBuiltin(&Int_InfoType);
|
||||||
}
|
}
|
||||||
|
|
|
@ -433,12 +433,10 @@ error:
|
||||||
|
|
||||||
static PyMemberDef *
|
static PyMemberDef *
|
||||||
initialize_members(PyStructSequence_Desc *desc,
|
initialize_members(PyStructSequence_Desc *desc,
|
||||||
Py_ssize_t *pn_members, Py_ssize_t *pn_unnamed_members)
|
Py_ssize_t n_members, Py_ssize_t n_unnamed_members)
|
||||||
{
|
{
|
||||||
PyMemberDef *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);
|
members = PyMem_NEW(PyMemberDef, n_members - n_unnamed_members + 1);
|
||||||
if (members == NULL) {
|
if (members == NULL) {
|
||||||
PyErr_NoMemory();
|
PyErr_NoMemory();
|
||||||
|
@ -463,8 +461,6 @@ initialize_members(PyStructSequence_Desc *desc,
|
||||||
}
|
}
|
||||||
members[k].name = NULL;
|
members[k].name = NULL;
|
||||||
|
|
||||||
*pn_members = n_members;
|
|
||||||
*pn_unnamed_members = n_unnamed_members;
|
|
||||||
return members;
|
return members;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -510,39 +506,58 @@ _PyStructSequence_InitBuiltinWithFlags(PyTypeObject *type,
|
||||||
PyStructSequence_Desc *desc,
|
PyStructSequence_Desc *desc,
|
||||||
unsigned long tp_flags)
|
unsigned long tp_flags)
|
||||||
{
|
{
|
||||||
if (type->tp_flags & Py_TPFLAGS_READY) {
|
Py_ssize_t n_unnamed_members;
|
||||||
if (_PyStaticType_InitBuiltin(type) < 0) {
|
Py_ssize_t n_members = count_members(desc, &n_unnamed_members);
|
||||||
goto failed_init_builtin;
|
PyMemberDef *members = NULL;
|
||||||
}
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
PyMemberDef *members;
|
int initialized = 1;
|
||||||
Py_ssize_t n_members, n_unnamed_members;
|
if ((type->tp_flags & Py_TPFLAGS_READY) == 0) {
|
||||||
|
assert(type->tp_name == NULL);
|
||||||
|
assert(type->tp_members == NULL);
|
||||||
|
assert(type->tp_base == NULL);
|
||||||
|
|
||||||
members = initialize_members(desc, &n_members, &n_unnamed_members);
|
members = initialize_members(desc, n_members, n_unnamed_members);
|
||||||
if (members == NULL) {
|
if (members == NULL) {
|
||||||
return -1;
|
goto error;
|
||||||
}
|
}
|
||||||
initialize_static_fields(type, desc, members, tp_flags);
|
initialize_static_fields(type, desc, members, tp_flags);
|
||||||
|
|
||||||
Py_INCREF(type); // XXX It should be immortal.
|
_Py_SetImmortal(type);
|
||||||
|
initialized = 0;
|
||||||
|
}
|
||||||
|
#ifndef NDEBUG
|
||||||
|
else {
|
||||||
|
// Ensure that the type was initialized.
|
||||||
|
assert(type->tp_name != NULL);
|
||||||
|
assert(type->tp_members != NULL);
|
||||||
|
assert(type->tp_base == &PyTuple_Type);
|
||||||
|
assert((type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN));
|
||||||
|
assert(_Py_IsImmortal(type));
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
if (_PyStaticType_InitBuiltin(type) < 0) {
|
if (_PyStaticType_InitBuiltin(type) < 0) {
|
||||||
PyMem_Free(members);
|
PyErr_Format(PyExc_RuntimeError,
|
||||||
goto failed_init_builtin;
|
"Can't initialize builtin type %s",
|
||||||
|
desc->name);
|
||||||
|
goto error;
|
||||||
|
}
|
||||||
|
// This should be dropped if tp_dict is made per-interpreter.
|
||||||
|
if (initialized) {
|
||||||
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (initialize_structseq_dict(
|
if (initialize_structseq_dict(
|
||||||
desc, type->tp_dict, n_members, n_unnamed_members) < 0) {
|
desc, type->tp_dict, n_members, n_unnamed_members) < 0) {
|
||||||
PyMem_Free(members);
|
goto error;
|
||||||
return -1;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
failed_init_builtin:
|
error:
|
||||||
PyErr_Format(PyExc_RuntimeError,
|
if (members != NULL) {
|
||||||
"Can't initialize builtin type %s",
|
PyMem_Free(members);
|
||||||
desc->name);
|
}
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -566,7 +581,8 @@ PyStructSequence_InitType2(PyTypeObject *type, PyStructSequence_Desc *desc)
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
|
||||||
members = initialize_members(desc, &n_members, &n_unnamed_members);
|
n_members = count_members(desc, &n_unnamed_members);
|
||||||
|
members = initialize_members(desc, n_members, n_unnamed_members);
|
||||||
if (members == NULL) {
|
if (members == NULL) {
|
||||||
return -1;
|
return -1;
|
||||||
}
|
}
|
||||||
|
@ -585,35 +601,32 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/* This is exposed in the internal API, not the public API.
|
||||||
|
It is only called on builtin static types, which are all
|
||||||
|
initialized via _PyStructSequence_InitBuiltinWithFlags(). */
|
||||||
|
|
||||||
void
|
void
|
||||||
_PyStructSequence_FiniType(PyTypeObject *type)
|
_PyStructSequence_FiniBuiltin(PyTypeObject *type)
|
||||||
{
|
{
|
||||||
// Ensure that the type is initialized
|
// Ensure that the type is initialized
|
||||||
assert(type->tp_name != NULL);
|
assert(type->tp_name != NULL);
|
||||||
assert(type->tp_base == &PyTuple_Type);
|
assert(type->tp_base == &PyTuple_Type);
|
||||||
|
assert((type->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN));
|
||||||
|
assert(_Py_IsImmortal(type));
|
||||||
|
|
||||||
// Cannot delete a type if it still has subclasses
|
// Cannot delete a type if it still has subclasses
|
||||||
if (_PyType_HasSubclasses(type)) {
|
if (_PyType_HasSubclasses(type)) {
|
||||||
|
// XXX Shouldn't this be an error?
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Undo PyStructSequence_NewType()
|
_PyStaticType_Dealloc(type);
|
||||||
|
|
||||||
|
// Undo _PyStructSequence_InitBuiltinWithFlags().
|
||||||
type->tp_name = NULL;
|
type->tp_name = NULL;
|
||||||
PyMem_Free(type->tp_members);
|
PyMem_Free(type->tp_members);
|
||||||
|
type->tp_members = NULL;
|
||||||
_PyStaticType_Dealloc(type);
|
type->tp_base = NULL;
|
||||||
assert(Py_REFCNT(type) == 1);
|
|
||||||
// Undo Py_INCREF(type) of _PyStructSequence_InitType().
|
|
||||||
// Don't use Py_DECREF(): static type must not be deallocated
|
|
||||||
Py_SET_REFCNT(type, 0);
|
|
||||||
#ifdef Py_REF_DEBUG
|
|
||||||
_Py_DecRefTotal(_PyInterpreterState_GET());
|
|
||||||
#endif
|
|
||||||
|
|
||||||
// Make sure that _PyStructSequence_InitType() will initialize
|
|
||||||
// the type again
|
|
||||||
assert(Py_REFCNT(type) == 0);
|
|
||||||
assert(type->tp_name == NULL);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
@ -627,7 +640,8 @@ _PyStructSequence_NewType(PyStructSequence_Desc *desc, unsigned long tp_flags)
|
||||||
Py_ssize_t n_members, n_unnamed_members;
|
Py_ssize_t n_members, n_unnamed_members;
|
||||||
|
|
||||||
/* Initialize MemberDefs */
|
/* Initialize MemberDefs */
|
||||||
members = initialize_members(desc, &n_members, &n_unnamed_members);
|
n_members = count_members(desc, &n_unnamed_members);
|
||||||
|
members = initialize_members(desc, n_members, n_unnamed_members);
|
||||||
if (members == NULL) {
|
if (members == NULL) {
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
|
@ -7031,6 +7031,7 @@ PyType_Ready(PyTypeObject *type)
|
||||||
int
|
int
|
||||||
_PyStaticType_InitBuiltin(PyTypeObject *self)
|
_PyStaticType_InitBuiltin(PyTypeObject *self)
|
||||||
{
|
{
|
||||||
|
assert(_Py_IsImmortal((PyObject *)self));
|
||||||
assert(!(self->tp_flags & Py_TPFLAGS_HEAPTYPE));
|
assert(!(self->tp_flags & Py_TPFLAGS_HEAPTYPE));
|
||||||
|
|
||||||
if (self->tp_flags & Py_TPFLAGS_READY) {
|
if (self->tp_flags & Py_TPFLAGS_READY) {
|
||||||
|
|
|
@ -6,7 +6,7 @@
|
||||||
#include "pycore_initconfig.h" // _PyStatus_ERR()
|
#include "pycore_initconfig.h" // _PyStatus_ERR()
|
||||||
#include "pycore_pyerrors.h" // _PyErr_Format()
|
#include "pycore_pyerrors.h" // _PyErr_Format()
|
||||||
#include "pycore_pystate.h" // _PyThreadState_GET()
|
#include "pycore_pystate.h" // _PyThreadState_GET()
|
||||||
#include "pycore_structseq.h" // _PyStructSequence_FiniType()
|
#include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin()
|
||||||
#include "pycore_sysmodule.h" // _PySys_Audit()
|
#include "pycore_sysmodule.h" // _PySys_Audit()
|
||||||
#include "pycore_traceback.h" // _PyTraceBack_FromFrame()
|
#include "pycore_traceback.h" // _PyTraceBack_FromFrame()
|
||||||
|
|
||||||
|
@ -1357,7 +1357,7 @@ _PyErr_FiniTypes(PyInterpreterState *interp)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_PyStructSequence_FiniType(&UnraisableHookArgsType);
|
_PyStructSequence_FiniBuiltin(&UnraisableHookArgsType);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -3492,13 +3492,13 @@ void
|
||||||
_PySys_Fini(PyInterpreterState *interp)
|
_PySys_Fini(PyInterpreterState *interp)
|
||||||
{
|
{
|
||||||
if (_Py_IsMainInterpreter(interp)) {
|
if (_Py_IsMainInterpreter(interp)) {
|
||||||
_PyStructSequence_FiniType(&VersionInfoType);
|
_PyStructSequence_FiniBuiltin(&VersionInfoType);
|
||||||
_PyStructSequence_FiniType(&FlagsType);
|
_PyStructSequence_FiniBuiltin(&FlagsType);
|
||||||
#if defined(MS_WINDOWS)
|
#if defined(MS_WINDOWS)
|
||||||
_PyStructSequence_FiniType(&WindowsVersionType);
|
_PyStructSequence_FiniBuiltin(&WindowsVersionType);
|
||||||
#endif
|
#endif
|
||||||
_PyStructSequence_FiniType(&Hash_InfoType);
|
_PyStructSequence_FiniBuiltin(&Hash_InfoType);
|
||||||
_PyStructSequence_FiniType(&AsyncGenHooksType);
|
_PyStructSequence_FiniBuiltin(&AsyncGenHooksType);
|
||||||
#ifdef __EMSCRIPTEN__
|
#ifdef __EMSCRIPTEN__
|
||||||
Py_CLEAR(EmscriptenInfoType);
|
Py_CLEAR(EmscriptenInfoType);
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -7,7 +7,7 @@
|
||||||
|
|
||||||
#include "Python.h"
|
#include "Python.h"
|
||||||
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
#include "pycore_pystate.h" // _PyInterpreterState_GET()
|
||||||
#include "pycore_structseq.h" // _PyStructSequence_FiniType()
|
#include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin()
|
||||||
#include "pycore_pythread.h"
|
#include "pycore_pythread.h"
|
||||||
|
|
||||||
#ifndef DONT_HAVE_STDIO_H
|
#ifndef DONT_HAVE_STDIO_H
|
||||||
|
@ -195,5 +195,5 @@ _PyThread_FiniType(PyInterpreterState *interp)
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
_PyStructSequence_FiniType(&ThreadInfoType);
|
_PyStructSequence_FiniBuiltin(&ThreadInfoType);
|
||||||
}
|
}
|
||||||
|
|
Loading…
Reference in New Issue