Skip to content

Commit

Permalink
gh-94673: Properly Initialize and Finalize Static Builtin Types for E…
Browse files Browse the repository at this point in the history
…ach Interpreter (gh-104072)

Until now, we haven't been initializing nor finalizing the per-interpreter state properly.
  • Loading branch information
ericsnowcurrently authored May 2, 2023
1 parent b1ca34d commit fdd8786
Show file tree
Hide file tree
Showing 17 changed files with 145 additions and 134 deletions.
3 changes: 2 additions & 1 deletion Include/internal/pycore_object.h
Original file line number Diff line number Diff line change
Expand Up @@ -272,8 +272,9 @@ _PyObject_GET_WEAKREFS_LISTPTR(PyObject *op)
{
if (PyType_Check(op) &&
((PyTypeObject *)op)->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
PyInterpreterState *interp = _PyInterpreterState_GET();
static_builtin_state *state = _PyStaticType_GetState(
(PyTypeObject *)op);
interp, (PyTypeObject *)op);
return _PyStaticType_GET_WEAKREFS_LISTPTR(state);
}
// Essentially _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET():
Expand Down
2 changes: 1 addition & 1 deletion Include/internal/pycore_pylifecycle.h
Original file line number Diff line number Diff line change
Expand Up @@ -39,7 +39,7 @@ extern PyStatus _PySys_Create(
extern PyStatus _PySys_ReadPreinitWarnOptions(PyWideStringList *options);
extern PyStatus _PySys_ReadPreinitXOptions(PyConfig *config);
extern int _PySys_UpdateConfig(PyThreadState *tstate);
extern void _PySys_Fini(PyInterpreterState *interp);
extern void _PySys_FiniTypes(PyInterpreterState *interp);
extern int _PyBuiltins_AddExceptions(PyObject * bltinmod);
extern PyStatus _Py_HashRandomization_Init(const PyConfig *);

Expand Down
10 changes: 7 additions & 3 deletions Include/internal/pycore_structseq.h
Original file line number Diff line number Diff line change
Expand Up @@ -16,18 +16,22 @@ PyAPI_FUNC(PyTypeObject *) _PyStructSequence_NewType(
unsigned long tp_flags);

extern int _PyStructSequence_InitBuiltinWithFlags(
PyInterpreterState *interp,
PyTypeObject *type,
PyStructSequence_Desc *desc,
unsigned long tp_flags);

static inline int
_PyStructSequence_InitBuiltin(PyTypeObject *type,
_PyStructSequence_InitBuiltin(PyInterpreterState *interp,
PyTypeObject *type,
PyStructSequence_Desc *desc)
{
return _PyStructSequence_InitBuiltinWithFlags(type, desc, 0);
return _PyStructSequence_InitBuiltinWithFlags(interp, type, desc, 0);
}

extern void _PyStructSequence_FiniBuiltin(PyTypeObject *type);
extern void _PyStructSequence_FiniBuiltin(
PyInterpreterState *interp,
PyTypeObject *type);

#ifdef __cplusplus
}
Expand Down
8 changes: 4 additions & 4 deletions Include/internal/pycore_typeobject.h
Original file line number Diff line number Diff line change
Expand Up @@ -104,10 +104,10 @@ _PyType_GetModuleState(PyTypeObject *type)
}


extern int _PyStaticType_InitBuiltin(PyTypeObject *type);
extern static_builtin_state * _PyStaticType_GetState(PyTypeObject *);
extern void _PyStaticType_ClearWeakRefs(PyTypeObject *type);
extern void _PyStaticType_Dealloc(PyTypeObject *type);
extern int _PyStaticType_InitBuiltin(PyInterpreterState *, PyTypeObject *type);
extern static_builtin_state * _PyStaticType_GetState(PyInterpreterState *, PyTypeObject *);
extern void _PyStaticType_ClearWeakRefs(PyInterpreterState *, PyTypeObject *type);
extern void _PyStaticType_Dealloc(PyInterpreterState *, PyTypeObject *);

