From 8ab6dc81ae9977185836174a44266fbff3427edc Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Wed, 11 Nov 2020 12:30:31 +0800 Subject: [PATCH 1/6] Use PyType_GetSlot() in Py_TRASHCAN_BEGIN macro. --- Include/cpython/object.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Include/cpython/object.h b/Include/cpython/object.h index ec6a3647677766..cd638b7b921da5 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -538,7 +538,7 @@ PyAPI_FUNC(void) _PyTrash_end(struct _ts *tstate); #define Py_TRASHCAN_BEGIN(op, dealloc) \ Py_TRASHCAN_BEGIN_CONDITION(op, \ - Py_TYPE(op)->tp_dealloc == (destructor)(dealloc)) + PyType_GetSlot(Py_TYPE(op), Py_tp_dealloc) == (destructor)(dealloc)) /* For backwards compatibility, these macros enable the trashcan * unconditionally */ From b288c3ed8fe67606dc332c1c5e87dc3da2156730 Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Fri, 13 Nov 2020 02:11:19 +0800 Subject: [PATCH 2/6] add the _PyTrash_cond() function --- Doc/whatsnew/3.10.rst | 5 +++++ Include/cpython/object.h | 5 +++-- .../next/C API/2020-11-13-01-40-28.bpo-40170.uh8lEf.rst | 3 +++ Objects/object.c | 9 +++++++++ 4 files changed, 20 insertions(+), 2 deletions(-) create mode 100644 Misc/NEWS.d/next/C API/2020-11-13-01-40-28.bpo-40170.uh8lEf.rst diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index 74c1c28ec0ff3b..cbf114d3a14345 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -439,6 +439,11 @@ New Features * The :c:func:`PyType_GetSlot` function can accept static types. (Contributed by Hai Shi and Petr Viktorin in :issue:`41073`.) +* The ``Py_TRASHCAN_BEGIN`` macro no longer accesses PyTypeObject attributes, + but now can get the condition by calling the new private + :c:func:`_PyTrash_cond()` function which hides implementation details. + (Contributed by Hai Shi in :issue:`40170`.) + Porting to Python 3.10 ---------------------- diff --git a/Include/cpython/object.h b/Include/cpython/object.h index cd638b7b921da5..de91e0d555ef61 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -515,6 +515,8 @@ struct _ts; /* Python 3.9 private API, invoked by the macros below. */ PyAPI_FUNC(int) _PyTrash_begin(struct _ts *tstate, PyObject *op); PyAPI_FUNC(void) _PyTrash_end(struct _ts *tstate); +/* Python 3.10 private API, invoked by the macros below. */ +PyAPI_FUNC(int) _PyTrash_cond(void *op_raw, void *dealloc); #define PyTrash_UNWIND_LEVEL 50 @@ -537,8 +539,7 @@ PyAPI_FUNC(void) _PyTrash_end(struct _ts *tstate); } while (0); #define Py_TRASHCAN_BEGIN(op, dealloc) \ - Py_TRASHCAN_BEGIN_CONDITION(op, \ - PyType_GetSlot(Py_TYPE(op), Py_tp_dealloc) == (destructor)(dealloc)) + Py_TRASHCAN_BEGIN_CONDITION(op, _PyTrash_cond(op, dealloc)); /* For backwards compatibility, these macros enable the trashcan * unconditionally */ diff --git a/Misc/NEWS.d/next/C API/2020-11-13-01-40-28.bpo-40170.uh8lEf.rst b/Misc/NEWS.d/next/C API/2020-11-13-01-40-28.bpo-40170.uh8lEf.rst new file mode 100644 index 00000000000000..741f9520686f31 --- /dev/null +++ b/Misc/NEWS.d/next/C API/2020-11-13-01-40-28.bpo-40170.uh8lEf.rst @@ -0,0 +1,3 @@ +The ``Py_TRASHCAN_BEGIN`` macro no longer accesses PyTypeObject attributes, +but now can get the condition by calling the new private +:c:func:`_PyTrash_cond()` function which hides implementation details. diff --git a/Objects/object.c b/Objects/object.c index be7790eefd118f..e57f75766cbff0 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2134,6 +2134,15 @@ _PyTrash_end(PyThreadState *tstate) } +int +_PyTrash_cond(void *op_raw, void *dealloc) +{ + PyObject *op = _PyObject_CAST(op_raw); + PyTypeObject *tp = Py_TYPE(op); + return tp->tp_dealloc == (destructor)dealloc; +} + + void _Py_NO_RETURN _PyObject_AssertFailed(PyObject *obj, const char *expr, const char *msg, const char *file, int line, const char *function) From a0c82d7bf4fd53cca29556c3e293e2dc73a1a144 Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Fri, 13 Nov 2020 12:26:33 +0800 Subject: [PATCH 3/6] apply victor's comment --- Doc/whatsnew/3.10.rst | 5 ----- Include/cpython/object.h | 6 +++--- Objects/object.c | 3 +-- 3 files changed, 4 insertions(+), 10 deletions(-) diff --git a/Doc/whatsnew/3.10.rst b/Doc/whatsnew/3.10.rst index cbf114d3a14345..74c1c28ec0ff3b 100644 --- a/Doc/whatsnew/3.10.rst +++ b/Doc/whatsnew/3.10.rst @@ -439,11 +439,6 @@ New Features * The :c:func:`PyType_GetSlot` function can accept static types. (Contributed by Hai Shi and Petr Viktorin in :issue:`41073`.) -* The ``Py_TRASHCAN_BEGIN`` macro no longer accesses PyTypeObject attributes, - but now can get the condition by calling the new private - :c:func:`_PyTrash_cond()` function which hides implementation details. - (Contributed by Hai Shi in :issue:`40170`.) - Porting to Python 3.10 ---------------------- diff --git a/Include/cpython/object.h b/Include/cpython/object.h index de91e0d555ef61..9f9a092ab771bb 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -515,8 +515,8 @@ struct _ts; /* Python 3.9 private API, invoked by the macros below. */ PyAPI_FUNC(int) _PyTrash_begin(struct _ts *tstate, PyObject *op); PyAPI_FUNC(void) _PyTrash_end(struct _ts *tstate); -/* Python 3.10 private API, invoked by the macros below. */ -PyAPI_FUNC(int) _PyTrash_cond(void *op_raw, void *dealloc); +/* Python 3.10 private API, invoked by the Py_TRASHCAN_BEGIN(). */ +PyAPI_FUNC(int) _PyTrash_cond(PyObject *op, void *dealloc); #define PyTrash_UNWIND_LEVEL 50 @@ -539,7 +539,7 @@ PyAPI_FUNC(int) _PyTrash_cond(void *op_raw, void *dealloc); } while (0); #define Py_TRASHCAN_BEGIN(op, dealloc) \ - Py_TRASHCAN_BEGIN_CONDITION(op, _PyTrash_cond(op, dealloc)); + Py_TRASHCAN_BEGIN_CONDITION(op, _PyTrash_cond(_PyObject_CAST(op), dealloc)) /* For backwards compatibility, these macros enable the trashcan * unconditionally */ diff --git a/Objects/object.c b/Objects/object.c index e57f75766cbff0..85866d236970cc 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2135,9 +2135,8 @@ _PyTrash_end(PyThreadState *tstate) int -_PyTrash_cond(void *op_raw, void *dealloc) +_PyTrash_cond(PyObject *op, void *dealloc) { - PyObject *op = _PyObject_CAST(op_raw); PyTypeObject *tp = Py_TYPE(op); return tp->tp_dealloc == (destructor)dealloc; } From 3d2f872aac9a1c269d1db886c715359de21c5f28 Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Fri, 13 Nov 2020 22:33:31 +0800 Subject: [PATCH 4/6] apply victor's comment --- Objects/object.c | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/Objects/object.c b/Objects/object.c index 85866d236970cc..e04f5bc5953cfb 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2137,8 +2137,7 @@ _PyTrash_end(PyThreadState *tstate) int _PyTrash_cond(PyObject *op, void *dealloc) { - PyTypeObject *tp = Py_TYPE(op); - return tp->tp_dealloc == (destructor)dealloc; + return Py_TYPE(op)->tp_dealloc == (destructor)dealloc; } From db2d98cf58237fe8ddbb186927c65649173e7ce1 Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Fri, 13 Nov 2020 23:13:46 +0800 Subject: [PATCH 5/6] apply victor's comment --- Include/cpython/object.h | 5 +++-- Objects/object.c | 4 ++-- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/Include/cpython/object.h b/Include/cpython/object.h index 9f9a092ab771bb..506cb106c75427 100644 --- a/Include/cpython/object.h +++ b/Include/cpython/object.h @@ -516,7 +516,7 @@ struct _ts; PyAPI_FUNC(int) _PyTrash_begin(struct _ts *tstate, PyObject *op); PyAPI_FUNC(void) _PyTrash_end(struct _ts *tstate); /* Python 3.10 private API, invoked by the Py_TRASHCAN_BEGIN(). */ -PyAPI_FUNC(int) _PyTrash_cond(PyObject *op, void *dealloc); +PyAPI_FUNC(int) _PyTrash_cond(PyObject *op, destructor dealloc); #define PyTrash_UNWIND_LEVEL 50 @@ -539,7 +539,8 @@ PyAPI_FUNC(int) _PyTrash_cond(PyObject *op, void *dealloc); } while (0); #define Py_TRASHCAN_BEGIN(op, dealloc) \ - Py_TRASHCAN_BEGIN_CONDITION(op, _PyTrash_cond(_PyObject_CAST(op), dealloc)) + Py_TRASHCAN_BEGIN_CONDITION(op, \ + _PyTrash_cond(_PyObject_CAST(op), (destructor)dealloc)) /* For backwards compatibility, these macros enable the trashcan * unconditionally */ diff --git a/Objects/object.c b/Objects/object.c index e04f5bc5953cfb..05eb01e2bd12a5 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2135,9 +2135,9 @@ _PyTrash_end(PyThreadState *tstate) int -_PyTrash_cond(PyObject *op, void *dealloc) +_PyTrash_cond(PyObject *op, destructor dealloc) { - return Py_TYPE(op)->tp_dealloc == (destructor)dealloc; + return Py_TYPE(op)->tp_dealloc == dealloc; } From 477dbd8ba29d9b6063e7ecc7c07e1c366a98773c Mon Sep 17 00:00:00 2001 From: Hai Shi Date: Wed, 25 Nov 2020 02:06:49 +0800 Subject: [PATCH 6/6] apply victor's comment --- Objects/object.c | 2 ++ 1 file changed, 2 insertions(+) diff --git a/Objects/object.c b/Objects/object.c index 05eb01e2bd12a5..2e8717f506ca0e 100644 --- a/Objects/object.c +++ b/Objects/object.c @@ -2134,6 +2134,8 @@ _PyTrash_end(PyThreadState *tstate) } +/* bpo-40170: It's only be used in Py_TRASHCAN_BEGIN macro to hide + implementation details. */ int _PyTrash_cond(PyObject *op, destructor dealloc) {