@@ -165,7 +165,7 @@ PyStackRef_IsHeapSafe(_PyStackRef ref)
165165}
166166
167167static inline _PyStackRef
168- PyStackRef_HeapSafe (_PyStackRef ref )
168+ PyStackRef_MakeHeapSafe (_PyStackRef ref )
169169{
170170 return ref ;
171171}
@@ -200,58 +200,73 @@ PyStackRef_AsStrongReference(_PyStackRef stackref)
200200// With GIL
201201
202202#define Py_TAG_BITS 3
203- #define Py_NULL_BIT 2
203+ #define Py_TAG_IMMORTAL 3
204204#define Py_TAG_REFCNT 1
205205#define BITS_TO_PTR (REF ) ((PyObject *)((REF).bits))
206206#define BITS_TO_PTR_MASKED (REF ) ((PyObject *)(((REF).bits) & (~Py_TAG_BITS)))
207207
208- #define PyStackRef_NULL_BITS (Py_TAG_REFCNT | Py_NULL_BIT)
208+ #define PyStackRef_NULL_BITS Py_TAG_IMMORTAL
209209static const _PyStackRef PyStackRef_NULL = { .bits = PyStackRef_NULL_BITS };
210210
211211#define PyStackRef_IsNull (ref ) ((ref).bits == PyStackRef_NULL_BITS)
212- #define PyStackRef_True ((_PyStackRef){.bits = ((uintptr_t)&_Py_TrueStruct) | Py_TAG_REFCNT })
213- #define PyStackRef_False ((_PyStackRef){.bits = ((uintptr_t)&_Py_FalseStruct) | Py_TAG_REFCNT })
214- #define PyStackRef_None ((_PyStackRef){.bits = ((uintptr_t)&_Py_NoneStruct) | Py_TAG_REFCNT })
212+ #define PyStackRef_True ((_PyStackRef){.bits = ((uintptr_t)&_Py_TrueStruct) | Py_TAG_IMMORTAL })
213+ #define PyStackRef_False ((_PyStackRef){.bits = ((uintptr_t)&_Py_FalseStruct) | Py_TAG_IMMORTAL })
214+ #define PyStackRef_None ((_PyStackRef){.bits = ((uintptr_t)&_Py_NoneStruct) | Py_TAG_IMMORTAL })
215215
216- // #define PyStackRef_IsTrue(ref) ((ref).bits == (((uintptr_t)&_Py_TrueStruct) | Py_TAG_REFCNT ))
217- // #define PyStackRef_IsFalse(ref) ((ref).bits == (((uintptr_t)&_Py_FalseStruct) | Py_TAG_REFCNT ))
218- // #define PyStackRef_IsNone(ref) ((ref).bits == (((uintptr_t)&_Py_NoneStruct) | Py_TAG_REFCNT))
216+ // #define PyStackRef_IsTrue(ref) ((ref).bits == (((uintptr_t)&_Py_TrueStruct) | Py_TAG_IMMORTAL ))
217+ // #define PyStackRef_IsFalse(ref) ((ref).bits == (((uintptr_t)&_Py_FalseStruct) | Py_TAG_IMMORTAL ))
218+ // #define
219219
220220/* We should be able to guarantee that the tag bits are set for immortal objects */
221221
222222#define PyStackRef_IsTrue (ref ) (((ref).bits & (~Py_TAG_BITS)) == ((uintptr_t)&_Py_TrueStruct))
223223#define PyStackRef_IsFalse (ref ) (((ref).bits & (~Py_TAG_BITS)) == ((uintptr_t)&_Py_FalseStruct))
224- // #define PyStackRef_IsNone(ref) (((ref).bits & (~Py_TAG_BITS)) == ((uintptr_t)&_Py_NoneStruct))
225224
226225
227226static inline void PyStackRef_CheckValid (_PyStackRef ref ) {
228227 int tag = ref .bits & Py_TAG_BITS ;
229- if (tag == PyStackRef_NULL_BITS ) {
230- assert (ref .bits == PyStackRef_NULL_BITS );
231- }
232- else if (tag == 0 ) {
233- assert (!_Py_IsImmortal (BITS_TO_PTR_MASKED (ref )));
228+ PyObject * obj = BITS_TO_PTR_MASKED (ref );
229+ switch (tag ) {
230+ case 0 :
231+ assert (!_Py_IsImmortal (obj ));
232+ break ;
233+ case Py_TAG_REFCNT :
234+ /* Can be immortal if object was made immortal after reference came into existence */
235+ assert (obj != NULL && obj != Py_True && obj != Py_False && obj != Py_None );
236+ break ;
237+ case Py_TAG_IMMORTAL :
238+ assert (obj == NULL || _Py_IsImmortal (obj ));
239+ break ;
240+ default :
241+ assert (0 );
234242 }
235243}
236244
245+ #ifdef Py_DEBUG
237246static inline int
238247PyStackRef_IsNone (_PyStackRef ref )
239248{
240249 if ((ref .bits & (~Py_TAG_BITS )) == ((uintptr_t )& _Py_NoneStruct )) {
241- assert ((ref .bits & Py_TAG_BITS ) == Py_TAG_REFCNT );
250+ assert ((ref .bits & Py_TAG_BITS ) == Py_TAG_IMMORTAL );
242251 return 1 ;
243252 }
244253 return 0 ;
245254}
246255
256+ #else
257+
258+ #define PyStackRef_IsNone (REF ) ((REF).bits == (((uintptr_t)&_Py_NoneStruct) | Py_TAG_IMMORTAL))
259+
260+ #endif
261+
247262static inline int
248263PyStackRef_HasCount (_PyStackRef ref )
249264{
250265 return ref .bits & Py_TAG_REFCNT ;
251266}
252267
253- static inline int
254- PyStackRef_HasCountAndNotNull (_PyStackRef ref )
268+ static inline bool
269+ PyStackRef_HasCountAndMortal (_PyStackRef ref )
255270{
256271 return (ref .bits & Py_TAG_BITS ) == Py_TAG_REFCNT ;
257272}
@@ -280,7 +295,7 @@ static inline _PyStackRef
280295PyStackRef_FromPyObjectSteal (PyObject * obj )
281296{
282297 assert (obj != NULL );
283- unsigned int tag = _Py_IsImmortal (obj ) ? Py_TAG_REFCNT : 0 ;
298+ unsigned int tag = _Py_IsImmortal (obj ) ? Py_TAG_IMMORTAL : 0 ;
284299 _PyStackRef ref = ((_PyStackRef ){.bits = ((uintptr_t )(obj )) | tag });
285300 PyStackRef_CheckValid (ref );
286301 return ref ;
@@ -295,8 +310,8 @@ PyStackRef_FromPyObjectSteal(PyObject *obj)
295310static inline _PyStackRef
296311_PyStackRef_FromPyObjectNew (PyObject * obj )
297312{
298- if (_Py_IsDeferrable (obj )) {
299- return (_PyStackRef ){ .bits = ((uintptr_t )obj ) | Py_TAG_REFCNT };
313+ if (_Py_IsImmortal (obj )) {
314+ return (_PyStackRef ){ .bits = ((uintptr_t )obj ) | Py_TAG_IMMORTAL };
300315 }
301316 Py_INCREF_MORTAL (obj );
302317 _PyStackRef ref = (_PyStackRef ){ .bits = (uintptr_t )obj };
@@ -307,14 +322,11 @@ _PyStackRef_FromPyObjectNew(PyObject *obj)
307322
308323/* Create a new reference from an object with an embedded reference count */
309324static inline _PyStackRef
310- _PyStackRef_FromPyObjectWithCount (PyObject * obj )
325+ PyStackRef_FromPyObjectImmortal (PyObject * obj )
311326{
312- return (_PyStackRef ){ .bits = (uintptr_t )obj | Py_TAG_REFCNT };
327+ assert (_Py_IsImmortal (obj ));
328+ return (_PyStackRef ){ .bits = (uintptr_t )obj | Py_TAG_IMMORTAL };
313329}
314- #define PyStackRef_FromPyObjectWithCount (obj ) _PyStackRef_FromPyObjectWithCount(_PyObject_CAST(obj))
315-
316- #define PyStackRef_FromPyObjectImmortal PyStackRef_FromPyObjectWithCount
317-
318330
319331static inline _PyStackRef
320332PyStackRef_DUP (_PyStackRef ref )
@@ -326,26 +338,19 @@ PyStackRef_DUP(_PyStackRef ref)
326338 return ref ;
327339}
328340
329- static inline int
341+ static inline bool
330342PyStackRef_IsHeapSafe (_PyStackRef ref )
331343{
332- return (
333- PyStackRef_IsNull (ref ) ||
334- !PyStackRef_HasCount (ref ) ||
335- _Py_IsImmortal (PyStackRef_AsPyObjectBorrow (ref ))
336- );
344+ return !PyStackRef_HasCountAndMortal (ref );
337345}
338346
339347static inline _PyStackRef
340- PyStackRef_HeapSafe (_PyStackRef ref )
348+ PyStackRef_MakeHeapSafe (_PyStackRef ref )
341349{
342- if (!PyStackRef_HasCountAndNotNull (ref )) {
350+ if (!PyStackRef_HasCountAndMortal (ref )) {
343351 return ref ;
344352 }
345353 PyObject * obj = BITS_TO_PTR_MASKED (ref );
346- if (_Py_IsImmortal (obj )) {
347- return ref ;
348- }
349354 Py_INCREF_MORTAL (obj );
350355 ref .bits = (uintptr_t )obj ;
351356 PyStackRef_CheckValid (ref );
0 commit comments