| 1 | #ifndef Py_CPYTHON_OBJIMPL_H |
| 2 | # error "this header file must not be included directly" |
| 3 | #endif |
| 4 | |
| 5 | static inline size_t _PyObject_SIZE(PyTypeObject *type) { |
| 6 | return _Py_STATIC_CAST(size_t, type->tp_basicsize); |
| 7 | } |
| 8 | |
| 9 | /* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a |
| 10 | vrbl-size object with nitems items, exclusive of gc overhead (if any). The |
| 11 | value is rounded up to the closest multiple of sizeof(void *), in order to |
| 12 | ensure that pointer fields at the end of the object are correctly aligned |
| 13 | for the platform (this is of special importance for subclasses of, e.g., |
| 14 | str or int, so that pointers can be stored after the embedded data). |
| 15 | |
| 16 | Note that there's no memory wastage in doing this, as malloc has to |
| 17 | return (at worst) pointer-aligned memory anyway. |
| 18 | */ |
| 19 | #if ((SIZEOF_VOID_P - 1) & SIZEOF_VOID_P) != 0 |
| 20 | # error "_PyObject_VAR_SIZE requires SIZEOF_VOID_P be a power of 2" |
| 21 | #endif |
| 22 | |
| 23 | static inline size_t _PyObject_VAR_SIZE(PyTypeObject *type, Py_ssize_t nitems) { |
| 24 | size_t size = _Py_STATIC_CAST(size_t, type->tp_basicsize); |
| 25 | size += _Py_STATIC_CAST(size_t, nitems) * _Py_STATIC_CAST(size_t, type->tp_itemsize); |
| 26 | return _Py_SIZE_ROUND_UP(size, SIZEOF_VOID_P); |
| 27 | } |
| 28 | |
| 29 | |
| 30 | /* This example code implements an object constructor with a custom |
| 31 | allocator, where PyObject_New is inlined, and shows the important |
| 32 | distinction between two steps (at least): |
| 33 | 1) the actual allocation of the object storage; |
| 34 | 2) the initialization of the Python specific fields |
| 35 | in this storage with PyObject_{Init, InitVar}. |
| 36 | |
| 37 | PyObject * |
| 38 | YourObject_New(...) |
| 39 | { |
| 40 | PyObject *op; |
| 41 | |
| 42 | op = (PyObject *) Your_Allocator(_PyObject_SIZE(YourTypeStruct)); |
| 43 | if (op == NULL) { |
| 44 | return PyErr_NoMemory(); |
| 45 | } |
| 46 | |
| 47 | PyObject_Init(op, &YourTypeStruct); |
| 48 | |
| 49 | op->ob_field = value; |
| 50 | ... |
| 51 | return op; |
| 52 | } |
| 53 | |
| 54 | Note that in C++, the use of the new operator usually implies that |
| 55 | the 1st step is performed automatically for you, so in a C++ class |
| 56 | constructor you would start directly with PyObject_Init/InitVar. */ |
| 57 | |
| 58 | |
| 59 | typedef struct { |
| 60 | /* user context passed as the first argument to the 2 functions */ |
| 61 | void *ctx; |
| 62 | |
| 63 | /* allocate an arena of size bytes */ |
| 64 | void* (*alloc) (void *ctx, size_t size); |
| 65 | |
| 66 | /* free an arena */ |
| 67 | void (*free) (void *ctx, void *ptr, size_t size); |
| 68 | } PyObjectArenaAllocator; |
| 69 | |
| 70 | /* Get the arena allocator. */ |
| 71 | PyAPI_FUNC(void) PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator); |
| 72 | |
| 73 | /* Set the arena allocator. */ |
| 74 | PyAPI_FUNC(void) PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator); |
| 75 | |
| 76 | |
| 77 | /* Test if an object implements the garbage collector protocol */ |
| 78 | PyAPI_FUNC(int) PyObject_IS_GC(PyObject *obj); |
| 79 | |
| 80 | |
| 81 | /* Code built with Py_BUILD_CORE must include pycore_gc.h instead which |
| 82 | defines a different _PyGC_FINALIZED() macro. */ |
| 83 | #ifndef Py_BUILD_CORE |
| 84 | // Kept for backward compatibility with Python 3.8 |
| 85 | # define _PyGC_FINALIZED(o) PyObject_GC_IsFinalized(o) |
| 86 | #endif |
| 87 | |
| 88 | |
| 89 | // Test if a type supports weak references |
| 90 | PyAPI_FUNC(int) PyType_SUPPORTS_WEAKREFS(PyTypeObject *type); |
| 91 | |
| 92 | PyAPI_FUNC(PyObject **) PyObject_GET_WEAKREFS_LISTPTR(PyObject *op); |
| 93 | |
| 94 | PyAPI_FUNC(PyObject *) (PyTypeObject *, |
| 95 | size_t); |
| 96 | |