PyAPI_FUNC(int) PyUnstable_Object_IsUniquelyReferenced(PyObject *);
PyAPI_FUNC(int) PyUnstable_SetImmortal(PyObject *op);
+
+#if defined(Py_GIL_DISABLED)
+PyAPI_FUNC(uintptr_t) _Py_GetThreadLocal_Addr(void);
+
+static inline uintptr_t
+_Py_ThreadId(void)
+{
+ uintptr_t tid;
+#if defined(_MSC_VER) && defined(_M_X64)
+ tid = __readgsqword(48);
+#elif defined(_MSC_VER) && defined(_M_IX86)
+ tid = __readfsdword(24);
+#elif defined(_MSC_VER) && defined(_M_ARM64)
+ tid = __getReg(18);
+#elif defined(__MINGW32__) && defined(_M_X64)
+ tid = __readgsqword(48);
+#elif defined(__MINGW32__) && defined(_M_IX86)
+ tid = __readfsdword(24);
+#elif defined(__MINGW32__) && defined(_M_ARM64)
+ tid = __getReg(18);
+#elif defined(__i386__)
+ __asm__("{movl %%gs:0, %0|mov %0, dword ptr gs:[0]}" : "=r" (tid)); // 32-bit always uses GS
+#elif defined(__MACH__) && defined(__x86_64__)
+ __asm__("{movq %%gs:0, %0|mov %0, qword ptr gs:[0]}" : "=r" (tid)); // x86_64 macOSX uses GS
+#elif defined(__x86_64__)
+ __asm__("{movq %%fs:0, %0|mov %0, qword ptr fs:[0]}" : "=r" (tid)); // x86_64 Linux, BSD uses FS
+#elif defined(__arm__) && __ARM_ARCH >= 7
+ __asm__ ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tid));
+#elif defined(__aarch64__) && defined(__APPLE__)
+ __asm__ ("mrs %0, tpidrro_el0" : "=r" (tid));
+#elif defined(__aarch64__)
+ __asm__ ("mrs %0, tpidr_el0" : "=r" (tid));
+#elif defined(__powerpc64__)
+ #if defined(__clang__) && _Py__has_builtin(__builtin_thread_pointer)
+ tid = (uintptr_t)__builtin_thread_pointer();
+ #else
+ // r13 is reserved for use as system thread ID by the Power 64-bit ABI.
+ register uintptr_t tp __asm__ ("r13");
+ __asm__("" : "=r" (tp));
+ tid = tp;
+ #endif
+#elif defined(__powerpc__)
+ #if defined(__clang__) && _Py__has_builtin(__builtin_thread_pointer)
+ tid = (uintptr_t)__builtin_thread_pointer();
+ #else
+ // r2 is reserved for use as system thread ID by the Power 32-bit ABI.
+ register uintptr_t tp __asm__ ("r2");
+ __asm__ ("" : "=r" (tp));
+ tid = tp;
+ #endif
+#elif defined(__s390__) && defined(__GNUC__)
+ // Both GCC and Clang have supported __builtin_thread_pointer
+ // for s390 from long time ago.
+ tid = (uintptr_t)__builtin_thread_pointer();
+#elif defined(__riscv)
+ #if defined(__clang__) && _Py__has_builtin(__builtin_thread_pointer)
+ tid = (uintptr_t)__builtin_thread_pointer();
+ #else
+ // tp is Thread Pointer provided by the RISC-V ABI.
+ __asm__ ("mv %0, tp" : "=r" (tid));
+ #endif
+#else
+ // Fallback to a portable implementation if we do not have a faster
+ // platform-specific implementation.
+ tid = _Py_GetThreadLocal_Addr();
+#endif
+ return tid;
+}
+
+static inline Py_ALWAYS_INLINE int
+_Py_IsOwnedByCurrentThread(PyObject *ob)
+{
+#ifdef _Py_THREAD_SANITIZER
+ return _Py_atomic_load_uintptr_relaxed(&ob->ob_tid) == _Py_ThreadId();
+#else
+ return ob->ob_tid == _Py_ThreadId();
+#endif
+}
+#endif
# define Py_MOD_GIL_NOT_USED ((void *)1)
#endif
-#if !defined(Py_LIMITED_API) && defined(Py_GIL_DISABLED)
+#if !defined(Py_LIMITED_API)
+# if defined(Py_GIL_DISABLED)
PyAPI_FUNC(int) PyUnstable_Module_SetGIL(PyObject *module, void *gil);
+# endif
#endif
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 >= _Py_PACK_VERSION(3, 15)
PyAPI_FUNC(int) Py_Is(PyObject *x, PyObject *y);
#define Py_Is(x, y) ((x) == (y))
-#if defined(Py_GIL_DISABLED) && !defined(Py_LIMITED_API)
-PyAPI_FUNC(uintptr_t) _Py_GetThreadLocal_Addr(void);
-
-static inline uintptr_t
-_Py_ThreadId(void)
-{
- uintptr_t tid;
-#if defined(_MSC_VER) && defined(_M_X64)
- tid = __readgsqword(48);
-#elif defined(_MSC_VER) && defined(_M_IX86)
- tid = __readfsdword(24);
-#elif defined(_MSC_VER) && defined(_M_ARM64)
- tid = __getReg(18);
-#elif defined(__MINGW32__) && defined(_M_X64)
- tid = __readgsqword(48);
-#elif defined(__MINGW32__) && defined(_M_IX86)
- tid = __readfsdword(24);
-#elif defined(__MINGW32__) && defined(_M_ARM64)
- tid = __getReg(18);
-#elif defined(__i386__)
- __asm__("{movl %%gs:0, %0|mov %0, dword ptr gs:[0]}" : "=r" (tid)); // 32-bit always uses GS
-#elif defined(__MACH__) && defined(__x86_64__)
- __asm__("{movq %%gs:0, %0|mov %0, qword ptr gs:[0]}" : "=r" (tid)); // x86_64 macOSX uses GS
-#elif defined(__x86_64__)
- __asm__("{movq %%fs:0, %0|mov %0, qword ptr fs:[0]}" : "=r" (tid)); // x86_64 Linux, BSD uses FS
-#elif defined(__arm__) && __ARM_ARCH >= 7
- __asm__ ("mrc p15, 0, %0, c13, c0, 3\nbic %0, %0, #3" : "=r" (tid));
-#elif defined(__aarch64__) && defined(__APPLE__)
- __asm__ ("mrs %0, tpidrro_el0" : "=r" (tid));
-#elif defined(__aarch64__)
- __asm__ ("mrs %0, tpidr_el0" : "=r" (tid));
-#elif defined(__powerpc64__)
- #if defined(__clang__) && _Py__has_builtin(__builtin_thread_pointer)
- tid = (uintptr_t)__builtin_thread_pointer();
- #else
- // r13 is reserved for use as system thread ID by the Power 64-bit ABI.
- register uintptr_t tp __asm__ ("r13");
- __asm__("" : "=r" (tp));
- tid = tp;
- #endif
-#elif defined(__powerpc__)
- #if defined(__clang__) && _Py__has_builtin(__builtin_thread_pointer)
- tid = (uintptr_t)__builtin_thread_pointer();
- #else
- // r2 is reserved for use as system thread ID by the Power 32-bit ABI.
- register uintptr_t tp __asm__ ("r2");
- __asm__ ("" : "=r" (tp));
- tid = tp;
- #endif
-#elif defined(__s390__) && defined(__GNUC__)
- // Both GCC and Clang have supported __builtin_thread_pointer
- // for s390 from long time ago.
- tid = (uintptr_t)__builtin_thread_pointer();
-#elif defined(__riscv)
- #if defined(__clang__) && _Py__has_builtin(__builtin_thread_pointer)
- tid = (uintptr_t)__builtin_thread_pointer();
- #else
- // tp is Thread Pointer provided by the RISC-V ABI.
- __asm__ ("mv %0, tp" : "=r" (tid));
- #endif
-#else
- // Fallback to a portable implementation if we do not have a faster
- // platform-specific implementation.
- tid = _Py_GetThreadLocal_Addr();
-#endif
- return tid;
-}
-
-static inline Py_ALWAYS_INLINE int
-_Py_IsOwnedByCurrentThread(PyObject *ob)
-{
-#ifdef _Py_THREAD_SANITIZER
- return _Py_atomic_load_uintptr_relaxed(&ob->ob_tid) == _Py_ThreadId();
-#else
- return ob->ob_tid == _Py_ThreadId();
-#endif
-}
-#endif
-
PyAPI_DATA(PyTypeObject) PyLong_Type;
PyAPI_DATA(PyTypeObject) PyBool_Type;
#define _Py_IMMORTAL_FLAGS (1 << 0)
#define _Py_LEGACY_ABI_CHECK_FLAG (1 << 1) /* see PyModuleDef_Init() */
#define _Py_STATICALLY_ALLOCATED_FLAG (1 << 2)
-#if defined(Py_GIL_DISABLED) && defined(Py_DEBUG)
-#define _Py_TYPE_REVEALED_FLAG (1 << 3)
+#if !defined(Py_LIMITED_API)
+# if defined(Py_GIL_DISABLED) && defined(Py_DEBUG)
+# define _Py_TYPE_REVEALED_FLAG (1 << 3)
+# endif
#endif
#define Py_CONSTANT_NONE 0
# define Py_BUILD_CORE
#endif
+#if defined(Py_TARGET_ABI3T)
+# if !defined(Py_GIL_DISABLED)
+// Define Py_GIL_DISABLED for users' needs. This macro is used to enable
+// locking needed in for free-threaded interpreters builds.
+# define Py_GIL_DISABLED
+# endif
+#endif
+
/**************************************************************************
Symbols and macros to supply platform-independent interfaces to basic
#endif
+#if !defined(_Py_OPAQUE_PYOBJECT)
/*
Immortalization:
# define _Py_REF_SHARED(refcnt, flags) \
(((refcnt) << _Py_REF_SHARED_SHIFT) + (flags))
#endif // Py_GIL_DISABLED
-
+#endif // _Py_OPAQUE_PYOBJECT
// Py_REFCNT() implementation for the stable ABI
PyAPI_FUNC(Py_ssize_t) Py_REFCNT(PyObject *ob);
#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030e0000
// Stable ABI implements Py_REFCNT() as a function call
- // on limited C API version 3.14 and newer.
+ // on limited C API version 3.14 and newer, and on abi3t.
+#elif defined(_Py_OPAQUE_PYOBJECT)
+ // Py_REFCNT() is also a function call in abi3t.
#else
static inline Py_ssize_t _Py_REFCNT(PyObject *ob) {
#if !defined(Py_GIL_DISABLED)
static inline void Py_SET_REFCNT(PyObject *ob, Py_ssize_t refcnt) {
assert(refcnt >= 0);
-#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030d0000
+#if (defined(Py_LIMITED_API) && Py_LIMITED_API+0 >= 0x030d0000) \
+ || defined(_Py_OPAQUE_PYOBJECT)
// Stable ABI implements Py_SET_REFCNT() as a function call
- // on limited C API version 3.13 and newer.
+ // on limited C API version 3.13 and newer, and abi3t.
_Py_SetRefcnt(ob, refcnt);
#else
// This immortal check is for code that is unaware of immortal objects.
ob->ob_ref_shared = _Py_REF_SHARED(refcnt, _Py_REF_MERGED);
}
#endif // Py_GIL_DISABLED
-#endif // Py_LIMITED_API+0 < 0x030d0000
+#endif // Py_LIMITED_API
}
#if !defined(Py_LIMITED_API) || Py_LIMITED_API+0 < 0x030b0000
# define Py_SET_REFCNT(ob, refcnt) Py_SET_REFCNT(_PyObject_CAST(ob), (refcnt))
static inline Py_ALWAYS_INLINE void Py_INCREF(PyObject *op)
{
-#if defined(Py_LIMITED_API) && (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG))
+#if (defined(Py_LIMITED_API) && (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG))) \
+ || defined(_Py_OPAQUE_PYOBJECT)
// Stable ABI implements Py_INCREF() as a function call on limited C API
- // version 3.12 and newer, and on Python built in debug mode. _Py_IncRef()
- // was added to Python 3.10.0a7, use Py_IncRef() on older Python versions.
+ // version 3.12 and newer, abi3t, and on Python built in debug mode.
+ // _Py_IncRef() was added to Python 3.10.0a7, use Py_IncRef() on older versions.
// Py_IncRef() accepts NULL whereas _Py_IncRef() doesn't.
# if Py_LIMITED_API+0 >= 0x030a00A7
_Py_IncRef(op);
# define Py_INCREF(op) Py_INCREF(_PyObject_CAST(op))
#endif
-
-#if !defined(Py_LIMITED_API) && defined(Py_GIL_DISABLED)
+#if !defined(Py_LIMITED_API)
+#if defined(Py_GIL_DISABLED)
// Implements Py_DECREF on objects not owned by the current thread.
PyAPI_FUNC(void) _Py_DecRefShared(PyObject *);
PyAPI_FUNC(void) _Py_DecRefSharedDebug(PyObject *, const char *, int);
// zero. Otherwise, the thread gives up ownership and merges the reference
// count fields.
PyAPI_FUNC(void) _Py_MergeZeroLocalRefcount(PyObject *);
-#endif
+#endif // Py_GIL_DISABLED
+#endif // Py_LIMITED_API
-#if defined(Py_LIMITED_API) && (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG))
+#if (defined(Py_LIMITED_API) && (Py_LIMITED_API+0 >= 0x030c0000 || defined(Py_REF_DEBUG))) \
+ || defined(_Py_OPAQUE_PYOBJECT)
// Stable ABI implements Py_DECREF() as a function call on limited C API
-// version 3.12 and newer, and on Python built in debug mode. _Py_DecRef() was
-// added to Python 3.10.0a7, use Py_DecRef() on older Python versions.
+// version 3.12 and newer, abi3t, and on Python built in debug mode.
+// _Py_DecRef() was added to Python 3.10.0a7, use Py_DecRef() on older versions.
// Py_DecRef() accepts NULL whereas _Py_DecRef() doesn't.
static inline void Py_DECREF(PyObject *op) {
# if Py_LIMITED_API+0 >= 0x030a00A7