17db96d56Sopenharmony_ci#ifndef Py_INTERNAL_OBJECT_H
27db96d56Sopenharmony_ci#define Py_INTERNAL_OBJECT_H
37db96d56Sopenharmony_ci#ifdef __cplusplus
47db96d56Sopenharmony_ciextern "C" {
57db96d56Sopenharmony_ci#endif
67db96d56Sopenharmony_ci
77db96d56Sopenharmony_ci#ifndef Py_BUILD_CORE
87db96d56Sopenharmony_ci#  error "this header requires Py_BUILD_CORE define"
97db96d56Sopenharmony_ci#endif
107db96d56Sopenharmony_ci
117db96d56Sopenharmony_ci#include <stdbool.h>
127db96d56Sopenharmony_ci#include "pycore_gc.h"            // _PyObject_GC_IS_TRACKED()
137db96d56Sopenharmony_ci#include "pycore_interp.h"        // PyInterpreterState.gc
147db96d56Sopenharmony_ci#include "pycore_pystate.h"       // _PyInterpreterState_GET()
157db96d56Sopenharmony_ci#include "pycore_runtime.h"       // _PyRuntime
167db96d56Sopenharmony_ci
177db96d56Sopenharmony_ci#define _PyObject_IMMORTAL_INIT(type) \
187db96d56Sopenharmony_ci    { \
197db96d56Sopenharmony_ci        .ob_refcnt = 999999999, \
207db96d56Sopenharmony_ci        .ob_type = type, \
217db96d56Sopenharmony_ci    }
227db96d56Sopenharmony_ci#define _PyVarObject_IMMORTAL_INIT(type, size) \
237db96d56Sopenharmony_ci    { \
247db96d56Sopenharmony_ci        .ob_base = _PyObject_IMMORTAL_INIT(type), \
257db96d56Sopenharmony_ci        .ob_size = size, \
267db96d56Sopenharmony_ci    }
277db96d56Sopenharmony_ci
287db96d56Sopenharmony_ciPyAPI_FUNC(void) _Py_NO_RETURN _Py_FatalRefcountErrorFunc(
297db96d56Sopenharmony_ci    const char *func,
307db96d56Sopenharmony_ci    const char *message);
317db96d56Sopenharmony_ci
327db96d56Sopenharmony_ci#define _Py_FatalRefcountError(message) _Py_FatalRefcountErrorFunc(__func__, message)
337db96d56Sopenharmony_ci
347db96d56Sopenharmony_cistatic inline void
357db96d56Sopenharmony_ci_Py_DECREF_SPECIALIZED(PyObject *op, const destructor destruct)
367db96d56Sopenharmony_ci{
377db96d56Sopenharmony_ci#ifdef Py_REF_DEBUG
387db96d56Sopenharmony_ci    _Py_RefTotal--;
397db96d56Sopenharmony_ci#endif
407db96d56Sopenharmony_ci    if (--op->ob_refcnt != 0) {
417db96d56Sopenharmony_ci        assert(op->ob_refcnt > 0);
427db96d56Sopenharmony_ci    }
437db96d56Sopenharmony_ci    else {
447db96d56Sopenharmony_ci#ifdef Py_TRACE_REFS
457db96d56Sopenharmony_ci        _Py_ForgetReference(op);
467db96d56Sopenharmony_ci#endif
477db96d56Sopenharmony_ci        destruct(op);
487db96d56Sopenharmony_ci    }
497db96d56Sopenharmony_ci}
507db96d56Sopenharmony_ci
517db96d56Sopenharmony_cistatic inline void
527db96d56Sopenharmony_ci_Py_DECREF_NO_DEALLOC(PyObject *op)
537db96d56Sopenharmony_ci{
547db96d56Sopenharmony_ci#ifdef Py_REF_DEBUG
557db96d56Sopenharmony_ci    _Py_RefTotal--;
567db96d56Sopenharmony_ci#endif
577db96d56Sopenharmony_ci    op->ob_refcnt--;
587db96d56Sopenharmony_ci#ifdef Py_DEBUG
597db96d56Sopenharmony_ci    if (op->ob_refcnt <= 0) {
607db96d56Sopenharmony_ci        _Py_FatalRefcountError("Expected a positive remaining refcount");
617db96d56Sopenharmony_ci    }
627db96d56Sopenharmony_ci#endif
637db96d56Sopenharmony_ci}
647db96d56Sopenharmony_ci
657db96d56Sopenharmony_ciPyAPI_FUNC(int) _PyType_CheckConsistency(PyTypeObject *type);
667db96d56Sopenharmony_ciPyAPI_FUNC(int) _PyDict_CheckConsistency(PyObject *mp, int check_content);
677db96d56Sopenharmony_ci
687db96d56Sopenharmony_ci/* Update the Python traceback of an object. This function must be called
697db96d56Sopenharmony_ci   when a memory block is reused from a free list.
707db96d56Sopenharmony_ci
717db96d56Sopenharmony_ci   Internal function called by _Py_NewReference(). */
727db96d56Sopenharmony_ciextern int _PyTraceMalloc_NewReference(PyObject *op);
737db96d56Sopenharmony_ci
747db96d56Sopenharmony_ci// Fast inlined version of PyType_HasFeature()
757db96d56Sopenharmony_cistatic inline int
767db96d56Sopenharmony_ci_PyType_HasFeature(PyTypeObject *type, unsigned long feature) {
777db96d56Sopenharmony_ci    return ((type->tp_flags & feature) != 0);
787db96d56Sopenharmony_ci}
797db96d56Sopenharmony_ci
807db96d56Sopenharmony_ciextern void _PyType_InitCache(PyInterpreterState *interp);
817db96d56Sopenharmony_ci
827db96d56Sopenharmony_ci
837db96d56Sopenharmony_ci/* Inline functions trading binary compatibility for speed:
847db96d56Sopenharmony_ci   _PyObject_Init() is the fast version of PyObject_Init(), and
857db96d56Sopenharmony_ci   _PyObject_InitVar() is the fast version of PyObject_InitVar().
867db96d56Sopenharmony_ci
877db96d56Sopenharmony_ci   These inline functions must not be called with op=NULL. */
887db96d56Sopenharmony_cistatic inline void
897db96d56Sopenharmony_ci_PyObject_Init(PyObject *op, PyTypeObject *typeobj)
907db96d56Sopenharmony_ci{
917db96d56Sopenharmony_ci    assert(op != NULL);
927db96d56Sopenharmony_ci    Py_SET_TYPE(op, typeobj);
937db96d56Sopenharmony_ci    if (_PyType_HasFeature(typeobj, Py_TPFLAGS_HEAPTYPE)) {
947db96d56Sopenharmony_ci        Py_INCREF(typeobj);
957db96d56Sopenharmony_ci    }
967db96d56Sopenharmony_ci    _Py_NewReference(op);
977db96d56Sopenharmony_ci}
987db96d56Sopenharmony_ci
997db96d56Sopenharmony_cistatic inline void
1007db96d56Sopenharmony_ci_PyObject_InitVar(PyVarObject *op, PyTypeObject *typeobj, Py_ssize_t size)
1017db96d56Sopenharmony_ci{
1027db96d56Sopenharmony_ci    assert(op != NULL);
1037db96d56Sopenharmony_ci    Py_SET_SIZE(op, size);
1047db96d56Sopenharmony_ci    _PyObject_Init((PyObject *)op, typeobj);
1057db96d56Sopenharmony_ci}
1067db96d56Sopenharmony_ci
1077db96d56Sopenharmony_ci
1087db96d56Sopenharmony_ci/* Tell the GC to track this object.
1097db96d56Sopenharmony_ci *
1107db96d56Sopenharmony_ci * The object must not be tracked by the GC.
1117db96d56Sopenharmony_ci *
1127db96d56Sopenharmony_ci * NB: While the object is tracked by the collector, it must be safe to call the
1137db96d56Sopenharmony_ci * ob_traverse method.
1147db96d56Sopenharmony_ci *
1157db96d56Sopenharmony_ci * Internal note: interp->gc.generation0->_gc_prev doesn't have any bit flags
1167db96d56Sopenharmony_ci * because it's not object header.  So we don't use _PyGCHead_PREV() and
1177db96d56Sopenharmony_ci * _PyGCHead_SET_PREV() for it to avoid unnecessary bitwise operations.
1187db96d56Sopenharmony_ci *
1197db96d56Sopenharmony_ci * See also the public PyObject_GC_Track() function.
1207db96d56Sopenharmony_ci */
1217db96d56Sopenharmony_cistatic inline void _PyObject_GC_TRACK(
1227db96d56Sopenharmony_ci// The preprocessor removes _PyObject_ASSERT_FROM() calls if NDEBUG is defined
1237db96d56Sopenharmony_ci#ifndef NDEBUG
1247db96d56Sopenharmony_ci    const char *filename, int lineno,
1257db96d56Sopenharmony_ci#endif
1267db96d56Sopenharmony_ci    PyObject *op)
1277db96d56Sopenharmony_ci{
1287db96d56Sopenharmony_ci    _PyObject_ASSERT_FROM(op, !_PyObject_GC_IS_TRACKED(op),
1297db96d56Sopenharmony_ci                          "object already tracked by the garbage collector",
1307db96d56Sopenharmony_ci                          filename, lineno, __func__);
1317db96d56Sopenharmony_ci
1327db96d56Sopenharmony_ci    PyGC_Head *gc = _Py_AS_GC(op);
1337db96d56Sopenharmony_ci    _PyObject_ASSERT_FROM(op,
1347db96d56Sopenharmony_ci                          (gc->_gc_prev & _PyGC_PREV_MASK_COLLECTING) == 0,
1357db96d56Sopenharmony_ci                          "object is in generation which is garbage collected",
1367db96d56Sopenharmony_ci                          filename, lineno, __func__);
1377db96d56Sopenharmony_ci
1387db96d56Sopenharmony_ci    PyInterpreterState *interp = _PyInterpreterState_GET();
1397db96d56Sopenharmony_ci    PyGC_Head *generation0 = interp->gc.generation0;
1407db96d56Sopenharmony_ci    PyGC_Head *last = (PyGC_Head*)(generation0->_gc_prev);
1417db96d56Sopenharmony_ci    _PyGCHead_SET_NEXT(last, gc);
1427db96d56Sopenharmony_ci    _PyGCHead_SET_PREV(gc, last);
1437db96d56Sopenharmony_ci    _PyGCHead_SET_NEXT(gc, generation0);
1447db96d56Sopenharmony_ci    generation0->_gc_prev = (uintptr_t)gc;
1457db96d56Sopenharmony_ci}
1467db96d56Sopenharmony_ci
1477db96d56Sopenharmony_ci/* Tell the GC to stop tracking this object.
1487db96d56Sopenharmony_ci *
1497db96d56Sopenharmony_ci * Internal note: This may be called while GC. So _PyGC_PREV_MASK_COLLECTING
1507db96d56Sopenharmony_ci * must be cleared. But _PyGC_PREV_MASK_FINALIZED bit is kept.
1517db96d56Sopenharmony_ci *
1527db96d56Sopenharmony_ci * The object must be tracked by the GC.
1537db96d56Sopenharmony_ci *
1547db96d56Sopenharmony_ci * See also the public PyObject_GC_UnTrack() which accept an object which is
1557db96d56Sopenharmony_ci * not tracked.
1567db96d56Sopenharmony_ci */
1577db96d56Sopenharmony_cistatic inline void _PyObject_GC_UNTRACK(
1587db96d56Sopenharmony_ci// The preprocessor removes _PyObject_ASSERT_FROM() calls if NDEBUG is defined
1597db96d56Sopenharmony_ci#ifndef NDEBUG
1607db96d56Sopenharmony_ci    const char *filename, int lineno,
1617db96d56Sopenharmony_ci#endif
1627db96d56Sopenharmony_ci    PyObject *op)
1637db96d56Sopenharmony_ci{
1647db96d56Sopenharmony_ci    _PyObject_ASSERT_FROM(op, _PyObject_GC_IS_TRACKED(op),
1657db96d56Sopenharmony_ci                          "object not tracked by the garbage collector",
1667db96d56Sopenharmony_ci                          filename, lineno, __func__);
1677db96d56Sopenharmony_ci
1687db96d56Sopenharmony_ci    PyGC_Head *gc = _Py_AS_GC(op);
1697db96d56Sopenharmony_ci    PyGC_Head *prev = _PyGCHead_PREV(gc);
1707db96d56Sopenharmony_ci    PyGC_Head *next = _PyGCHead_NEXT(gc);
1717db96d56Sopenharmony_ci    _PyGCHead_SET_NEXT(prev, next);
1727db96d56Sopenharmony_ci    _PyGCHead_SET_PREV(next, prev);
1737db96d56Sopenharmony_ci    gc->_gc_next = 0;
1747db96d56Sopenharmony_ci    gc->_gc_prev &= _PyGC_PREV_MASK_FINALIZED;
1757db96d56Sopenharmony_ci}
1767db96d56Sopenharmony_ci
1777db96d56Sopenharmony_ci// Macros to accept any type for the parameter, and to automatically pass
1787db96d56Sopenharmony_ci// the filename and the filename (if NDEBUG is not defined) where the macro
1797db96d56Sopenharmony_ci// is called.
1807db96d56Sopenharmony_ci#ifdef NDEBUG
1817db96d56Sopenharmony_ci#  define _PyObject_GC_TRACK(op) \
1827db96d56Sopenharmony_ci        _PyObject_GC_TRACK(_PyObject_CAST(op))
1837db96d56Sopenharmony_ci#  define _PyObject_GC_UNTRACK(op) \
1847db96d56Sopenharmony_ci        _PyObject_GC_UNTRACK(_PyObject_CAST(op))
1857db96d56Sopenharmony_ci#else
1867db96d56Sopenharmony_ci#  define _PyObject_GC_TRACK(op) \
1877db96d56Sopenharmony_ci        _PyObject_GC_TRACK(__FILE__, __LINE__, _PyObject_CAST(op))
1887db96d56Sopenharmony_ci#  define _PyObject_GC_UNTRACK(op) \
1897db96d56Sopenharmony_ci        _PyObject_GC_UNTRACK(__FILE__, __LINE__, _PyObject_CAST(op))
1907db96d56Sopenharmony_ci#endif
1917db96d56Sopenharmony_ci
1927db96d56Sopenharmony_ci#ifdef Py_REF_DEBUG
1937db96d56Sopenharmony_ciextern void _PyDebug_PrintTotalRefs(void);
1947db96d56Sopenharmony_ci#endif
1957db96d56Sopenharmony_ci
1967db96d56Sopenharmony_ci#ifdef Py_TRACE_REFS
1977db96d56Sopenharmony_ciextern void _Py_AddToAllObjects(PyObject *op, int force);
1987db96d56Sopenharmony_ciextern void _Py_PrintReferences(FILE *);
1997db96d56Sopenharmony_ciextern void _Py_PrintReferenceAddresses(FILE *);
2007db96d56Sopenharmony_ci#endif
2017db96d56Sopenharmony_ci
2027db96d56Sopenharmony_cistatic inline PyObject **
2037db96d56Sopenharmony_ci_PyObject_GET_WEAKREFS_LISTPTR(PyObject *op)
2047db96d56Sopenharmony_ci{
2057db96d56Sopenharmony_ci    Py_ssize_t offset = Py_TYPE(op)->tp_weaklistoffset;
2067db96d56Sopenharmony_ci    return (PyObject **)((char *)op + offset);
2077db96d56Sopenharmony_ci}
2087db96d56Sopenharmony_ci
2097db96d56Sopenharmony_ci// Fast inlined version of PyObject_IS_GC()
2107db96d56Sopenharmony_cistatic inline int
2117db96d56Sopenharmony_ci_PyObject_IS_GC(PyObject *obj)
2127db96d56Sopenharmony_ci{
2137db96d56Sopenharmony_ci    return (PyType_IS_GC(Py_TYPE(obj))
2147db96d56Sopenharmony_ci            && (Py_TYPE(obj)->tp_is_gc == NULL
2157db96d56Sopenharmony_ci                || Py_TYPE(obj)->tp_is_gc(obj)));
2167db96d56Sopenharmony_ci}
2177db96d56Sopenharmony_ci
2187db96d56Sopenharmony_ci// Fast inlined version of PyType_IS_GC()
2197db96d56Sopenharmony_ci#define _PyType_IS_GC(t) _PyType_HasFeature((t), Py_TPFLAGS_HAVE_GC)
2207db96d56Sopenharmony_ci
2217db96d56Sopenharmony_cistatic inline size_t
2227db96d56Sopenharmony_ci_PyType_PreHeaderSize(PyTypeObject *tp)
2237db96d56Sopenharmony_ci{
2247db96d56Sopenharmony_ci    return _PyType_IS_GC(tp) * sizeof(PyGC_Head) +
2257db96d56Sopenharmony_ci        _PyType_HasFeature(tp, Py_TPFLAGS_MANAGED_DICT) * 2 * sizeof(PyObject *);
2267db96d56Sopenharmony_ci}
2277db96d56Sopenharmony_ci
2287db96d56Sopenharmony_civoid _PyObject_GC_Link(PyObject *op);
2297db96d56Sopenharmony_ci
2307db96d56Sopenharmony_ci// Usage: assert(_Py_CheckSlotResult(obj, "__getitem__", result != NULL));
2317db96d56Sopenharmony_ciextern int _Py_CheckSlotResult(
2327db96d56Sopenharmony_ci    PyObject *obj,
2337db96d56Sopenharmony_ci    const char *slot_name,
2347db96d56Sopenharmony_ci    int success);
2357db96d56Sopenharmony_ci
2367db96d56Sopenharmony_ci// PyType_Ready() must be called if _PyType_IsReady() is false.
2377db96d56Sopenharmony_ci// See also the Py_TPFLAGS_READY flag.
2387db96d56Sopenharmony_ci#define _PyType_IsReady(type) ((type)->tp_dict != NULL)
2397db96d56Sopenharmony_ci
2407db96d56Sopenharmony_ci// Test if a type supports weak references
2417db96d56Sopenharmony_cistatic inline int _PyType_SUPPORTS_WEAKREFS(PyTypeObject *type) {
2427db96d56Sopenharmony_ci    return (type->tp_weaklistoffset > 0);
2437db96d56Sopenharmony_ci}
2447db96d56Sopenharmony_ci
2457db96d56Sopenharmony_ciextern PyObject* _PyType_AllocNoTrack(PyTypeObject *type, Py_ssize_t nitems);
2467db96d56Sopenharmony_ci
2477db96d56Sopenharmony_ciextern int _PyObject_InitializeDict(PyObject *obj);
2487db96d56Sopenharmony_ciextern int _PyObject_StoreInstanceAttribute(PyObject *obj, PyDictValues *values,
2497db96d56Sopenharmony_ci                                          PyObject *name, PyObject *value);
2507db96d56Sopenharmony_ciPyObject * _PyObject_GetInstanceAttribute(PyObject *obj, PyDictValues *values,
2517db96d56Sopenharmony_ci                                        PyObject *name);
2527db96d56Sopenharmony_ci
2537db96d56Sopenharmony_cistatic inline PyDictValues **_PyObject_ValuesPointer(PyObject *obj)
2547db96d56Sopenharmony_ci{
2557db96d56Sopenharmony_ci    assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
2567db96d56Sopenharmony_ci    return ((PyDictValues **)obj)-4;
2577db96d56Sopenharmony_ci}
2587db96d56Sopenharmony_ci
2597db96d56Sopenharmony_cistatic inline PyObject **_PyObject_ManagedDictPointer(PyObject *obj)
2607db96d56Sopenharmony_ci{
2617db96d56Sopenharmony_ci    assert(Py_TYPE(obj)->tp_flags & Py_TPFLAGS_MANAGED_DICT);
2627db96d56Sopenharmony_ci    return ((PyObject **)obj)-3;
2637db96d56Sopenharmony_ci}
2647db96d56Sopenharmony_ci
2657db96d56Sopenharmony_ci#define MANAGED_DICT_OFFSET (((int)sizeof(PyObject *))*-3)
2667db96d56Sopenharmony_ci
2677db96d56Sopenharmony_ciextern PyObject ** _PyObject_DictPointer(PyObject *);
2687db96d56Sopenharmony_ciextern int _PyObject_VisitInstanceAttributes(PyObject *self, visitproc visit, void *arg);
2697db96d56Sopenharmony_ciextern void _PyObject_ClearInstanceAttributes(PyObject *self);
2707db96d56Sopenharmony_ciextern void _PyObject_FreeInstanceAttributes(PyObject *self);
2717db96d56Sopenharmony_ciextern int _PyObject_IsInstanceDictEmpty(PyObject *);
2727db96d56Sopenharmony_ciextern PyObject* _PyType_GetSubclasses(PyTypeObject *);
2737db96d56Sopenharmony_ci
2747db96d56Sopenharmony_ci// Access macro to the members which are floating "behind" the object
2757db96d56Sopenharmony_ci#define _PyHeapType_GET_MEMBERS(etype) \
2767db96d56Sopenharmony_ci    ((PyMemberDef *)(((char *)etype) + Py_TYPE(etype)->tp_basicsize))
2777db96d56Sopenharmony_ci
2787db96d56Sopenharmony_ciPyAPI_FUNC(PyObject *) _PyObject_LookupSpecial(PyObject *, PyObject *);
2797db96d56Sopenharmony_ci
2807db96d56Sopenharmony_ci/* C function call trampolines to mitigate bad function pointer casts.
2817db96d56Sopenharmony_ci *
2827db96d56Sopenharmony_ci * Typical native ABIs ignore additional arguments or fill in missing
2837db96d56Sopenharmony_ci * values with 0/NULL in function pointer cast. Compilers do not show
2847db96d56Sopenharmony_ci * warnings when a function pointer is explicitly casted to an
2857db96d56Sopenharmony_ci * incompatible type.
2867db96d56Sopenharmony_ci *
2877db96d56Sopenharmony_ci * Bad fpcasts are an issue in WebAssembly. WASM's indirect_call has strict
2887db96d56Sopenharmony_ci * function signature checks. Argument count, types, and return type must
2897db96d56Sopenharmony_ci * match.
2907db96d56Sopenharmony_ci *
2917db96d56Sopenharmony_ci * Third party code unintentionally rely on problematic fpcasts. The call
2927db96d56Sopenharmony_ci * trampoline mitigates common occurences of bad fpcasts on Emscripten.
2937db96d56Sopenharmony_ci */
2947db96d56Sopenharmony_ci#if defined(__EMSCRIPTEN__) && defined(PY_CALL_TRAMPOLINE)
2957db96d56Sopenharmony_ci#define _PyCFunction_TrampolineCall(meth, self, args) \
2967db96d56Sopenharmony_ci    _PyCFunctionWithKeywords_TrampolineCall( \
2977db96d56Sopenharmony_ci        (*(PyCFunctionWithKeywords)(void(*)(void))meth), self, args, NULL)
2987db96d56Sopenharmony_ciextern PyObject* _PyCFunctionWithKeywords_TrampolineCall(
2997db96d56Sopenharmony_ci    PyCFunctionWithKeywords meth, PyObject *, PyObject *, PyObject *);
3007db96d56Sopenharmony_ci#else
3017db96d56Sopenharmony_ci#define _PyCFunction_TrampolineCall(meth, self, args) \
3027db96d56Sopenharmony_ci    (meth)((self), (args))
3037db96d56Sopenharmony_ci#define _PyCFunctionWithKeywords_TrampolineCall(meth, self, args, kw) \
3047db96d56Sopenharmony_ci    (meth)((self), (args), (kw))
3057db96d56Sopenharmony_ci#endif // __EMSCRIPTEN__ && PY_CALL_TRAMPOLINE
3067db96d56Sopenharmony_ci
3077db96d56Sopenharmony_ci#ifdef __cplusplus
3087db96d56Sopenharmony_ci}
3097db96d56Sopenharmony_ci#endif
3107db96d56Sopenharmony_ci#endif /* !Py_INTERNAL_OBJECT_H */
311