PyObject *
_Py_type_getattro_impl(PyTypeObject *type, PyObject *name, int *suppress_missing_attribute);
Expand Down
8 changes: 2 additions & 6 deletions Modules/_io/_iomodule.c
Original file line number Diff line number Diff line change
Expand Up @@ -680,7 +680,7 @@ _PyIO_InitTypes(PyInterpreterState *interp)

for (size_t i=0; i < Py_ARRAY_LENGTH(static_types); i++) {
PyTypeObject *type = static_types[i];
if (_PyStaticType_InitBuiltin(type) < 0) {
if (_PyStaticType_InitBuiltin(interp, type) < 0) {
return _PyStatus_ERR("Can't initialize builtin type");
}
}
Expand All @@ -691,15 +691,11 @@ _PyIO_InitTypes(PyInterpreterState *interp)
void
_PyIO_FiniTypes(PyInterpreterState *interp)
{
if (!_Py_IsMainInterpreter(interp)) {
return;
}

// Deallocate types in the reverse order to deallocate subclasses before
// their base classes.
for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types) - 1; i >= 0; i--) {
PyTypeObject *type = static_types[i];
_PyStaticType_Dealloc(type);
_PyStaticType_Dealloc(interp, type);
}
}

Expand Down
8 changes: 2 additions & 6 deletions Objects/exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -3598,7 +3598,7 @@ _PyExc_InitTypes(PyInterpreterState *interp)
{
for (size_t i=0; i < Py_ARRAY_LENGTH(static_exceptions); i++) {
PyTypeObject *exc = static_exceptions[i].exc;
if (_PyStaticType_InitBuiltin(exc) < 0) {
if (_PyStaticType_InitBuiltin(interp, exc) < 0) {
return -1;
}
}
Expand All @@ -3609,13 +3609,9 @@ _PyExc_InitTypes(PyInterpreterState *interp)
static void
_PyExc_FiniTypes(PyInterpreterState *interp)
{
if (!_Py_IsMainInterpreter(interp)) {
return;
}

for (Py_ssize_t i=Py_ARRAY_LENGTH(static_exceptions) - 1; i >= 0; i--) {
PyTypeObject *exc = static_exceptions[i].exc;
_PyStaticType_Dealloc(exc);
_PyStaticType_Dealloc(interp, exc);
}
}

Expand Down
9 changes: 4 additions & 5 deletions Objects/floatobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -1991,8 +1991,9 @@ PyStatus
_PyFloat_InitTypes(PyInterpreterState *interp)
{
/* Init float info */
if (_PyStructSequence_InitBuiltin(&FloatInfoType,
&floatinfo_desc) < 0) {
if (_PyStructSequence_InitBuiltin(interp, &FloatInfoType,
&floatinfo_desc) < 0)
{
return _PyStatus_ERR("can't init float info type");
}

Expand Down Expand Up @@ -2028,9 +2029,7 @@ _PyFloat_Fini(PyInterpreterState *interp)
void
_PyFloat_FiniType(PyInterpreterState *interp)
{
if (_Py_IsMainInterpreter(interp)) {
_PyStructSequence_FiniBuiltin(&FloatInfoType);
}
_PyStructSequence_FiniBuiltin(interp, &FloatInfoType);
}

/* Print summary info about the state of the optimized allocator */
Expand Down
11 changes: 4 additions & 7 deletions Objects/longobject.c
Original file line number Diff line number Diff line change
Expand Up @@ -7,7 +7,6 @@
#include "pycore_initconfig.h" // _PyStatus_OK()
#include "pycore_long.h" // _Py_SmallInts
#include "pycore_object.h" // _PyObject_Init()
#include "pycore_pystate.h" // _Py_IsMainInterpreter()
#include "pycore_runtime.h" // _PY_NSMALLPOSINTS
#include "pycore_structseq.h" // _PyStructSequence_FiniBuiltin()

Expand Down Expand Up @@ -6352,7 +6351,9 @@ PyStatus
_PyLong_InitTypes(PyInterpreterState *interp)
{
/* initialize int_info */
if (_PyStructSequence_InitBuiltin(&Int_InfoType, &int_info_desc) < 0) {
if (_PyStructSequence_InitBuiltin(interp, &Int_InfoType,
&int_info_desc) < 0)
{
return _PyStatus_ERR("can't init int info type");
}

Expand All @@ -6363,9 +6364,5 @@ _PyLong_InitTypes(PyInterpreterState *interp)
void
_PyLong_FiniTypes(PyInterpreterState *interp)
{
if (!_Py_IsMainInterpreter(interp)) {
return;
}

_PyStructSequence_FiniBuiltin(&Int_InfoType);
_PyStructSequence_FiniBuiltin(interp, &Int_InfoType);
}
8 changes: 2 additions & 6 deletions Objects/object.c
Original file line number Diff line number Diff line change
Expand Up @@ -2105,7 +2105,7 @@ _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 (_PyStaticType_InitBuiltin(type) < 0) {
if (_PyStaticType_InitBuiltin(interp, type) < 0) {
return _PyStatus_ERR("Can't initialize builtin type");
}
if (type == &PyType_Type) {
Expand All @@ -2128,15 +2128,11 @@ _PyTypes_InitTypes(PyInterpreterState *interp)
void
_PyTypes_FiniTypes(PyInterpreterState *interp)
{
if (!_Py_IsMainInterpreter(interp)) {
return;
}

// Deallocate types in the reverse order to deallocate subclasses before
// their base classes.
for (Py_ssize_t i=Py_ARRAY_LENGTH(static_types)-1; i>=0; i--) {
PyTypeObject *type = static_types[i];
_PyStaticType_Dealloc(type);
_PyStaticType_Dealloc(interp, type);
}
}

Expand Down
21 changes: 12 additions & 9 deletions Objects/structseq.c
Original file line number Diff line number Diff line change
Expand Up @@ -502,7 +502,8 @@ initialize_static_type(PyTypeObject *type, PyStructSequence_Desc *desc,
}

int
_PyStructSequence_InitBuiltinWithFlags(PyTypeObject *type,
_PyStructSequence_InitBuiltinWithFlags(PyInterpreterState *interp,
PyTypeObject *type,
PyStructSequence_Desc *desc,
unsigned long tp_flags)
{
Expand Down Expand Up @@ -536,7 +537,7 @@ _PyStructSequence_InitBuiltinWithFlags(PyTypeObject *type,
}
#endif

if (_PyStaticType_InitBuiltin(type) < 0) {
if (_PyStaticType_InitBuiltin(interp, type) < 0) {
PyErr_Format(PyExc_RuntimeError,
"Can't initialize builtin type %s",
desc->name);
Expand Down Expand Up @@ -606,7 +607,7 @@ PyStructSequence_InitType(PyTypeObject *type, PyStructSequence_Desc *desc)
initialized via _PyStructSequence_InitBuiltinWithFlags(). */

void
_PyStructSequence_FiniBuiltin(PyTypeObject *type)
_PyStructSequence_FiniBuiltin(PyInterpreterState *interp, PyTypeObject *type)
{
// Ensure that the type is initialized
assert(type->tp_name != NULL);
Expand All @@ -620,13 +621,15 @@ _PyStructSequence_FiniBuiltin(PyTypeObject *type)
return;
}

_PyStaticType_Dealloc(type);
_PyStaticType_Dealloc(interp, type);

// Undo _PyStructSequence_InitBuiltinWithFlags().
type->tp_name = NULL;
PyMem_Free(type->tp_members);
type->tp_members = NULL;
type->tp_base = NULL;
if (_Py_IsMainInterpreter(interp)) {
// Undo _PyStructSequence_InitBuiltinWithFlags().
type->tp_name = NULL;
PyMem_Free(type->tp_members);
type->tp_members = NULL;
type->tp_base = NULL;
}
}


Expand Down
Loading

0 comments on commit fdd8786

Please sign in to comment.