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