bpo-40170: PyObject_GET_WEAKREFS_LISTPTR() becomes a function (GH-19377)

Convert the PyObject_GET_WEAKREFS_LISTPTR() macro to a function to
hide implementation details: the macro accessed directly to the
PyTypeObject.tp_weaklistoffset member.

Add _PyObject_GET_WEAKREFS_LISTPTR() static inline function to the
internal C API.
This commit is contained in:
Victor Stinner 2020-04-06 14:07:02 +02:00 committed by GitHub
parent 08050e959e
commit 38aefc585f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
8 changed files with 25 additions and 6 deletions

View File

@ -138,8 +138,7 @@ PyAPI_FUNC(PyObject *) _PyObject_GC_Calloc(size_t size);
/* Test if a type supports weak references */
#define PyType_SUPPORTS_WEAKREFS(t) ((t)->tp_weaklistoffset > 0)
#define PyObject_GET_WEAKREFS_LISTPTR(o) \
((PyObject **) (((char *) (o)) + Py_TYPE(o)->tp_weaklistoffset))
PyAPI_FUNC(PyObject **) PyObject_GET_WEAKREFS_LISTPTR(PyObject *op);
#ifdef __cplusplus
}

View File

@ -87,6 +87,13 @@ extern void _Py_PrintReferences(FILE *);
extern void _Py_PrintReferenceAddresses(FILE *);
#endif
static inline PyObject **
_PyObject_GET_WEAKREFS_LISTPTR(PyObject *op)
{
Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset;
return (PyObject **)((char *)op + offset);
}
#ifdef __cplusplus
}
#endif

View File

@ -0,0 +1,3 @@
Convert the :c:func:`PyObject_GET_WEAKREFS_LISTPTR` macro to a function to hide
implementation details: the macro accessed directly to the
:c:member:`PyTypeObject.tp_weaklistoffset` member.

View File

@ -1,8 +1,9 @@
#include "Python.h"
#include "pycore_object.h" // _PyObject_GET_WEAKREFS_LISTPTR
#define GET_WEAKREFS_LISTPTR(o) \
((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o))
((PyWeakReference **) _PyObject_GET_WEAKREFS_LISTPTR(o))
/*[clinic input]
module _weakref

View File

@ -788,7 +788,7 @@ handle_weakrefs(PyGC_Head *unreachable, PyGC_Head *old)
/* It supports weakrefs. Does it have any? */
wrlist = (PyWeakReference **)
PyObject_GET_WEAKREFS_LISTPTR(op);
_PyObject_GET_WEAKREFS_LISTPTR(op);
/* `op` may have some weakrefs. March over the list, clear
* all the weakrefs, and move the weakrefs with callbacks

View File

@ -2206,6 +2206,14 @@ _Py_Dealloc(PyObject *op)
(*dealloc)(op);
}
PyObject **
PyObject_GET_WEAKREFS_LISTPTR(PyObject *op)
{
return _PyObject_GET_WEAKREFS_LISTPTR(op);
}
#ifdef __cplusplus
}
#endif

View File

@ -1271,7 +1271,7 @@ subtype_dealloc(PyObject *self)
if (type->tp_weaklistoffset && !base->tp_weaklistoffset) {
/* Modeled after GET_WEAKREFS_LISTPTR() */
PyWeakReference **list = (PyWeakReference **) \
PyObject_GET_WEAKREFS_LISTPTR(self);
_PyObject_GET_WEAKREFS_LISTPTR(self);
while (*list)
_PyWeakref_ClearRef(*list);
}

View File

@ -1,9 +1,10 @@
#include "Python.h"
#include "pycore_object.h" // _PyObject_GET_WEAKREFS_LISTPTR
#include "structmember.h"
#define GET_WEAKREFS_LISTPTR(o) \
((PyWeakReference **) PyObject_GET_WEAKREFS_LISTPTR(o))
((PyWeakReference **) _PyObject_GET_WEAKREFS_LISTPTR(o))
Py_ssize_t