@@ -14,16 +14,25 @@ extern "C" {
14
14
#include "pycore_pystate.h" // _PyInterpreterState_GET()
15
15
#include "pycore_runtime.h" // _PyRuntime
16
16
17
- #define _PyObject_IMMORTAL_INIT (type ) \
18
- { \
19
- .ob_refcnt = 999999999, \
20
- .ob_type = type, \
21
- }
22
- #define _PyVarObject_IMMORTAL_INIT (type , size ) \
23
- { \
24
- .ob_base = _PyObject_IMMORTAL_INIT(type), \
25
- .ob_size = size, \
26
- }
17
+ /* We need to maintain an internal copy of Py{Var}Object_HEAD_INIT to avoid
18
+ designated initializer conflicts in C++20. If we use the deinition in
19
+ object.h, we will be mixing designated and non-designated initializers in
20
+ pycore objects which is forbiddent in C++20. However, if we then use
21
+ designated initializers in object.h then Extensions without designated break.
22
+ Furthermore, we can't use designated initializers in Extensions since these
23
+ are not supported pre-C++20. Thus, keeping an internal copy here is the most
24
+ backwards compatible solution */
25
+ #define _PyObject_HEAD_INIT (type ) \
26
+ { \
27
+ _PyObject_EXTRA_INIT \
28
+ .ob_refcnt = _Py_IMMORTAL_REFCNT, \
29
+ .ob_type = (type) \
30
+ },
31
+ #define _PyVarObject_HEAD_INIT (type , size ) \
32
+ { \
33
+ .ob_base = _PyObject_HEAD_INIT(type) \
34
+ .ob_size = size \
35
+ },
27
36
28
37
PyAPI_FUNC (void ) _Py_NO_RETURN _Py_FatalRefcountErrorFunc (
29
38
const char * func ,
@@ -92,6 +101,10 @@ static inline void _Py_ClearImmortal(PyObject *op)
92
101
static inline void
93
102
_Py_DECREF_SPECIALIZED (PyObject * op , const destructor destruct )
94
103
{
104
+ if (_Py_IsImmortal (op )) {
105
+ return ;
106
+ }
107
+ _Py_DECREF_STAT_INC ();
95
108
#ifdef Py_REF_DEBUG
96
109
_Py_DEC_REFTOTAL (_PyInterpreterState_GET ());
97
110
#endif
@@ -109,6 +122,10 @@ _Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct)
109
122
static inline void
110
123
_Py_DECREF_NO_DEALLOC (PyObject * op )
111
124
{
125
+ if (_Py_IsImmortal (op )) {
126
+ return ;
127
+ }
128
+ _Py_DECREF_STAT_INC ();
112
129
#ifdef Py_REF_DEBUG
113
130
_Py_DEC_REFTOTAL (_PyInterpreterState_GET ());
114
131
#endif
@@ -279,6 +296,13 @@ extern void _Py_PrintReferenceAddresses(PyInterpreterState *, FILE *);
279
296
static inline PyObject * *
280
297
_PyObject_GET_WEAKREFS_LISTPTR (PyObject * op )
281
298
{
299
+ if (PyType_Check (op ) &&
300
+ ((PyTypeObject * )op )-> tp_flags & _Py_TPFLAGS_STATIC_BUILTIN ) {
301
+ PyInterpreterState * interp = _PyInterpreterState_GET ();
302
+ static_builtin_state * state = _PyStaticType_GetState (
303
+ interp , (PyTypeObject * )op );
304
+ return _PyStaticType_GET_WEAKREFS_LISTPTR (state );
305
+ }
282
306
// Essentially _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET():
283
307
Py_ssize_t offset = Py_TYPE (op )-> tp_weaklistoffset ;
284
308
return (PyObject * * )((char * )op + offset );
@@ -322,7 +346,7 @@ static inline size_t
322
346
_PyType_PreHeaderSize (PyTypeObject * tp )
323
347
{
324
348
return _PyType_IS_GC (tp ) * sizeof (PyGC_Head ) +
325
- _PyType_HasFeature (tp , Py_TPFLAGS_MANAGED_DICT ) * 2 * sizeof (PyObject * );
349
+ _PyType_HasFeature (tp , Py_TPFLAGS_PREHEADER ) * 2 * sizeof (PyObject * );
326
350
}
327
351
328
352
void _PyObject_GC_Link (PyObject * op );
@@ -333,10 +357,6 @@ extern int _Py_CheckSlotResult(
333
357
const char * slot_name ,
334
358
int success );
335
359
336
- // PyType_Ready() must be called if _PyType_IsReady() is false.
337
- // See also the Py_TPFLAGS_READY flag.
338
- #define _PyType_IsReady (type ) ((type)->tp_dict != NULL)
339
-
340
360
// Test if a type supports weak references
341
361
static inline int _PyType_SUPPORTS_WEAKREFS (PyTypeObject * type ) {
342
362
return (type -> tp_weaklistoffset != 0 );
@@ -350,30 +370,50 @@ extern int _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values,
350
370
PyObject * _PyObject_GetInstanceAttribute (PyObject * obj , PyDictValues * values ,
351
371
PyObject * name );
352
372
353
- static inline PyDictValues * * _PyObject_ValuesPointer (PyObject * obj )
373
+ typedef union {
374
+ PyObject * dict ;
375
+ /* Use a char* to generate a warning if directly assigning a PyDictValues */
376
+ char * values ;
377
+ } PyDictOrValues ;
378
+
379
+ static inline PyDictOrValues *
380
+ _PyObject_DictOrValuesPointer (PyObject * obj )
354
381
{
355
382
assert (Py_TYPE (obj )-> tp_flags & Py_TPFLAGS_MANAGED_DICT );
356
- return ((PyDictValues * * )obj )- 4 ;
383
+ return ((PyDictOrValues * )obj )- 3 ;
384
+ }
385
+
386
+ static inline int
387
+ _PyDictOrValues_IsValues (PyDictOrValues dorv )
388
+ {
389
+ return ((uintptr_t )dorv .values ) & 1 ;
357
390
}
358
391
359
- static inline PyObject * * _PyObject_ManagedDictPointer (PyObject * obj )
392
+ static inline PyDictValues *
393
+ _PyDictOrValues_GetValues (PyDictOrValues dorv )
360
394
{
361
- assert (Py_TYPE (obj )-> tp_flags & Py_TPFLAGS_MANAGED_DICT );
362
- return ((PyObject * * )obj )- 3 ;
395
+ assert (_PyDictOrValues_IsValues (dorv ));
396
+ return (PyDictValues * )(dorv .values + 1 );
397
+ }
398
+
399
+ static inline PyObject *
400
+ _PyDictOrValues_GetDict (PyDictOrValues dorv )
401
+ {
402
+ assert (!_PyDictOrValues_IsValues (dorv ));
403
+ return dorv .dict ;
404
+ }
405
+
406
+ static inline void
407
+ _PyDictOrValues_SetValues (PyDictOrValues * ptr , PyDictValues * values )
408
+ {
409
+ ptr -> values = ((char * )values ) - 1 ;
363
410
}
364
411
365
- #define MANAGED_DICT_OFFSET (((int )sizeof(PyObject *))*-3 )
412
+ #define MANAGED_WEAKREF_OFFSET (((Py_ssize_t )sizeof(PyObject *))*-4 )
366
413
367
- extern PyObject * * _PyObject_DictPointer (PyObject * );
368
- extern int _PyObject_VisitInstanceAttributes (PyObject * self , visitproc visit , void * arg );
369
- extern void _PyObject_ClearInstanceAttributes (PyObject * self );
370
- extern void _PyObject_FreeInstanceAttributes (PyObject * self );
414
+ extern PyObject * * _PyObject_ComputedDictPointer (PyObject * );
415
+ extern void _PyObject_FreeInstanceAttributes (PyObject * obj );
371
416
extern int _PyObject_IsInstanceDictEmpty (PyObject * );
372
- extern PyObject * _PyType_GetSubclasses (PyTypeObject * );
373
-
374
- // Access macro to the members which are floating "behind" the object
375
- #define _PyHeapType_GET_MEMBERS (etype ) \
376
- ((PyMemberDef *)(((char *)etype) + Py_TYPE(etype)->tp_basicsize))
377
417
378
418
PyAPI_FUNC (PyObject * ) _PyObject_LookupSpecial (PyObject * , PyObject * );
379
419
0 commit comments