File indexing completed on 2025-10-17 08:59:08
0001 #ifndef Py_INTERNAL_OBJECT_H
0002 #define Py_INTERNAL_OBJECT_H
0003 #ifdef __cplusplus
0004 extern "C" {
0005 #endif
0006
0007 #ifndef Py_BUILD_CORE
0008 # error "this header requires Py_BUILD_CORE define"
0009 #endif
0010
0011 #include <stdbool.h>
0012 #include "pycore_gc.h" // _PyObject_GC_IS_TRACKED()
0013 #include "pycore_interp.h" // PyInterpreterState.gc
0014 #include "pycore_pystate.h" // _PyInterpreterState_GET()
0015 #include "pycore_runtime.h" // _PyRuntime
0016
0017
0018
0019
0020
0021
0022
0023
0024
0025 #define _PyObject_HEAD_INIT(type) \
0026 { \
0027 _PyObject_EXTRA_INIT \
0028 .ob_refcnt = _Py_IMMORTAL_REFCNT, \
0029 .ob_type = (type) \
0030 },
0031 #define _PyVarObject_HEAD_INIT(type, size) \
0032 { \
0033 .ob_base = _PyObject_HEAD_INIT(type) \
0034 .ob_size = size \
0035 },
0036
0037 PyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalRefcountErrorFunc(
0038 const char *func,
0039 const char *message);
0040
0041 #define _Py_FatalRefcountError(message) \
0042 _Py_FatalRefcountErrorFunc(__func__, (message))
0043
0044
0045 #ifdef Py_REF_DEBUG
0046
0047
0048 PyAPI_DATA(Py_ssize_t) _Py_RefTotal;
0049
0050 extern void _Py_AddRefTotal(PyInterpreterState *, Py_ssize_t);
0051 extern void _Py_IncRefTotal(PyInterpreterState *);
0052 extern void _Py_DecRefTotal(PyInterpreterState *);
0053
0054 # define _Py_DEC_REFTOTAL(interp) \
0055 interp->object_state.reftotal--
0056 #endif
0057
0058
0059 static inline void _Py_RefcntAdd(PyObject* op, Py_ssize_t n)
0060 {
0061 if (_Py_IsImmortal(op)) {
0062 return;
0063 }
0064 #ifdef Py_REF_DEBUG
0065 _Py_AddRefTotal(_PyInterpreterState_GET(), n);
0066 #endif
0067 op->ob_refcnt += n;
0068
0069
0070
0071
0072 _Py_INCREF_STAT_INC();
0073 }
0074 #define _Py_RefcntAdd(op, n) _Py_RefcntAdd(_PyObject_CAST(op), n)
0075
0076 static inline void _Py_SetImmortal(PyObject *op)
0077 {
0078 #ifdef Py_DEBUG
0079
0080 if (PyUnicode_CheckExact(op)) {
0081 assert(PyUnicode_CHECK_INTERNED(op) == SSTATE_INTERNED_IMMORTAL
0082 || PyUnicode_CHECK_INTERNED(op) == SSTATE_INTERNED_IMMORTAL_STATIC);
0083 }
0084 #endif
0085 if (op) {
0086 op->ob_refcnt = _Py_IMMORTAL_REFCNT;
0087 }
0088 }
0089 #define _Py_SetImmortal(op) _Py_SetImmortal(_PyObject_CAST(op))
0090
0091
0092 static inline void _Py_ClearImmortal(PyObject *op)
0093 {
0094 if (op) {
0095 assert(_Py_IsImmortal(op));
0096 op->ob_refcnt = 1;
0097 Py_DECREF(op);
0098 }
0099 }
0100 #define _Py_ClearImmortal(op) \
0101 do { \
0102 _Py_ClearImmortal(_PyObject_CAST(op)); \
0103 op = NULL; \
0104 } while (0)
0105
0106 static inline void
0107 _Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct)
0108 {
0109 if (_Py_IsImmortal(op)) {
0110 return;
0111 }
0112 _Py_DECREF_STAT_INC();
0113 #ifdef Py_REF_DEBUG
0114 _Py_DEC_REFTOTAL(_PyInterpreterState_GET());
0115 #endif
0116 if (--op->ob_refcnt != 0) {
0117 assert(op->ob_refcnt > 0);
0118 }
0119 else {
0120 #ifdef Py_TRACE_REFS
0121 _Py_ForgetReference(op);
0122 #endif
0123 destruct(op);
0124 }
0125 }
0126
0127 static inline void
0128 _Py_DECREF_NO_DEALLOC(PyObject *op)
0129 {
0130 if (_Py_IsImmortal(op)) {
0131 return;
0132 }
0133 _Py_DECREF_STAT_INC();
0134 #ifdef Py_REF_DEBUG
0135 _Py_DEC_REFTOTAL(_PyInterpreterState_GET());
0136 #endif
0137 op->ob_refcnt--;
0138 #ifdef Py_DEBUG
0139 if (op->ob_refcnt <= 0) {
0140 _Py_FatalRefcountError("Expected a positive remaining refcount");
0141 }
0142 #endif
0143 }
0144
0145 #ifdef Py_REF_DEBUG
0146 # undef _Py_DEC_REFTOTAL
0147 #endif
0148
0149
0150 PyAPI_FUNC(int) _PyType_CheckConsistency(PyTypeObject *type);
0151 PyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content);
0152
0153
0154
0155
0156
0157 extern int _PyTraceMalloc_NewReference(PyObject *op);
0158
0159
0160 static inline int
0161 _PyType_HasFeature(PyTypeObject *type, unsigned long feature) {
0162 return ((type->tp_flags & feature) != 0);
0163 }
0164
0165 extern void _PyType_InitCache(PyInterpreterState *interp);
0166
0167 extern void _PyObject_InitState(PyInterpreterState *interp);
0168
0169
0170
0171
0172
0173
0174 static inline void
0175 _PyObject_Init(PyObject *op, PyTypeObject *typeobj)
0176 {
0177 assert(op != NULL);
0178 Py_SET_TYPE(op, typeobj);
0179 if (_PyType_HasFeature(typeobj, Py_TPFLAGS_HEAPTYPE)) {
0180 Py_INCREF(typeobj);
0181 }
0182 _Py_NewReference(op);
0183 }
0184
0185 static inline void
0186 _PyObject_InitVar(PyVarObject *op, PyTypeObject *typeobj, Py_ssize_t size)
0187 {
0188 assert(op != NULL);
0189 assert(typeobj != &PyLong_Type);
0190 _PyObject_Init((PyObject *)op, typeobj);
0191 Py_SET_SIZE(op, size);
0192 }
0193
0194
0195
0196
0197
0198
0199
0200
0201
0202
0203
0204
0205
0206
0207
0208 static inline void _PyObject_GC_TRACK(
0209
0210 #ifndef NDEBUG
0211 const char *filename, int lineno,
0212 #endif
0213 PyObject *op)
0214 {
0215 _PyObject_ASSERT_FROM(op, !_PyObject_GC_IS_TRACKED(op),
0216 "object already tracked by the garbage collector",
0217 filename, lineno, __func__);
0218
0219 PyGC_Head *gc = _Py_AS_GC(op);
0220 _PyObject_ASSERT_FROM(op,
0221 (gc->_gc_prev & _PyGC_PREV_MASK_COLLECTING) == 0,
0222 "object is in generation which is garbage collected",
0223 filename, lineno, __func__);
0224
0225 PyInterpreterState *interp = _PyInterpreterState_GET();
0226 PyGC_Head *generation0 = interp->gc.generation0;
0227 PyGC_Head *last = (PyGC_Head*)(generation0->_gc_prev);
0228 _PyGCHead_SET_NEXT(last, gc);
0229 _PyGCHead_SET_PREV(gc, last);
0230 _PyGCHead_SET_NEXT(gc, generation0);
0231 generation0->_gc_prev = (uintptr_t)gc;
0232 }
0233
0234
0235
0236
0237
0238
0239
0240
0241
0242
0243
0244 static inline void _PyObject_GC_UNTRACK(
0245
0246 #ifndef NDEBUG
0247 const char *filename, int lineno,
0248 #endif
0249 PyObject *op)
0250 {
0251 _PyObject_ASSERT_FROM(op, _PyObject_GC_IS_TRACKED(op),
0252 "object not tracked by the garbage collector",
0253 filename, lineno, __func__);
0254
0255 PyGC_Head *gc = _Py_AS_GC(op);
0256 PyGC_Head *prev = _PyGCHead_PREV(gc);
0257 PyGC_Head *next = _PyGCHead_NEXT(gc);
0258 _PyGCHead_SET_NEXT(prev, next);
0259 _PyGCHead_SET_PREV(next, prev);
0260 gc->_gc_next = 0;
0261 gc->_gc_prev &= _PyGC_PREV_MASK_FINALIZED;
0262 }
0263
0264
0265
0266
0267 #ifdef NDEBUG
0268 # define _PyObject_GC_TRACK(op) \
0269 _PyObject_GC_TRACK(_PyObject_CAST(op))
0270 # define _PyObject_GC_UNTRACK(op) \
0271 _PyObject_GC_UNTRACK(_PyObject_CAST(op))
0272 #else
0273 # define _PyObject_GC_TRACK(op) \
0274 _PyObject_GC_TRACK(__FILE__, __LINE__, _PyObject_CAST(op))
0275 # define _PyObject_GC_UNTRACK(op) \
0276 _PyObject_GC_UNTRACK(__FILE__, __LINE__, _PyObject_CAST(op))
0277 #endif
0278
0279 #ifdef Py_REF_DEBUG
0280 extern void _PyInterpreterState_FinalizeRefTotal(PyInterpreterState *);
0281 extern void _Py_FinalizeRefTotal(_PyRuntimeState *);
0282 extern void _PyDebug_PrintTotalRefs(void);
0283 #endif
0284
0285 #ifdef Py_TRACE_REFS
0286 extern void _Py_AddToAllObjects(PyObject *op, int force);
0287 extern void _Py_PrintReferences(PyInterpreterState *, FILE *);
0288 extern void _Py_PrintReferenceAddresses(PyInterpreterState *, FILE *);
0289 #endif
0290
0291
0292
0293
0294
0295
0296
0297
0298
0299
0300
0301 static inline PyObject **
0302 _PyObject_GET_WEAKREFS_LISTPTR(PyObject *op)
0303 {
0304 if (PyType_Check(op) &&
0305 ((PyTypeObject *)op)->tp_flags & _Py_TPFLAGS_STATIC_BUILTIN) {
0306 PyInterpreterState *interp = _PyInterpreterState_GET();
0307 static_builtin_state *state = _PyStaticType_GetState(
0308 interp, (PyTypeObject *)op);
0309 return _PyStaticType_GET_WEAKREFS_LISTPTR(state);
0310 }
0311
0312 Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset;
0313 return (PyObject **)((char *)op + offset);
0314 }
0315
0316
0317
0318
0319
0320
0321
0322
0323
0324
0325
0326
0327
0328 static inline PyWeakReference **
0329 _PyObject_GET_WEAKREFS_LISTPTR_FROM_OFFSET(PyObject *op)
0330 {
0331 assert(!PyType_Check(op) ||
0332 ((PyTypeObject *)op)->tp_flags & Py_TPFLAGS_HEAPTYPE);
0333 Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset;
0334 return (PyWeakReference **)((char *)op + offset);
0335 }
0336
0337
0338
0339 static inline int
0340 _PyObject_IS_GC(PyObject *obj)
0341 {
0342 return (PyType_IS_GC(Py_TYPE(obj))
0343 && (Py_TYPE(obj)->tp_is_gc == NULL
0344 || Py_TYPE(obj)->tp_is_gc(obj)));
0345 }
0346
0347
0348 #define _PyType_IS_GC(t) _PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC)
0349
0350 static inline size_t
0351 _PyType_PreHeaderSize(PyTypeObject *tp)
0352 {
0353 return _PyType_IS_GC(tp) * sizeof(PyGC_Head) +
0354 _PyType_HasFeature(tp, Py_TPFLAGS_PREHEADER) * 2 * sizeof(PyObject *);
0355 }
0356
0357 void _PyObject_GC_Link(PyObject *op);
0358
0359
0360 extern int _Py_CheckSlotResult(
0361 PyObject *obj,
0362 const char *slot_name,
0363 int success);
0364
0365
0366 static inline int _PyType_SUPPORTS_WEAKREFS(PyTypeObject *type) {
0367 return (type->tp_weaklistoffset != 0);
0368 }
0369
0370 extern PyObject* _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems);
0371
0372 extern int _PyObject_InitializeDict(PyObject *obj);
0373 extern int _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values,
0374 PyObject *name, PyObject *value);
0375 PyObject * _PyObject_GetInstanceAttribute(PyObject *obj, PyDictValues *values,
0376 PyObject *name);
0377
0378 typedef union {
0379 PyObject *dict;
0380
0381 char *values;
0382 } PyDictOrValues;
0383
0384 static inline PyDictOrValues *
0385 _PyObject_DictOrValuesPointer(PyObject *obj)
0386 {
0387 assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
0388 return ((PyDictOrValues *)obj)-3;
0389 }
0390
0391 static inline int
0392 _PyDictOrValues_IsValues(PyDictOrValues dorv)
0393 {
0394 return ((uintptr_t)dorv.values) & 1;
0395 }
0396
0397 static inline PyDictValues *
0398 _PyDictOrValues_GetValues(PyDictOrValues dorv)
0399 {
0400 assert(_PyDictOrValues_IsValues(dorv));
0401 return (PyDictValues *)(dorv.values + 1);
0402 }
0403
0404 static inline PyObject *
0405 _PyDictOrValues_GetDict(PyDictOrValues dorv)
0406 {
0407 assert(!_PyDictOrValues_IsValues(dorv));
0408 return dorv.dict;
0409 }
0410
0411 static inline void
0412 _PyDictOrValues_SetValues(PyDictOrValues *ptr, PyDictValues *values)
0413 {
0414 ptr->values = ((char *)values) - 1;
0415 }
0416
0417 #define MANAGED_WEAKREF_OFFSET (((Py_ssize_t)sizeof(PyObject *))*-4)
0418
0419 extern PyObject ** _PyObject_ComputedDictPointer(PyObject *);
0420 extern void _PyObject_FreeInstanceAttributes(PyObject *obj);
0421 extern int _PyObject_IsInstanceDictEmpty(PyObject *);
0422
0423 PyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, PyObject *);
0424
0425
0426
0427
0428
0429
0430
0431
0432
0433
0434
0435
0436
0437
0438
0439 #if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE)
0440 #define _PyCFunction_TrampolineCall(meth, self, args) \
0441 _PyCFunctionWithKeywords_TrampolineCall( \
0442 (*(PyCFunctionWithKeywords)(void(*)(void))(meth)), (self), (args), NULL)
0443 extern PyObject* _PyCFunctionWithKeywords_TrampolineCall(
0444 PyCFunctionWithKeywords meth, PyObject *, PyObject *, PyObject *);
0445 #else
0446 #define _PyCFunction_TrampolineCall(meth, self, args) \
0447 (meth)((self), (args))
0448 #define _PyCFunctionWithKeywords_TrampolineCall(meth, self, args, kw) \
0449 (meth)((self), (args), (kw))
0450 #endif
0451
0452 #ifdef __cplusplus
0453 }
0454 #endif
0455 #endif