@@ -85,67 +85,81 @@ typedef union _PyStackRef {
85
85
# define PyStackRef_None ((_PyStackRef){.bits = ((uintptr_t)&_Py_NoneStruct) })
86
86
#endif
87
87
88
- // Note: the following are all macros because MSVC (Windows) has trouble inlining them.
89
88
90
- #define PyStackRef_Is (a , b ) ((a).bits == (b).bits)
91
-
92
- #define PyStackRef_IsDeferred (ref ) (((ref).bits & Py_TAG_BITS) == Py_TAG_DEFERRED)
89
+ static inline int
90
+ PyStackRef_Is (_PyStackRef a , _PyStackRef b ) {
91
+ return a .bits == b .bits ;
92
+ }
93
93
94
+ static inline int
95
+ PyStackRef_IsDeferred (_PyStackRef ref )
96
+ {
97
+ return ((ref .bits & Py_TAG_BITS ) == Py_TAG_DEFERRED );
98
+ }
94
99
95
- #ifdef Py_GIL_DISABLED
96
100
// Gets a PyObject * from a _PyStackRef
97
101
static inline PyObject *
98
102
PyStackRef_AsPyObjectBorrow (_PyStackRef stackref )
99
103
{
104
+ #ifdef Py_GIL_DISABLED
100
105
PyObject * cleared = ((PyObject * )((stackref ).bits & (~Py_TAG_BITS )));
101
106
return cleared ;
102
- }
103
107
#else
104
- # define PyStackRef_AsPyObjectBorrow ( stackref ) ((PyObject *)(stackref).bits)
108
+ return ((PyObject * )(stackref ).bits );
105
109
#endif
110
+ }
106
111
107
112
// Converts a PyStackRef back to a PyObject *, stealing the
108
113
// PyStackRef.
109
- #ifdef Py_GIL_DISABLED
110
114
static inline PyObject *
111
115
PyStackRef_AsPyObjectSteal (_PyStackRef stackref )
112
116
{
117
+ #ifdef Py_GIL_DISABLED
113
118
if (!PyStackRef_IsNull (stackref ) && PyStackRef_IsDeferred (stackref )) {
114
119
return Py_NewRef (PyStackRef_AsPyObjectBorrow (stackref ));
115
120
}
116
121
return PyStackRef_AsPyObjectBorrow (stackref );
117
- }
118
122
#else
119
- # define PyStackRef_AsPyObjectSteal ( stackref ) PyStackRef_AsPyObjectBorrow(stackref)
123
+ return PyStackRef_AsPyObjectBorrow (stackref );
120
124
#endif
125
+ }
121
126
122
127
// Converts a PyStackRef back to a PyObject *, converting the
123
128
// stackref to a new reference.
124
- #define PyStackRef_AsPyObjectNew (stackref ) Py_NewRef(PyStackRef_AsPyObjectBorrow(stackref))
129
+ static inline PyObject *
130
+ PyStackRef_AsPyObjectNew (_PyStackRef stackref )
131
+ {
132
+ return Py_NewRef (PyStackRef_AsPyObjectBorrow (stackref ));
133
+ }
125
134
126
- #define PyStackRef_TYPE (stackref ) Py_TYPE(PyStackRef_AsPyObjectBorrow(stackref))
135
+ static inline PyTypeObject *
136
+ PyStackRef_TYPE (_PyStackRef stackref )
137
+ {
138
+ return Py_TYPE (PyStackRef_AsPyObjectBorrow (stackref ));
139
+ }
127
140
128
141
// Converts a PyObject * to a PyStackRef, stealing the reference
129
- #ifdef Py_GIL_DISABLED
130
142
static inline _PyStackRef
131
143
_PyStackRef_FromPyObjectSteal (PyObject * obj )
132
144
{
145
+ #ifdef Py_GIL_DISABLED
133
146
// Make sure we don't take an already tagged value.
134
147
assert (((uintptr_t )obj & Py_TAG_BITS ) == 0 );
135
148
int tag = (obj == NULL || _Py_IsImmortal (obj )) ? (Py_TAG_DEFERRED ) : Py_TAG_PTR ;
136
149
return ((_PyStackRef ){.bits = ((uintptr_t )(obj )) | tag });
137
- }
138
- # define PyStackRef_FromPyObjectSteal (obj ) _PyStackRef_FromPyObjectSteal(_PyObject_CAST(obj))
139
150
#else
140
- # define PyStackRef_FromPyObjectSteal ( obj ) ((_PyStackRef){.bits = ((uintptr_t)(obj))})
151
+ return ((_PyStackRef ){.bits = ((uintptr_t )(obj ))});
141
152
#endif
153
+ }
154
+
155
+ #define PyStackRef_FromPyObjectSteal (obj ) _PyStackRef_FromPyObjectSteal(_PyObject_CAST(obj))
142
156
143
157
144
158
// Converts a PyObject * to a PyStackRef, with a new reference
145
- #ifdef Py_GIL_DISABLED
146
159
static inline _PyStackRef
147
160
PyStackRef_FromPyObjectNew (PyObject * obj )
148
161
{
162
+ #ifdef Py_GIL_DISABLED
149
163
// Make sure we don't take an already tagged value.
150
164
assert (((uintptr_t )obj & Py_TAG_BITS ) == 0 );
151
165
assert (obj != NULL );
@@ -156,27 +170,30 @@ PyStackRef_FromPyObjectNew(PyObject *obj)
156
170
else {
157
171
return (_PyStackRef ){ .bits = (uintptr_t )(Py_NewRef (obj )) | Py_TAG_PTR };
158
172
}
159
- }
160
- # define PyStackRef_FromPyObjectNew (obj ) PyStackRef_FromPyObjectNew(_PyObject_CAST(obj))
161
173
#else
162
- # define PyStackRef_FromPyObjectNew ( obj ) ((_PyStackRef){ .bits = (uintptr_t)(Py_NewRef(obj)) })
174
+ return ((_PyStackRef ){ .bits = (uintptr_t )(Py_NewRef (obj )) });
163
175
#endif
176
+ }
177
+
178
+ #define PyStackRef_FromPyObjectNew (obj ) PyStackRef_FromPyObjectNew(_PyObject_CAST(obj))
164
179
165
- #ifdef Py_GIL_DISABLED
166
180
// Same as PyStackRef_FromPyObjectNew but only for immortal objects.
167
181
static inline _PyStackRef
168
182
PyStackRef_FromPyObjectImmortal (PyObject * obj )
169
183
{
184
+ #ifdef Py_GIL_DISABLED
170
185
// Make sure we don't take an already tagged value.
171
186
assert (((uintptr_t )obj & Py_TAG_BITS ) == 0 );
172
187
assert (obj != NULL );
173
188
assert (_Py_IsImmortal (obj ));
174
189
return (_PyStackRef ){ .bits = (uintptr_t )obj | Py_TAG_DEFERRED };
175
- }
176
- # define PyStackRef_FromPyObjectImmortal (obj ) PyStackRef_FromPyObjectImmortal(_PyObject_CAST(obj))
177
190
#else
178
- # define PyStackRef_FromPyObjectImmortal (obj ) ((_PyStackRef){ .bits = (uintptr_t)(obj) })
191
+ assert (_Py_IsImmortal (obj ));
192
+ return ((_PyStackRef ){ .bits = (uintptr_t )(obj ) });
179
193
#endif
194
+ }
195
+
196
+ #define PyStackRef_FromPyObjectImmortal (obj ) PyStackRef_FromPyObjectImmortal(_PyObject_CAST(obj))
180
197
181
198
182
199
#define PyStackRef_CLEAR (op ) \
@@ -189,20 +206,20 @@ PyStackRef_FromPyObjectImmortal(PyObject *obj)
189
206
} \
190
207
} while (0)
191
208
192
- #ifdef Py_GIL_DISABLED
193
209
static inline void
194
210
PyStackRef_CLOSE (_PyStackRef stackref )
195
211
{
212
+ #ifdef Py_GIL_DISABLED
196
213
if (PyStackRef_IsDeferred (stackref )) {
197
214
// No assert for being immortal or deferred here.
198
215
// The GC unsets deferred objects right before clearing.
199
216
return ;
200
217
}
201
218
Py_DECREF (PyStackRef_AsPyObjectBorrow (stackref ));
202
- }
203
219
#else
204
- # define PyStackRef_CLOSE ( stackref ) Py_DECREF(PyStackRef_AsPyObjectBorrow(stackref));
220
+ Py_DECREF (PyStackRef_AsPyObjectBorrow (stackref ));
205
221
#endif
222
+ }
206
223
207
224
#define PyStackRef_XCLOSE (stackref ) \
208
225
do { \
@@ -213,21 +230,32 @@ PyStackRef_CLOSE(_PyStackRef stackref)
213
230
} while (0);
214
231
215
232
216
- #ifdef Py_GIL_DISABLED
217
233
static inline _PyStackRef
218
234
PyStackRef_DUP (_PyStackRef stackref )
219
235
{
236
+ #ifdef Py_GIL_DISABLED
220
237
if (PyStackRef_IsDeferred (stackref )) {
221
238
assert (PyStackRef_IsNull (stackref ) ||
222
239
_Py_IsImmortal (PyStackRef_AsPyObjectBorrow (stackref )));
223
240
return stackref ;
224
241
}
225
242
Py_INCREF (PyStackRef_AsPyObjectBorrow (stackref ));
226
243
return stackref ;
227
- }
228
244
#else
229
- # define PyStackRef_DUP (stackref ) PyStackRef_FromPyObjectSteal(Py_NewRef(PyStackRef_AsPyObjectBorrow(stackref)));
245
+ Py_INCREF (PyStackRef_AsPyObjectBorrow (stackref ));
246
+ return stackref ;
230
247
#endif
248
+ }
249
+
250
+ static inline _PyStackRef
251
+ PyStackRef_XDUP (_PyStackRef stackref )
252
+ {
253
+ if (!PyStackRef_IsNull (stackref )) {
254
+ return PyStackRef_DUP (stackref );
255
+ }
256
+ return stackref ;
257
+ }
258
+
231
259
232
260
static inline void
233
261
_PyObjectStack_FromStackRefStack (PyObject * * dst , const _PyStackRef * src , size_t length )
0 commit comments