Skip to content

Commit

Permalink
Add PyMem_Raw{New,Resize} convenience macros.
Browse files Browse the repository at this point in the history
  • Loading branch information
picnixz committed Nov 28, 2024
1 parent 2313f84 commit 356196b
Show file tree
Hide file tree
Showing 5 changed files with 59 additions and 12 deletions.
25 changes: 25 additions & 0 deletions Doc/c-api/memory.rst
Original file line number Diff line number Diff line change
Expand Up @@ -199,6 +199,31 @@ zero bytes.
If *p* is ``NULL``, no operation is performed.
The following type-oriented macros are provided for convenience. Note that
*TYPE* refers to any C type.
.. c:macro:: PyMem_RawNew(TYPE, n)
Same as :c:func:`PyMem_RawMalloc`, but allocates ``(n * sizeof(TYPE))``
bytes of memory. Returns a pointer cast to ``TYPE*``. The memory will
not have been initialized in any way.
.. versionadded:: next
.. c:macro:: PyMem_RawResize(p, TYPE, n)
Same as :c:func:`PyMem_RawRealloc`, but the memory block is resized to
``(n * sizeof(TYPE))`` bytes. Returns a pointer cast to ``TYPE*``.
On return, *p* will be a pointer to the new memory area, or ``NULL`` in
the event of failure.
This is a C preprocessor macro; *p* is always reassigned. Save the original
value of *p* to avoid losing memory when handling errors.
.. versionadded:: next
.. _memoryinterface:
Memory Interface
Expand Down
2 changes: 2 additions & 0 deletions Doc/data/stable_abi.dat

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.

6 changes: 5 additions & 1 deletion Doc/whatsnew/3.14.rst
Original file line number Diff line number Diff line change
Expand Up @@ -907,13 +907,17 @@ New features
test if two strings are equal.
(Contributed by Victor Stinner in :gh:`124502`.)


* Add :c:func:`PyType_Freeze` function to make a type immutable.
(Contributed by Victor Stinner in :gh:`121654`.)

* Add :c:func:`PyUnstable_Object_EnableDeferredRefcount` for enabling
deferred reference counting, as outlined in :pep:`703`.

* Add the :c:macro:`PyMem_RawNew` and :c:macro:`PyMem_RawResize` convenience
macros to the limited C API.
(Contributed by Bénédikt Tran in :gh:`XXX`.)


Porting to Python 3.14
----------------------

Expand Down
34 changes: 23 additions & 11 deletions Include/pymem.h
Original file line number Diff line number Diff line change
Expand Up @@ -60,20 +60,21 @@ PyAPI_FUNC(void) PyMem_Free(void *ptr);
* overflow checking is always done.
*/

#define PyMem_New(type, n) \
( ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \
( (type *) PyMem_Malloc((n) * sizeof(type)) ) )
#define PyMem_New(TYPE, N) \
(((size_t)(N) <= PY_SSIZE_T_MAX / sizeof(TYPE)) \
? (TYPE *)PyMem_Malloc((N) * sizeof(TYPE)) \
: NULL)

/*
* The value of (p) is always clobbered by this macro regardless of success.
* The caller MUST check if (p) is NULL afterwards and deal with the memory
* error if so. This means the original value of (p) MUST be saved for the
* The value of (PTR) is always clobbered by this macro regardless of success.
* The caller MUST check if (PTR) is NULL afterwards and deal with the memory
* error if so. This means the original value of (PTR) MUST be saved for the
* caller's memory error handler to not lose track of it.
*/
#define PyMem_Resize(p, type, n) \
( (p) = ((size_t)(n) > PY_SSIZE_T_MAX / sizeof(type)) ? NULL : \
(type *) PyMem_Realloc((p), (n) * sizeof(type)) )

#define PyMem_Resize(PTR, TYPE, N) \
((PTR) = ((size_t)(N) <= PY_SSIZE_T_MAX / sizeof(TYPE)) \
? (TYPE *)PyMem_Realloc((PTR), (N) * sizeof(TYPE)) \
: NULL)

// Deprecated aliases only kept for backward compatibility.
// PyMem_Del and PyMem_DEL are defined with no parameter to be able to use
Expand All @@ -86,7 +87,6 @@ PyAPI_FUNC(void) PyMem_Free(void *ptr);
#define PyMem_Del(p) PyMem_Free((p))
#define PyMem_DEL(p) PyMem_Free((p))


#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030d0000
// Memory allocator which doesn't require the GIL to be held.
// Usually, it's just a thin wrapper to functions of the standard C library:
Expand All @@ -98,6 +98,18 @@ PyAPI_FUNC(void *) PyMem_RawRealloc(void *ptr, size_t new_size);
PyAPI_FUNC(void) PyMem_RawFree(void *ptr);
#endif

#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= 0x030e0000
#define PyMem_RawNew(TYPE, N) \
(((size_t)(N) <= PY_SSIZE_T_MAX / sizeof(TYPE)) \
? (TYPE *)PyMem_RawMalloc((N) * sizeof(TYPE)) \
: NULL)

#define PyMem_RawResize(PTR, TYPE, N) \
((PTR) = ((size_t)(N) <= PY_SSIZE_T_MAX / sizeof(TYPE)) \
? (TYPE *)PyMem_RawRealloc((PTR), (N) * sizeof(TYPE)) \
: NULL)
#endif

#ifndef Py_LIMITED_API
# define Py_CPYTHON_PYMEM_H
# include "cpython/pymem.h"
Expand Down
4 changes: 4 additions & 0 deletions Misc/stable_abi.toml
Original file line number Diff line number Diff line change
Expand Up @@ -2540,3 +2540,7 @@
added = '3.14'
[function.PyType_Freeze]
added = '3.14'
[macro.PyMem_RawNew]
added = '3.14'
[macro.PyMem_RawResize]
added = '3.14'

0 comments on commit 356196b

Please sign in to comment.