1 #ifndef Py_CPYTHON_OBJIMPL_H
2 #  error "this header file must not be included directly"
3 #endif
4 
5 #ifdef __cplusplus
6 extern "C" {
7 #endif
8 
9 #define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize )
10 
11 /* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a
12    vrbl-size object with nitems items, exclusive of gc overhead (if any).  The
13    value is rounded up to the closest multiple of sizeof(void *), in order to
14    ensure that pointer fields at the end of the object are correctly aligned
15    for the platform (this is of special importance for subclasses of, e.g.,
16    str or int, so that pointers can be stored after the embedded data).
17 
18    Note that there's no memory wastage in doing this, as malloc has to
19    return (at worst) pointer-aligned memory anyway.
20 */
21 #if ((SIZEOF_VOID_P - 1) & SIZEOF_VOID_P) != 0
22 #   error "_PyObject_VAR_SIZE requires SIZEOF_VOID_P be a power of 2"
23 #endif
24 
25 #define _PyObject_VAR_SIZE(typeobj, nitems)     \
26     _Py_SIZE_ROUND_UP((typeobj)->tp_basicsize + \
27         (nitems)*(typeobj)->tp_itemsize,        \
28         SIZEOF_VOID_P)
29 
30 
31 /* This example code implements an object constructor with a custom
32    allocator, where PyObject_New is inlined, and shows the important
33    distinction between two steps (at least):
34        1) the actual allocation of the object storage;
35        2) the initialization of the Python specific fields
36       in this storage with PyObject_{Init, InitVar}.
37 
38    PyObject *
39    YourObject_New(...)
40    {
41        PyObject *op;
42 
43        op = (PyObject *) Your_Allocator(_PyObject_SIZE(YourTypeStruct));
44        if (op == NULL)
45        return PyErr_NoMemory();
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 /* Inline functions trading binary compatibility for speed:
60    PyObject_INIT() is the fast version of PyObject_Init(), and
61    PyObject_INIT_VAR() is the fast version of PyObject_InitVar().
62 
63    These inline functions must not be called with op=NULL. */
64 static inline PyObject*
_PyObject_INIT(PyObject * op,PyTypeObject * typeobj)65 _PyObject_INIT(PyObject *op, PyTypeObject *typeobj)
66 {
67     assert(op != NULL);
68     Py_SET_TYPE(op, typeobj);
69     if (PyType_GetFlags(typeobj) & Py_TPFLAGS_HEAPTYPE) {
70         Py_INCREF(typeobj);
71     }
72     _Py_NewReference(op);
73     return op;
74 }
75 
76 #define PyObject_INIT(op, typeobj) \
77     _PyObject_INIT(_PyObject_CAST(op), (typeobj))
78 
79 static inline PyVarObject*
_PyObject_INIT_VAR(PyVarObject * op,PyTypeObject * typeobj,Py_ssize_t size)80 _PyObject_INIT_VAR(PyVarObject *op, PyTypeObject *typeobj, Py_ssize_t size)
81 {
82     assert(op != NULL);
83     Py_SET_SIZE(op, size);
84     PyObject_INIT((PyObject *)op, typeobj);
85     return op;
86 }
87 
88 #define PyObject_INIT_VAR(op, typeobj, size) \
89     _PyObject_INIT_VAR(_PyVarObject_CAST(op), (typeobj), (size))
90 
91 
92 /* This function returns the number of allocated memory blocks, regardless of size */
93 PyAPI_FUNC(Py_ssize_t) _Py_GetAllocatedBlocks(void);
94 
95 /* Macros */
96 #ifdef WITH_PYMALLOC
97 PyAPI_FUNC(int) _PyObject_DebugMallocStats(FILE *out);
98 #endif
99 
100 
101 typedef struct {
102     /* user context passed as the first argument to the 2 functions */
103     void *ctx;
104 
105     /* allocate an arena of size bytes */
106     void* (*alloc) (void *ctx, size_t size);
107 
108     /* free an arena */
109     void (*free) (void *ctx, void *ptr, size_t size);
110 } PyObjectArenaAllocator;
111 
112 /* Get the arena allocator. */
113 PyAPI_FUNC(void) PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator);
114 
115 /* Set the arena allocator. */
116 PyAPI_FUNC(void) PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator);
117 
118 
119 PyAPI_FUNC(Py_ssize_t) _PyGC_CollectNoFail(void);
120 PyAPI_FUNC(Py_ssize_t) _PyGC_CollectIfEnabled(void);
121 
122 
123 /* Test if an object implements the garbage collector protocol */
124 PyAPI_FUNC(int) PyObject_IS_GC(PyObject *obj);
125 
126 
127 /* Code built with Py_BUILD_CORE must include pycore_gc.h instead which
128    defines a different _PyGC_FINALIZED() macro. */
129 #ifndef Py_BUILD_CORE
130    // Kept for backward compatibility with Python 3.8
131 #  define _PyGC_FINALIZED(o) PyObject_GC_IsFinalized(o)
132 #endif
133 
134 PyAPI_FUNC(PyObject *) _PyObject_GC_Malloc(size_t size);
135 PyAPI_FUNC(PyObject *) _PyObject_GC_Calloc(size_t size);
136 
137 
138 /* Test if a type supports weak references */
139 #define PyType_SUPPORTS_WEAKREFS(t) ((t)->tp_weaklistoffset > 0)
140 
141 PyAPI_FUNC(PyObject **) PyObject_GET_WEAKREFS_LISTPTR(PyObject *op);
142 
143 #ifdef __cplusplus
144 }
145 #endif
146