mirror of
https://github.com/johndoe6345789/typthon.git
synced 2026-04-25 14:15:29 +00:00
Massive automated renaming of all Py_/PyObject/etc. prefixes to Ty_/TyObject/etc. This includes: - All public API types (TyObject, TyTypeObject, etc.) - All public API functions (Ty_Initialize, Ty_BuildValue, etc.) - All internal API (_Ty_ prefixes) - Reference counting macros (Ty_INCREF, Ty_DECREF, etc.) - Type flags (Ty_TPFLAGS_*) - Debug flags (Ty_DEBUG, Ty_TRACE_REFS, etc.) - All object type APIs (TyList_, TyDict_, TyUnicode_, etc.) This changes over 60,000 occurrences across 1000+ files. Co-authored-by: johndoe6345789 <224850594+johndoe6345789@users.noreply.github.com>
105 lines
3.7 KiB
C
105 lines
3.7 KiB
C
#ifndef Ty_CPYTHON_OBJIMPL_H
|
|
# error "this header file must not be included directly"
|
|
#endif
|
|
|
|
static inline size_t _TyObject_SIZE(TyTypeObject *type) {
|
|
return _Ty_STATIC_CAST(size_t, type->tp_basicsize);
|
|
}
|
|
|
|
/* _TyObject_VAR_SIZE returns the number of bytes (as size_t) allocated for a
|
|
vrbl-size object with nitems items, exclusive of gc overhead (if any). The
|
|
value is rounded up to the closest multiple of sizeof(void *), in order to
|
|
ensure that pointer fields at the end of the object are correctly aligned
|
|
for the platform (this is of special importance for subclasses of, e.g.,
|
|
str or int, so that pointers can be stored after the embedded data).
|
|
|
|
Note that there's no memory wastage in doing this, as malloc has to
|
|
return (at worst) pointer-aligned memory anyway.
|
|
*/
|
|
#if ((SIZEOF_VOID_P - 1) & SIZEOF_VOID_P) != 0
|
|
# error "_TyObject_VAR_SIZE requires SIZEOF_VOID_P be a power of 2"
|
|
#endif
|
|
|
|
static inline size_t _TyObject_VAR_SIZE(TyTypeObject *type, Ty_ssize_t nitems) {
|
|
size_t size = _Ty_STATIC_CAST(size_t, type->tp_basicsize);
|
|
size += _Ty_STATIC_CAST(size_t, nitems) * _Ty_STATIC_CAST(size_t, type->tp_itemsize);
|
|
return _Ty_SIZE_ROUND_UP(size, SIZEOF_VOID_P);
|
|
}
|
|
|
|
|
|
/* This example code implements an object constructor with a custom
|
|
allocator, where PyObject_New is inlined, and shows the important
|
|
distinction between two steps (at least):
|
|
1) the actual allocation of the object storage;
|
|
2) the initialization of the Python specific fields
|
|
in this storage with PyObject_{Init, InitVar}.
|
|
|
|
TyObject *
|
|
YourObject_New(...)
|
|
{
|
|
TyObject *op;
|
|
|
|
op = (TyObject *) Your_Allocator(_TyObject_SIZE(YourTypeStruct));
|
|
if (op == NULL) {
|
|
return TyErr_NoMemory();
|
|
}
|
|
|
|
PyObject_Init(op, &YourTypeStruct);
|
|
|
|
op->ob_field = value;
|
|
...
|
|
return op;
|
|
}
|
|
|
|
Note that in C++, the use of the new operator usually implies that
|
|
the 1st step is performed automatically for you, so in a C++ class
|
|
constructor you would start directly with PyObject_Init/InitVar. */
|
|
|
|
|
|
typedef struct {
|
|
/* user context passed as the first argument to the 2 functions */
|
|
void *ctx;
|
|
|
|
/* allocate an arena of size bytes */
|
|
void* (*alloc) (void *ctx, size_t size);
|
|
|
|
/* free an arena */
|
|
void (*free) (void *ctx, void *ptr, size_t size);
|
|
} PyObjectArenaAllocator;
|
|
|
|
/* Get the arena allocator. */
|
|
PyAPI_FUNC(void) PyObject_GetArenaAllocator(PyObjectArenaAllocator *allocator);
|
|
|
|
/* Set the arena allocator. */
|
|
PyAPI_FUNC(void) PyObject_SetArenaAllocator(PyObjectArenaAllocator *allocator);
|
|
|
|
|
|
/* Test if an object implements the garbage collector protocol */
|
|
PyAPI_FUNC(int) PyObject_IS_GC(TyObject *obj);
|
|
|
|
|
|
// Test if a type supports weak references
|
|
PyAPI_FUNC(int) TyType_SUPPORTS_WEAKREFS(TyTypeObject *type);
|
|
|
|
PyAPI_FUNC(TyObject **) PyObject_GET_WEAKREFS_LISTPTR(TyObject *op);
|
|
|
|
PyAPI_FUNC(TyObject *) PyUnstable_Object_GC_NewWithExtraData(TyTypeObject *,
|
|
size_t);
|
|
|
|
|
|
/* Visit all live GC-capable objects, similar to gc.get_objects(None). The
|
|
* supplied callback is called on every such object with the void* arg set
|
|
* to the supplied arg. Returning 0 from the callback ends iteration, returning
|
|
* 1 allows iteration to continue. Returning any other value may result in
|
|
* undefined behaviour.
|
|
*
|
|
* If new objects are (de)allocated by the callback it is undefined if they
|
|
* will be visited.
|
|
|
|
* Garbage collection is disabled during operation. Explicitly running a
|
|
* collection in the callback may lead to undefined behaviour e.g. visiting the
|
|
* same objects multiple times or not at all.
|
|
*/
|
|
typedef int (*gcvisitobjects_t)(TyObject*, void*);
|
|
PyAPI_FUNC(void) PyUnstable_GC_VisitObjects(gcvisitobjects_t callback, void* arg);
|