Skip to content

[DRAFT] gh-105059: In C++, Py_INCREF() uses a function call #105764

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Closed
wants to merge 1 commit into from
Closed
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
42 changes: 33 additions & 9 deletions Include/object.h
Original file line number Diff line number Diff line change
Expand Up @@ -134,13 +134,21 @@ check by comparing the reference count field to the immortality reference count.
{ _Py_IMMORTAL_REFCNT }, \
(type) \
},
#else
#elif !defined(__cplusplus)
#define PyObject_HEAD_INIT(type) \
{ \
_PyObject_EXTRA_INIT \
{ 1 }, \
(type) \
},
#else
// gh-105059: In C++, ob_refcnt type is Py_ssize_t
#define PyObject_HEAD_INIT(type) \
{ \
_PyObject_EXTRA_INIT \
1, \
(type) \
},
#endif /* Py_BUILD_CORE */

#define PyVarObject_HEAD_INIT(type, size) \
Expand All @@ -165,12 +173,18 @@ check by comparing the reference count field to the immortality reference count.
*/
struct _object {
_PyObject_HEAD_EXTRA
#ifndef __cplusplus
union {
Py_ssize_t ob_refcnt;
#if SIZEOF_VOID_P > 4
PY_UINT32_T ob_refcnt_split[2];
#endif
};
#else
// gh-105059: In C++, avoid anonymous union for ob_refcnt.
// C++ uses opaque function calls for Py_INCREF() and Py_DECREF().
Py_ssize_t ob_refcnt;
#endif
PyTypeObject *ob_type;
};

Expand Down Expand Up @@ -611,15 +625,18 @@ PyAPI_FUNC(void) _Py_DecRef(PyObject *);
static inline Py_ALWAYS_INLINE void Py_INCREF(PyObject *op)
{
#if defined(Py_LIMITED_API) && (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG))
// Stable ABI implements Py_INCREF() as a function call on limited C API
// version 3.12 and newer, and on Python built in debug mode. _Py_IncRef()
// was added to Python 3.10.0a7, use Py_IncRef() on older Python versions.
// Py_IncRef() accepts NULL whereas _Py_IncRef() doesn't.
// In limited C API version 3.12 and newer and on Python built in debug
// mode, Py_INCREF() is implemented as a function call. _Py_IncRef() was
// added to Python 3.10.0a7, use Py_IncRef() on older Python versions.
// Py_IncRef() accepts NULL, whereas _Py_IncRef() doesn't.
# if Py_LIMITED_API+0 >= 0x030a00A7
_Py_IncRef(op);
# else
Py_IncRef(op);
# endif
#elif defined(__cplusplus)
// gh-105059: In C++, Py_INCREF() is implemented as a function call
_Py_IncRef(op);
#else
// Non-limited C API and limited C API for Python 3.9 and older access
// directly PyObject.ob_refcnt.
Expand Down Expand Up @@ -649,10 +666,10 @@ static inline Py_ALWAYS_INLINE void Py_INCREF(PyObject *op)
#endif

#if defined(Py_LIMITED_API) && (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG))
// Stable ABI implements Py_DECREF() as a function call on limited C API
// version 3.12 and newer, and on Python built in debug mode. _Py_DecRef() was
// added to Python 3.10.0a7, use Py_DecRef() on older Python versions.
// Py_DecRef() accepts NULL whereas _Py_IncRef() doesn't.
// In limited C API version 3.12 and newer and on Python built in debug mode,
// Py_DECREF() is implemented as a function call. _Py_DecRef() was added to
// Python 3.10.0a7, use Py_DecRef() on older Python versions. Py_DecRef()
// accepts NULL, whereas _Py_DecRef() doesn't.
static inline void Py_DECREF(PyObject *op) {
# if Py_LIMITED_API+0 >= 0x030a00A7
_Py_DecRef(op);
Expand All @@ -662,6 +679,13 @@ static inline void Py_DECREF(PyObject *op) {
}
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))

#elif defined(__cplusplus)
// gh-105059: In C++, Py_DECREF() is implemented as a function call
static inline void Py_DECREF(PyObject *op) {
_Py_DecRef(op);
}
#define Py_DECREF(op) Py_DECREF(_PyObject_CAST(op))

#elif defined(Py_REF_DEBUG)
static inline void Py_DECREF(const char *filename, int lineno, PyObject *op)
{
Expand Down