@@ -60,54 +60,22 @@ typedef union _PyStackRef {
6060#define Py_TAG_BITS ((uintptr_t)1)
6161
6262#ifdef Py_GIL_DISABLED
63- static const _PyStackRef PyStackRef_NULL = { .bits = 0 | Py_TAG_DEFERRED };
64- #else
65- static const _PyStackRef PyStackRef_NULL = { .bits = 0 };
66- #endif
6763
64+ static const _PyStackRef PyStackRef_NULL = { .bits = Py_TAG_DEFERRED };
6865#define PyStackRef_IsNull (stackref ) ((stackref).bits == PyStackRef_NULL.bits)
66+ #define PyStackRef_True ((_PyStackRef){.bits = ((uintptr_t)&_Py_TrueStruct) | Py_TAG_DEFERRED })
67+ #define PyStackRef_False ((_PyStackRef){.bits = ((uintptr_t)&_Py_FalseStruct) | Py_TAG_DEFERRED })
68+ #define PyStackRef_None ((_PyStackRef){.bits = ((uintptr_t)&_Py_NoneStruct) | Py_TAG_DEFERRED })
6969
70-
71- #ifdef Py_GIL_DISABLED
72- # define PyStackRef_True ((_PyStackRef){.bits = ((uintptr_t)&_Py_TrueStruct) | Py_TAG_DEFERRED })
73- #else
74- # define PyStackRef_True ((_PyStackRef){.bits = ((uintptr_t)&_Py_TrueStruct) })
75- #endif
76-
77- #ifdef Py_GIL_DISABLED
78- # define PyStackRef_False ((_PyStackRef){.bits = ((uintptr_t)&_Py_FalseStruct) | Py_TAG_DEFERRED })
79- #else
80- # define PyStackRef_False ((_PyStackRef){.bits = ((uintptr_t)&_Py_FalseStruct) })
81- #endif
82-
83- #ifdef Py_GIL_DISABLED
84- # define PyStackRef_None ((_PyStackRef){.bits = ((uintptr_t)&_Py_NoneStruct) | Py_TAG_DEFERRED })
85- #else
86- # define PyStackRef_None ((_PyStackRef){.bits = ((uintptr_t)&_Py_NoneStruct) })
87- #endif
88-
89- // Note: the following are all macros because MSVC (Windows) has trouble inlining them.
90-
91- #define PyStackRef_Is (a , b ) ((a).bits == (b).bits)
92-
93- #define PyStackRef_IsDeferred (ref ) (((ref).bits & Py_TAG_BITS) == Py_TAG_DEFERRED)
94-
95-
96- #ifdef Py_GIL_DISABLED
97- // Gets a PyObject * from a _PyStackRef
9870static inline PyObject *
9971PyStackRef_AsPyObjectBorrow (_PyStackRef stackref )
10072{
10173 PyObject * cleared = ((PyObject * )((stackref ).bits & (~Py_TAG_BITS )));
10274 return cleared ;
10375}
104- #else
105- # define PyStackRef_AsPyObjectBorrow (stackref ) ((PyObject *)(stackref).bits)
106- #endif
10776
108- // Converts a PyStackRef back to a PyObject *, stealing the
109- // PyStackRef.
110- #ifdef Py_GIL_DISABLED
77+ #define PyStackRef_IsDeferred (ref ) (((ref).bits & Py_TAG_BITS) == Py_TAG_DEFERRED)
78+
11179static inline PyObject *
11280PyStackRef_AsPyObjectSteal (_PyStackRef stackref )
11381{
@@ -117,18 +85,7 @@ PyStackRef_AsPyObjectSteal(_PyStackRef stackref)
11785 }
11886 return PyStackRef_AsPyObjectBorrow (stackref );
11987}
120- #else
121- # define PyStackRef_AsPyObjectSteal (stackref ) PyStackRef_AsPyObjectBorrow(stackref)
122- #endif
123-
124- // Converts a PyStackRef back to a PyObject *, converting the
125- // stackref to a new reference.
126- #define PyStackRef_AsPyObjectNew (stackref ) Py_NewRef(PyStackRef_AsPyObjectBorrow(stackref))
127-
128- #define PyStackRef_TYPE (stackref ) Py_TYPE(PyStackRef_AsPyObjectBorrow(stackref))
12988
130- // Converts a PyObject * to a PyStackRef, stealing the reference
131- #ifdef Py_GIL_DISABLED
13289static inline _PyStackRef
13390_PyStackRef_FromPyObjectSteal (PyObject * obj )
13491{
@@ -139,13 +96,7 @@ _PyStackRef_FromPyObjectSteal(PyObject *obj)
13996 return ((_PyStackRef ){.bits = ((uintptr_t )(obj )) | tag });
14097}
14198# define PyStackRef_FromPyObjectSteal (obj ) _PyStackRef_FromPyObjectSteal(_PyObject_CAST(obj))
142- #else
143- # define PyStackRef_FromPyObjectSteal (obj ) ((_PyStackRef){.bits = ((uintptr_t)(obj))})
144- #endif
145-
14699
147- // Converts a PyObject * to a PyStackRef, with a new reference
148- #ifdef Py_GIL_DISABLED
149100static inline _PyStackRef
150101PyStackRef_FromPyObjectNew (PyObject * obj )
151102{
@@ -159,13 +110,8 @@ PyStackRef_FromPyObjectNew(PyObject *obj)
159110 return (_PyStackRef ){ .bits = (uintptr_t )(Py_NewRef (obj )) | Py_TAG_PTR };
160111 }
161112}
162- # define PyStackRef_FromPyObjectNew (obj ) PyStackRef_FromPyObjectNew(_PyObject_CAST(obj))
163- #else
164- # define PyStackRef_FromPyObjectNew (obj ) ((_PyStackRef){ .bits = (uintptr_t)(Py_NewRef(obj)) })
165- #endif
113+ #define PyStackRef_FromPyObjectNew (obj ) PyStackRef_FromPyObjectNew(_PyObject_CAST(obj))
166114
167- #ifdef Py_GIL_DISABLED
168- // Same as PyStackRef_FromPyObjectNew but only for immortal objects.
169115static inline _PyStackRef
170116PyStackRef_FromPyObjectImmortal (PyObject * obj )
171117{
@@ -175,45 +121,17 @@ PyStackRef_FromPyObjectImmortal(PyObject *obj)
175121 assert (_Py_IsImmortal (obj ));
176122 return (_PyStackRef ){ .bits = (uintptr_t )obj | Py_TAG_DEFERRED };
177123}
178- # define PyStackRef_FromPyObjectImmortal (obj ) PyStackRef_FromPyObjectImmortal(_PyObject_CAST(obj))
179- #else
180- # define PyStackRef_FromPyObjectImmortal (obj ) ((_PyStackRef){ .bits = (uintptr_t)(obj) })
181- #endif
182-
183-
184- #define PyStackRef_CLEAR (op ) \
185- do { \
186- _PyStackRef *_tmp_op_ptr = &(op); \
187- _PyStackRef _tmp_old_op = (*_tmp_op_ptr); \
188- if (!PyStackRef_IsNull(_tmp_old_op)) { \
189- *_tmp_op_ptr = PyStackRef_NULL; \
190- PyStackRef_CLOSE(_tmp_old_op); \
191- } \
192- } while (0)
124+ #define PyStackRef_FromPyObjectImmortal (obj ) PyStackRef_FromPyObjectImmortal(_PyObject_CAST(obj))
193125
194- #ifdef Py_GIL_DISABLED
195- # define PyStackRef_CLOSE (REF ) \
126+ #define PyStackRef_CLOSE (REF ) \
196127 do { \
197128 _PyStackRef _close_tmp = (REF); \
198129 assert(!PyStackRef_IsNull(_close_tmp)); \
199130 if (!PyStackRef_IsDeferred(_close_tmp)) { \
200131 Py_DECREF(PyStackRef_AsPyObjectBorrow(_close_tmp)); \
201132 } \
202133 } while (0)
203- #else
204- # define PyStackRef_CLOSE (stackref ) Py_DECREF(PyStackRef_AsPyObjectBorrow(stackref))
205- #endif
206134
207- #define PyStackRef_XCLOSE (stackref ) \
208- do { \
209- _PyStackRef _tmp = (stackref); \
210- if (!PyStackRef_IsNull(_tmp)) { \
211- PyStackRef_CLOSE(_tmp); \
212- } \
213- } while (0);
214-
215-
216- #ifdef Py_GIL_DISABLED
217135static inline _PyStackRef
218136PyStackRef_DUP (_PyStackRef stackref )
219137{
@@ -227,9 +145,6 @@ PyStackRef_DUP(_PyStackRef stackref)
227145 Py_INCREF (PyStackRef_AsPyObjectBorrow (stackref ));
228146 return stackref ;
229147}
230- #else
231- # define PyStackRef_DUP (stackref ) PyStackRef_FromPyObjectSteal(Py_NewRef(PyStackRef_AsPyObjectBorrow(stackref)))
232- #endif
233148
234149// Convert a possibly deferred reference to a strong reference.
235150static inline _PyStackRef
@@ -238,13 +153,62 @@ PyStackRef_AsStrongReference(_PyStackRef stackref)
238153 return PyStackRef_FromPyObjectSteal (PyStackRef_AsPyObjectSteal (stackref ));
239154}
240155
241- static inline void
242- _PyObjectStack_FromStackRefStack (PyObject * * dst , const _PyStackRef * src , size_t length )
243- {
244- for (size_t i = 0 ; i < length ; i ++ ) {
245- dst [i ] = PyStackRef_AsPyObjectBorrow (src [i ]);
246- }
247- }
156+
157+ #else // Py_GIL_DISABLED
158+
159+ // With GIL
160+ static const _PyStackRef PyStackRef_NULL = { .bits = 0 };
161+ #define PyStackRef_IsNull (stackref ) ((stackref).bits == 0)
162+ #define PyStackRef_True ((_PyStackRef){.bits = (uintptr_t)&_Py_TrueStruct })
163+ #define PyStackRef_False ((_PyStackRef){.bits = ((uintptr_t)&_Py_FalseStruct) })
164+ #define PyStackRef_None ((_PyStackRef){.bits = ((uintptr_t)&_Py_NoneStruct) })
165+
166+ #define PyStackRef_AsPyObjectBorrow (stackref ) ((PyObject *)(stackref).bits)
167+
168+ #define PyStackRef_AsPyObjectSteal (stackref ) PyStackRef_AsPyObjectBorrow(stackref)
169+
170+ #define PyStackRef_FromPyObjectSteal (obj ) ((_PyStackRef){.bits = ((uintptr_t)(obj))})
171+
172+ #define PyStackRef_FromPyObjectNew (obj ) ((_PyStackRef){ .bits = (uintptr_t)(Py_NewRef(obj)) })
173+
174+ #define PyStackRef_FromPyObjectImmortal (obj ) ((_PyStackRef){ .bits = (uintptr_t)(obj) })
175+
176+ #define PyStackRef_CLOSE (stackref ) Py_DECREF(PyStackRef_AsPyObjectBorrow(stackref))
177+
178+ #define PyStackRef_DUP (stackref ) PyStackRef_FromPyObjectSteal(Py_NewRef(PyStackRef_AsPyObjectBorrow(stackref)))
179+
180+
181+ #endif // Py_GIL_DISABLED
182+
183+ // Note: this is a macro because MSVC (Windows) has trouble inlining it.
184+
185+ #define PyStackRef_Is (a , b ) ((a).bits == (b).bits)
186+
187+ // Converts a PyStackRef back to a PyObject *, converting the
188+ // stackref to a new reference.
189+ #define PyStackRef_AsPyObjectNew (stackref ) Py_NewRef(PyStackRef_AsPyObjectBorrow(stackref))
190+
191+ #define PyStackRef_TYPE (stackref ) Py_TYPE(PyStackRef_AsPyObjectBorrow(stackref))
192+
193+ #define PyStackRef_CLEAR (op ) \
194+ do { \
195+ _PyStackRef *_tmp_op_ptr = &(op); \
196+ _PyStackRef _tmp_old_op = (*_tmp_op_ptr); \
197+ if (!PyStackRef_IsNull(_tmp_old_op)) { \
198+ *_tmp_op_ptr = PyStackRef_NULL; \
199+ PyStackRef_CLOSE(_tmp_old_op); \
200+ } \
201+ } while (0)
202+
203+ #define PyStackRef_XCLOSE (stackref ) \
204+ do { \
205+ _PyStackRef _tmp = (stackref); \
206+ if (!PyStackRef_IsNull(_tmp)) { \
207+ PyStackRef_CLOSE(_tmp); \
208+ } \
209+ } while (0);
210+
211+
248212
249213// StackRef type checks
250214
0 commit comments