@@ -50,28 +50,29 @@ extern "C" {
5050 CPython refcounting operations on it!
5151*/
5252
53-
54- #if !defined(Py_GIL_DISABLED ) && defined(Py_STACKREF_DEBUG )
55-
5653#define Py_INT_TAG 3
5754#define Py_TAG_INVALID 2
5855#define Py_TAG_REFCNT 1
5956#define Py_TAG_BITS 3
6057
58+ #define Py_TAGGED_SHIFT 2
59+
60+ #if !defined(Py_GIL_DISABLED ) && defined(Py_STACKREF_DEBUG )
61+
6162PyAPI_FUNC (PyObject * ) _Py_stackref_get_object (_PyStackRef ref );
6263PyAPI_FUNC (PyObject * ) _Py_stackref_close (_PyStackRef ref , const char * filename , int linenumber );
6364PyAPI_FUNC (_PyStackRef ) _Py_stackref_create (PyObject * obj , uint16_t flags , const char * filename , int linenumber );
6465PyAPI_FUNC (void ) _Py_stackref_record_borrow (_PyStackRef ref , const char * filename , int linenumber );
6566extern void _Py_stackref_associate (PyInterpreterState * interp , PyObject * obj , _PyStackRef ref );
6667
6768static const _PyStackRef PyStackRef_NULL = { .index = 0 };
68- static const _PyStackRef PyStackRef_ERROR = { .index = 4 };
69+ static const _PyStackRef PyStackRef_ERROR = { .index = ( 1 << Py_TAGGED_SHIFT ) };
6970
70- #define PyStackRef_None ((_PyStackRef){ .index = 8 } )
71- #define PyStackRef_False ((_PyStackRef){ .index = 12 })
72- #define PyStackRef_True ((_PyStackRef){ .index = 16 })
71+ #define PyStackRef_None ((_PyStackRef){ .index = (2 << Py_TAGGED_SHIFT) } )
72+ #define PyStackRef_False ((_PyStackRef){ .index = (3 << Py_TAGGED_SHIFT) })
73+ #define PyStackRef_True ((_PyStackRef){ .index = (4 << Py_TAGGED_SHIFT) })
7374
74- #define INITIAL_STACKREF_INDEX 20
75+ #define INITIAL_STACKREF_INDEX (5 << Py_TAGGED_SHIFT)
7576
7677static inline _PyStackRef
7778PyStackRef_Wrap (void * ptr )
@@ -111,7 +112,13 @@ PyStackRef_IsNull(_PyStackRef ref)
111112static inline bool
112113PyStackRef_IsError (_PyStackRef ref )
113114{
114- return ref .index == 4 ;
115+ return ref .index == (1 << Py_TAGGED_SHIFT );
116+ }
117+
118+ static inline bool
119+ PyStackRef_IsMalformed (_PyStackRef ref )
120+ {
121+ return (ref .index & Py_TAG_BITS ) == Py_TAG_INVALID ;
115122}
116123
117124static inline bool
@@ -315,6 +322,7 @@ _PyStackRef_MakeHeapSafe(_PyStackRef ref, const char *filename, int linenumber)
315322static inline _PyStackRef
316323_PyStackRef_FromPyObjectNewMortal (PyObject * obj , const char * filename , int linenumber )
317324{
325+ assert (obj != NULL );
318326 assert (!_Py_IsStaticImmortal (obj ));
319327 Py_XINCREF (obj );
320328 return _Py_stackref_create (obj , 0 , filename , linenumber );
@@ -337,11 +345,6 @@ PyStackRef_IsNullOrInt(_PyStackRef ref);
337345
338346#else
339347
340- #define Py_INT_TAG 3
341- #define Py_TAG_INVALID 2
342- #define Py_TAG_REFCNT 1
343- #define Py_TAG_BITS 3
344-
345348static const _PyStackRef PyStackRef_ERROR = { .bits = Py_TAG_INVALID };
346349
347350/* Wrap a pointer in a stack ref.
@@ -399,25 +402,25 @@ PyStackRef_IsTaggedInt(_PyStackRef i)
399402static inline _PyStackRef
400403PyStackRef_TagInt (intptr_t i )
401404{
402- assert (Py_ARITHMETIC_RIGHT_SHIFT (intptr_t , (i << 2 ), 2 ) == i );
403- return (_PyStackRef ){ .bits = ((((uintptr_t )i ) << 2 ) | Py_INT_TAG ) };
405+ assert (Py_ARITHMETIC_RIGHT_SHIFT (intptr_t , (i << Py_TAGGED_SHIFT ), Py_TAGGED_SHIFT ) == i );
406+ return (_PyStackRef ){ .bits = ((((uintptr_t )i ) << Py_TAGGED_SHIFT ) | Py_INT_TAG ) };
404407}
405408
406409static inline intptr_t
407410PyStackRef_UntagInt (_PyStackRef i )
408411{
409412 assert (PyStackRef_IsTaggedInt (i ));
410413 intptr_t val = (intptr_t )i .bits ;
411- return Py_ARITHMETIC_RIGHT_SHIFT (intptr_t , val , 2 );
414+ return Py_ARITHMETIC_RIGHT_SHIFT (intptr_t , val , Py_TAGGED_SHIFT );
412415}
413416
414417
415418static inline _PyStackRef
416419PyStackRef_IncrementTaggedIntNoOverflow (_PyStackRef ref )
417420{
418421 assert ((ref .bits & Py_TAG_BITS ) == Py_INT_TAG ); // Is tagged int
419- assert ((ref .bits & (~Py_TAG_BITS )) != (INT_MAX & (~Py_TAG_BITS ))); // Isn't about to overflow
420- return (_PyStackRef ){ .bits = ref .bits + 4 };
422+ assert ((ref .bits & (~Py_TAG_BITS )) != (INTPTR_MAX & (~Py_TAG_BITS ))); // Isn't about to overflow
423+ return (_PyStackRef ){ .bits = ref .bits + ( 1 << Py_TAGGED_SHIFT ) };
421424}
422425
423426#define PyStackRef_IsDeferredOrTaggedInt (ref ) (((ref).bits & Py_TAG_REFCNT) != 0)
0 commit comments