Skip to content

Commit 722229e

Browse files
gh-121263: Macro-ify most stackref functions for MSVC (GH-121270)
Macro-ify most stackref functions for MSVC
1 parent 9315688 commit 722229e

File tree

1 file changed

+30
-58
lines changed

1 file changed

+30
-58
lines changed

Include/internal/pycore_stackref.h

Lines changed: 30 additions & 58 deletions
Original file line numberDiff line numberDiff line change
@@ -85,81 +85,67 @@ typedef union _PyStackRef {
8585
# define PyStackRef_None ((_PyStackRef){.bits = ((uintptr_t)&_Py_NoneStruct) })
8686
#endif
8787

88+
// Note: the following are all macros because MSVC (Windows) has trouble inlining them.
8889

89-
static inline int
90-
PyStackRef_Is(_PyStackRef a, _PyStackRef b) {
91-
return a.bits == b.bits;
92-
}
90+
#define PyStackRef_Is(a, b) ((a).bits == (b).bits)
91+
92+
#define PyStackRef_IsDeferred(ref) (((ref).bits & Py_TAG_BITS) == Py_TAG_DEFERRED)
9393

94-
static inline int
95-
PyStackRef_IsDeferred(_PyStackRef ref)
96-
{
97-
return ((ref.bits & Py_TAG_BITS) == Py_TAG_DEFERRED);
98-
}
9994

95+
#ifdef Py_GIL_DISABLED
10096
// Gets a PyObject * from a _PyStackRef
10197
static inline PyObject *
10298
PyStackRef_AsPyObjectBorrow(_PyStackRef stackref)
10399
{
104-
#ifdef Py_GIL_DISABLED
105100
PyObject *cleared = ((PyObject *)((stackref).bits & (~Py_TAG_BITS)));
106101
return cleared;
102+
}
107103
#else
108-
return ((PyObject *)(stackref).bits);
104+
# define PyStackRef_AsPyObjectBorrow(stackref) ((PyObject *)(stackref).bits)
109105
#endif
110-
}
111106

112107
// Converts a PyStackRef back to a PyObject *, stealing the
113108
// PyStackRef.
109+
#ifdef Py_GIL_DISABLED
114110
static inline PyObject *
115111
PyStackRef_AsPyObjectSteal(_PyStackRef stackref)
116112
{
117-
#ifdef Py_GIL_DISABLED
118113
if (!PyStackRef_IsNull(stackref) && PyStackRef_IsDeferred(stackref)) {
119114
return Py_NewRef(PyStackRef_AsPyObjectBorrow(stackref));
120115
}
121116
return PyStackRef_AsPyObjectBorrow(stackref);
117+
}
122118
#else
123-
return PyStackRef_AsPyObjectBorrow(stackref);
119+
# define PyStackRef_AsPyObjectSteal(stackref) PyStackRef_AsPyObjectBorrow(stackref)
124120
#endif
125-
}
126121

127122
// Converts a PyStackRef back to a PyObject *, converting the
128123
// stackref to a new reference.
129-
static inline PyObject *
130-
PyStackRef_AsPyObjectNew(_PyStackRef stackref)
131-
{
132-
return Py_NewRef(PyStackRef_AsPyObjectBorrow(stackref));
133-
}
124+
#define PyStackRef_AsPyObjectNew(stackref) Py_NewRef(PyStackRef_AsPyObjectBorrow(stackref))
134125

135-
static inline PyTypeObject *
136-
PyStackRef_TYPE(_PyStackRef stackref)
137-
{
138-
return Py_TYPE(PyStackRef_AsPyObjectBorrow(stackref));
139-
}
126+
#define PyStackRef_TYPE(stackref) Py_TYPE(PyStackRef_AsPyObjectBorrow(stackref))
140127

141128
// Converts a PyObject * to a PyStackRef, stealing the reference
129+
#ifdef Py_GIL_DISABLED
142130
static inline _PyStackRef
143131
_PyStackRef_FromPyObjectSteal(PyObject *obj)
144132
{
145-
#ifdef Py_GIL_DISABLED
146133
// Make sure we don't take an already tagged value.
147134
assert(((uintptr_t)obj & Py_TAG_BITS) == 0);
148135
int tag = (obj == NULL || _Py_IsImmortal(obj)) ? (Py_TAG_DEFERRED) : Py_TAG_PTR;
149136
return ((_PyStackRef){.bits = ((uintptr_t)(obj)) | tag});
137+
}
138+
# define PyStackRef_FromPyObjectSteal(obj) _PyStackRef_FromPyObjectSteal(_PyObject_CAST(obj))
150139
#else
151-
return ((_PyStackRef){.bits = ((uintptr_t)(obj))});
140+
# define PyStackRef_FromPyObjectSteal(obj) ((_PyStackRef){.bits = ((uintptr_t)(obj))})
152141
#endif
153-
}
154-
155-
#define PyStackRef_FromPyObjectSteal(obj) _PyStackRef_FromPyObjectSteal(_PyObject_CAST(obj))
156142

