17db96d56Sopenharmony_ci#ifndef Py_CPYTHON_OBJIMPL_H 27db96d56Sopenharmony_ci# error "this header file must not be included directly" 37db96d56Sopenharmony_ci#endif 47db96d56Sopenharmony_ci 57db96d56Sopenharmony_ci#define _PyObject_SIZE(typeobj) ( (typeobj)->tp_basicsize ) 67db96d56Sopenharmony_ci 77db96d56Sopenharmony_ci/* _PyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a 87db96d56Sopenharmony_ci vrbl-size object with nitems items, exclusive of gc overhead (if any). The 97db96d56Sopenharmony_ci value is rounded up to the closest multiple of sizeof(void *), in order to 107db96d56Sopenharmony_ci ensure that pointer fields at the end of the object are correctly aligned 117db96d56Sopenharmony_ci for the platform (this is of special importance for subclasses of, e.g., 127db96d56Sopenharmony_ci str or int, so that pointers can be stored after the embedded data). 137db96d56Sopenharmony_ci 147db96d56Sopenharmony_ci Note that there's no memory wastage in doing this, as malloc has to 157db96d56Sopenharmony_ci return (at worst) pointer-aligned memory anyway. 167db96d56Sopenharmony_ci*/ 177db96d56Sopenharmony_ci#if ((SIZEOF_VOID_P - 1) & SIZEOF_VOID_P) != 0 187db96d56Sopenharmony_ci# error "_PyObject_VAR_SIZE requires SIZEOF_VOID_P be a power of 2" 197db96d56Sopenharmony_ci#endif 207db96d56Sopenharmony_ci 217db96d56Sopenharmony_ci#define _PyObject_VAR_SIZE(typeobj, nitems) \ 227db96d56Sopenharmony_ci _Py_SIZE_ROUND_UP((typeobj)->tp_basicsize + \ 237db96d56Sopenharmony_ci (nitems)*(typeobj)->tp_itemsize, \ 247db96d56Sopenharmony_ci SIZEOF_VOID_P) 257db96d56Sopenharmony_ci 267db96d56Sopenharmony_ci 277db96d56Sopenharmony_ci/* This example code implements an object constructor with a custom 287db96d56Sopenharmony_ci allocator, where PyObject_New is inlined, and shows the important 297db96d56Sopenharmony_ci distinction between two steps (at least): 307db96d56Sopenharmony_ci 1) the actual allocation of the object storage; 317db96d56Sopenharmony_ci 2) the initialization of the Python specific fields 327db96d56Sopenharmony_ci in this storage with PyObject_{Init, InitVar}. 337db96d56Sopenharmony_ci 347db96d56Sopenharmony_ci PyObject * 357db96d56Sopenharmony_ci YourObject_New(...) 367db96d56Sopenharmony_ci { 377db96d56Sopenharmony_ci PyObject *op; 387db96d56Sopenharmony_ci 397db96d56Sopenharmony_ci op = (PyObject *) Your_Allocator(_PyObject_SIZE(YourTypeStruct)); 407db96d56Sopenharmony_ci if (op == NULL) { 417db96d56Sopenharmony_ci return PyErr_NoMemory(); 427db96d56Sopenharmony_ci } 437db96d56Sopenharmony_ci 447db96d56Sopenharmony_ci PyObject_Init(op, &YourTypeStruct); 457db96d56Sopenharmony_ci 467db96d56Sopenharmony_ci op->ob_field = value; 477db96d56Sopenharmony_ci ... 487db96d56Sopenharmony_ci return op; 497db96d56Sopenharmony_ci } 507db96d56Sopenharmony_ci 517db96d56Sopenharmony_ci Note that in C++, the use of the new operator usually implies that 527db96d56Sopenharmony_ci the 1st step is performed automatically for you, so in a C++ class 537db96d56Sopenharmony_ci constructor you would start directly with PyObject_Init/InitVar. */ 547db96d56Sopenharmony_ci 557db96d56Sopenharmony_ci 567db96d56Sopenharmony_citypedef struct { 577db96d56Sopenharmony_ci /* user context passed as the first argument to the 2 functions */ 587db96d56Sopenharmony_ci void *ctx; 597db96d56Sopenharmony_ci 607db96d56Sopenharmony_ci /* allocate an arena of size bytes */ 617db96d56Sopenharmony_ci void* (*alloc) (void *ctx, size_t size); 627db96d56Sopenharmony_ci 637db96d56Sopenharmony_ci /* free an arena */ 647db96d56Sopenharmony_ci void (*free) (void *ctx, void *ptr, size_t size); 657db96d56Sopenharmony_ci} PyObjectArenaAllocator; 667db96d56Sopenharmony_ci 677db96d56Sopenharmony_ci/* Get the arena allocator. */ 687db96d56Sopenharmony_ciPyAPI_FUNC(void) PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator); 697db96d56Sopenharmony_ci 707db96d56Sopenharmony_ci/* Set the arena allocator. */ 717db96d56Sopenharmony_ciPyAPI_FUNC(void) PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator); 727db96d56Sopenharmony_ci 737db96d56Sopenharmony_ci 747db96d56Sopenharmony_ci/* Test if an object implements the garbage collector protocol */ 757db96d56Sopenharmony_ciPyAPI_FUNC(int) PyObject_IS_GC(PyObject *obj); 767db96d56Sopenharmony_ci 777db96d56Sopenharmony_ci 787db96d56Sopenharmony_ci/* Code built with Py_BUILD_CORE must include pycore_gc.h instead which 797db96d56Sopenharmony_ci defines a different _PyGC_FINALIZED() macro. */ 807db96d56Sopenharmony_ci#ifndef Py_BUILD_CORE 817db96d56Sopenharmony_ci // Kept for backward compatibility with Python 3.8 827db96d56Sopenharmony_ci# define _PyGC_FINALIZED(o) PyObject_GC_IsFinalized(o) 837db96d56Sopenharmony_ci#endif 847db96d56Sopenharmony_ci 857db96d56Sopenharmony_ci 867db96d56Sopenharmony_ci// Test if a type supports weak references 877db96d56Sopenharmony_ciPyAPI_FUNC(int) PyType_SUPPORTS_WEAKREFS(PyTypeObject *type); 887db96d56Sopenharmony_ci 897db96d56Sopenharmony_ciPyAPI_FUNC(PyObject **) PyObject_GET_WEAKREFS_LISTPTR(PyObject *op); 90