@@ -268,12 +268,6 @@ clear_tp_dict(PyTypeObject *self)
268
268
static inline PyObject *
269
269
lookup_tp_bases (PyTypeObject * self )
270
270
{
271
- if (self -> tp_flags & _Py_TPFLAGS_STATIC_BUILTIN ) {
272
- PyInterpreterState * interp = _PyInterpreterState_GET ();
273
- static_builtin_state * state = _PyStaticType_GetState (interp , self );
274
- assert (state != NULL );
275
- return state -> tp_bases ;
276
- }
277
271
return self -> tp_bases ;
278
272
}
279
273
@@ -287,12 +281,22 @@ _PyType_GetBases(PyTypeObject *self)
287
281
static inline void
288
282
set_tp_bases (PyTypeObject * self , PyObject * bases )
289
283
{
284
+ assert (PyTuple_CheckExact (bases ));
290
285
if (self -> tp_flags & _Py_TPFLAGS_STATIC_BUILTIN ) {
291
- PyInterpreterState * interp = _PyInterpreterState_GET ();
292
- static_builtin_state * state = _PyStaticType_GetState (interp , self );
293
- assert (state != NULL );
294
- state -> tp_bases = bases ;
295
- return ;
286
+ // XXX tp_bases can probably be statically allocated for each
287
+ // static builtin type.
288
+ assert (_Py_IsMainInterpreter (_PyInterpreterState_GET ()));
289
+ assert (self -> tp_bases == NULL );
290
+ if (PyTuple_GET_SIZE (bases ) == 0 ) {
291
+ assert (self -> tp_base == NULL );
292
+ }
293
+ else {
294
+ assert (PyTuple_GET_SIZE (bases ) == 1 );
295
+ assert (PyTuple_GET_ITEM (bases , 0 ) == (PyObject * )self -> tp_base );
296
+ assert (self -> tp_base -> tp_flags & _Py_TPFLAGS_STATIC_BUILTIN );
297
+ assert (_Py_IsImmortal (self -> tp_base ));
298
+ }
299
+ _Py_SetImmortal (bases );
296
300
}
297
301
self -> tp_bases = bases ;
298
302
}
@@ -301,10 +305,14 @@ static inline void
301
305
clear_tp_bases (PyTypeObject * self )
302
306
{
303
307
if (self -> tp_flags & _Py_TPFLAGS_STATIC_BUILTIN ) {
304
- PyInterpreterState * interp = _PyInterpreterState_GET ();
305
- static_builtin_state * state = _PyStaticType_GetState (interp , self );
306
- assert (state != NULL );
307
- Py_CLEAR (state -> tp_bases );
308
+ if (_Py_IsMainInterpreter (_PyInterpreterState_GET ())) {
309
+ if (self -> tp_bases != NULL
310
+ && PyTuple_GET_SIZE (self -> tp_bases ) > 0 )
311
+ {
312
+ assert (_Py_IsImmortal (self -> tp_bases ));
313
+ _Py_ClearImmortal (self -> tp_bases );
314
+ }
315
+ }
308
316
return ;
309
317
}
310
318
Py_CLEAR (self -> tp_bases );
@@ -314,12 +322,6 @@ clear_tp_bases(PyTypeObject *self)
314
322
static inline PyObject *
315
323
lookup_tp_mro (PyTypeObject * self )
316
324
{
317
- if (self -> tp_flags & _Py_TPFLAGS_STATIC_BUILTIN ) {
318
- PyInterpreterState * interp = _PyInterpreterState_GET ();
319
- static_builtin_state * state = _PyStaticType_GetState (interp , self );
320
- assert (state != NULL );
321
- return state -> tp_mro ;
322
- }
323
325
return self -> tp_mro ;
324
326
}
325
327
@@ -333,12 +335,14 @@ _PyType_GetMRO(PyTypeObject *self)
333
335
static inline void
334
336
set_tp_mro (PyTypeObject * self , PyObject * mro )
335
337
{
338
+ assert (PyTuple_CheckExact (mro ));
336
339
if (self -> tp_flags & _Py_TPFLAGS_STATIC_BUILTIN ) {
337
- PyInterpreterState * interp = _PyInterpreterState_GET ();
338
- static_builtin_state * state = _PyStaticType_GetState (interp , self );
339
- assert (state != NULL );
340
- state -> tp_mro = mro ;
341
- return ;
340
+ // XXX tp_mro can probably be statically allocated for each
341
+ // static builtin type.
342
+ assert (_Py_IsMainInterpreter (_PyInterpreterState_GET ()));
343
+ assert (self -> tp_mro == NULL );
344
+ /* Other checks are done via set_tp_bases. */
345
+ _Py_SetImmortal (mro );
342
346
}
343
347
self -> tp_mro = mro ;
344
348
}
@@ -347,10 +351,14 @@ static inline void
347
351
clear_tp_mro (PyTypeObject * self )
348
352
{
349
353
if (self -> tp_flags & _Py_TPFLAGS_STATIC_BUILTIN ) {
350
- PyInterpreterState * interp = _PyInterpreterState_GET ();
351
- static_builtin_state * state = _PyStaticType_GetState (interp , self );
352
- assert (state != NULL );
353
- Py_CLEAR (state -> tp_mro );
354
+ if (_Py_IsMainInterpreter (_PyInterpreterState_GET ())) {
355
+ if (self -> tp_mro != NULL
356
+ && PyTuple_GET_SIZE (self -> tp_mro ) > 0 )
357
+ {
358
+ assert (_Py_IsImmortal (self -> tp_mro ));
359
+ _Py_ClearImmortal (self -> tp_mro );
360
+ }
361
+ }
354
362
return ;
355
363
}
356
364
Py_CLEAR (self -> tp_mro );
@@ -7153,6 +7161,14 @@ type_ready_preheader(PyTypeObject *type)
7153
7161
static int
7154
7162
type_ready_mro (PyTypeObject * type )
7155
7163
{
7164
+ if (type -> tp_flags & _Py_TPFLAGS_STATIC_BUILTIN ) {
7165
+ if (!_Py_IsMainInterpreter (_PyInterpreterState_GET ())) {
7166
+ assert (lookup_tp_mro (type ) != NULL );
7167
+ return 0 ;
7168
+ }
7169
+ assert (lookup_tp_mro (type ) == NULL );
7170
+ }
7171
+
7156
7172
/* Calculate method resolution order */
7157
7173
if (mro_internal (type , NULL ) < 0 ) {
7158
7174
return -1 ;
0 commit comments