157143

158144
// Converts a PyObject * to a PyStackRef, with a new reference
145+
#ifdef Py_GIL_DISABLED
159146
static inline _PyStackRef
160147
PyStackRef_FromPyObjectNew(PyObject *obj)
161148
{
162-
#ifdef Py_GIL_DISABLED
163149
// Make sure we don't take an already tagged value.
164150
assert(((uintptr_t)obj & Py_TAG_BITS) == 0);
165151
assert(obj != NULL);
@@ -170,30 +156,27 @@ PyStackRef_FromPyObjectNew(PyObject *obj)
170156
else {
171157
return (_PyStackRef){ .bits = (uintptr_t)(Py_NewRef(obj)) | Py_TAG_PTR };
172158
}
159+
}
160+
# define PyStackRef_FromPyObjectNew(obj) PyStackRef_FromPyObjectNew(_PyObject_CAST(obj))
173161
#else
174-
return ((_PyStackRef){ .bits = (uintptr_t)(Py_NewRef(obj)) });
162+
# define PyStackRef_FromPyObjectNew(obj) ((_PyStackRef){ .bits = (uintptr_t)(Py_NewRef(obj)) })
175163
#endif
176-
}
177-
178-
#define PyStackRef_FromPyObjectNew(obj) PyStackRef_FromPyObjectNew(_PyObject_CAST(obj))
179164

165+
#ifdef Py_GIL_DISABLED
180166
// Same as PyStackRef_FromPyObjectNew but only for immortal objects.
181167
static inline _PyStackRef
182168
PyStackRef_FromPyObjectImmortal(PyObject *obj)
183169
{
184-
#ifdef Py_GIL_DISABLED
185170
// Make sure we don't take an already tagged value.
186171
assert(((uintptr_t)obj & Py_TAG_BITS) == 0);
187172
assert(obj != NULL);
188173
assert(_Py_IsImmortal(obj));
189174
return (_PyStackRef){ .bits = (uintptr_t)obj | Py_TAG_DEFERRED };
175+
}
176+
# define PyStackRef_FromPyObjectImmortal(obj) PyStackRef_FromPyObjectImmortal(_PyObject_CAST(obj))
190177
#else
191-
assert(_Py_IsImmortal(obj));
192-
return ((_PyStackRef){ .bits = (uintptr_t)(obj) });
178+
# define PyStackRef_FromPyObjectImmortal(obj) ((_PyStackRef){ .bits = (uintptr_t)(obj) })
193179
#endif
194-
}
195-
196-
#define PyStackRef_FromPyObjectImmortal(obj) PyStackRef_FromPyObjectImmortal(_PyObject_CAST(obj))
197180

198181

199182
#define PyStackRef_CLEAR(op) \
@@ -206,20 +189,20 @@ PyStackRef_FromPyObjectImmortal(PyObject *obj)
206189
} \
207190
} while (0)
208191

192+
#ifdef Py_GIL_DISABLED
209193
static inline void
210194
PyStackRef_CLOSE(_PyStackRef stackref)
211195
{
212-
#ifdef Py_GIL_DISABLED
213196
if (PyStackRef_IsDeferred(stackref)) {
214197
// No assert for being immortal or deferred here.
215198
// The GC unsets deferred objects right before clearing.
216199
return;
217200
}
218201
Py_DECREF(PyStackRef_AsPyObjectBorrow(stackref));
202+
}
219203
#else
220-
Py_DECREF(PyStackRef_AsPyObjectBorrow(stackref));
204+
# define PyStackRef_CLOSE(stackref) Py_DECREF(PyStackRef_AsPyObjectBorrow(stackref));
221205
#endif
222-
}
223206

224207
#define PyStackRef_XCLOSE(stackref) \
225208
do { \
@@ -230,32 +213,21 @@ PyStackRef_CLOSE(_PyStackRef stackref)
230213
} while (0);
231214

232215

216+
#ifdef Py_GIL_DISABLED
233217
static inline _PyStackRef
234218
PyStackRef_DUP(_PyStackRef stackref)
235219
{
236-
#ifdef Py_GIL_DISABLED
237220
if (PyStackRef_IsDeferred(stackref)) {
238221
assert(PyStackRef_IsNull(stackref) ||
239222
_Py_IsImmortal(PyStackRef_AsPyObjectBorrow(stackref)));
240223
return stackref;
241224
}
242225
Py_INCREF(PyStackRef_AsPyObjectBorrow(stackref));
243226
return stackref;
227+
}
244228
#else
245-
Py_INCREF(PyStackRef_AsPyObjectBorrow(stackref));
246-
return stackref;
229+
# define PyStackRef_DUP(stackref) PyStackRef_FromPyObjectSteal(Py_NewRef(PyStackRef_AsPyObjectBorrow(stackref)));
247230
#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-
259231

260232
static inline void
261233
_PyObjectStack_FromStackRefStack(PyObject **dst, const _PyStackRef *src, size_t length)

0 commit comments

Comments
 (0)