aboutsummaryrefslogtreecommitdiffstatshomepage
path: root/Include
diff options
context:
space:
mode:
Diffstat (limited to 'Include')
-rw-r--r--Include/Python.h13
-rw-r--r--Include/abstract.h14
-rw-r--r--Include/boolobject.h13
-rw-r--r--Include/cpython/unicodeobject.h131
-rw-r--r--Include/internal/mimalloc/mimalloc/internal.h4
-rw-r--r--Include/internal/pycore_ceval.h13
-rw-r--r--Include/internal/pycore_critical_section.h24
-rw-r--r--Include/internal/pycore_crossinterp.h37
-rw-r--r--Include/internal/pycore_freelist_state.h2
-rw-r--r--Include/internal/pycore_interp_structs.h3
-rw-r--r--Include/internal/pycore_long.h13
-rw-r--r--Include/internal/pycore_magic_number.h3
-rw-r--r--Include/internal/pycore_object.h21
-rw-r--r--Include/internal/pycore_opcode_metadata.h8
-rw-r--r--Include/internal/pycore_optimizer.h117
-rw-r--r--Include/internal/pycore_pymem.h10
-rw-r--r--Include/internal/pycore_stackref.h68
-rw-r--r--Include/internal/pycore_uop_ids.h476
-rw-r--r--Include/internal/pycore_uop_metadata.h81
-rw-r--r--Include/object.h18
-rw-r--r--Include/pymacro.h82
21 files changed, 720 insertions, 431 deletions
diff --git a/Include/Python.h b/Include/Python.h
index f34d581f0b4..64be8014589 100644
--- a/Include/Python.h
+++ b/Include/Python.h
@@ -59,14 +59,6 @@
# include <intrin.h> // __readgsqword()
#endif
-// Suppress known warnings in Python header files.
-#if defined(_MSC_VER)
-// Warning that alignas behaviour has changed. Doesn't affect us, because we
-// never relied on the old behaviour.
-#pragma warning(push)
-#pragma warning(disable: 5274)
-#endif
-
// Include Python header files
#include "pyport.h"
#include "pymacro.h"
@@ -146,9 +138,4 @@
#include "cpython/pyfpe.h"
#include "cpython/tracemalloc.h"
-// Restore warning filter
-#ifdef _MSC_VER
-#pragma warning(pop)
-#endif
-
#endif /* !Py_PYTHON_H */
diff --git a/Include/abstract.h b/Include/abstract.h
index b9199fc03a3..80f3298701d 100644
--- a/Include/abstract.h
+++ b/Include/abstract.h
@@ -138,7 +138,12 @@ extern "C" {
Delete attribute named attr_name, for object o. Returns
-1 on failure.
- This is the equivalent of the Python statement: del o.attr_name. */
+ This is the equivalent of the Python statement: del o.attr_name.
+
+ Implemented as a macro in the limited C API 3.12 and older. */
+#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 < 0x030d0000
+# define PyObject_DelAttrString(O, A) PyObject_SetAttrString((O), (A), NULL)
+#endif
/* Implemented elsewhere:
@@ -147,7 +152,12 @@ extern "C" {
Delete attribute named attr_name, for object o. Returns -1
on failure. This is the equivalent of the Python
- statement: del o.attr_name. */
+ statement: del o.attr_name.
+
+ Implemented as a macro in the limited C API 3.12 and older. */
+#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 < 0x030d0000
+# define PyObject_DelAttr(O, A) PyObject_SetAttr((O), (A), NULL)
+#endif
/* Implemented elsewhere:
diff --git a/Include/boolobject.h b/Include/boolobject.h
index 3037e61bbf6..b56e2baecaa 100644
--- a/Include/boolobject.h
+++ b/Include/boolobject.h
@@ -34,9 +34,16 @@ PyAPI_FUNC(int) Py_IsTrue(PyObject *x);
PyAPI_FUNC(int) Py_IsFalse(PyObject *x);
#define Py_IsFalse(x) Py_Is((x), Py_False)
-/* Macros for returning Py_True or Py_False, respectively */
-#define Py_RETURN_TRUE return Py_True
-#define Py_RETURN_FALSE return Py_False
+/* Macros for returning Py_True or Py_False, respectively.
+ * Only treat Py_True and Py_False as immortal in the limited C API 3.12
+ * and newer. */
+#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 < 0x030c0000
+# define Py_RETURN_TRUE return Py_NewRef(Py_True)
+# define Py_RETURN_FALSE return Py_NewRef(Py_False)
+#else
+# define Py_RETURN_TRUE return Py_True
+# define Py_RETURN_FALSE return Py_False
+#endif
/* Function to return a bool from a C long */
PyAPI_FUNC(PyObject *) PyBool_FromLong(long);
diff --git a/Include/cpython/unicodeobject.h b/Include/cpython/unicodeobject.h
index 3d0414f5291..86c502730f4 100644
--- a/Include/cpython/unicodeobject.h
+++ b/Include/cpython/unicodeobject.h
@@ -47,6 +47,63 @@ static inline Py_UCS4 Py_UNICODE_LOW_SURROGATE(Py_UCS4 ch) {
/* --- Unicode Type ------------------------------------------------------- */
+struct _PyUnicodeObject_state {
+ /* If interned is non-zero, the two references from the
+ dictionary to this object are *not* counted in ob_refcnt.
+ The possible values here are:
+ 0: Not Interned
+ 1: Interned
+ 2: Interned and Immortal
+ 3: Interned, Immortal, and Static
+ This categorization allows the runtime to determine the right
+ cleanup mechanism at runtime shutdown. */
+#ifdef Py_GIL_DISABLED
+ // Needs to be accessed atomically, so can't be a bit field.
+ unsigned char interned;
+#else
+ unsigned int interned:2;
+#endif
+ /* Character size:
+
+ - PyUnicode_1BYTE_KIND (1):
+
+ * character type = Py_UCS1 (8 bits, unsigned)
+ * all characters are in the range U+0000-U+00FF (latin1)
+ * if ascii is set, all characters are in the range U+0000-U+007F
+ (ASCII), otherwise at least one character is in the range
+ U+0080-U+00FF
+
+ - PyUnicode_2BYTE_KIND (2):
+
+ * character type = Py_UCS2 (16 bits, unsigned)
+ * all characters are in the range U+0000-U+FFFF (BMP)
+ * at least one character is in the range U+0100-U+FFFF
+
+ - PyUnicode_4BYTE_KIND (4):
+
+ * character type = Py_UCS4 (32 bits, unsigned)
+ * all characters are in the range U+0000-U+10FFFF
+ * at least one character is in the range U+10000-U+10FFFF
+ */
+ unsigned int kind:3;
+ /* Compact is with respect to the allocation scheme. Compact unicode
+ objects only require one memory block while non-compact objects use
+ one block for the PyUnicodeObject struct and another for its data
+ buffer. */
+ unsigned int compact:1;
+ /* The string only contains characters in the range U+0000-U+007F (ASCII)
+ and the kind is PyUnicode_1BYTE_KIND. If ascii is set and compact is
+ set, use the PyASCIIObject structure. */
+ unsigned int ascii:1;
+ /* The object is statically allocated. */
+ unsigned int statically_allocated:1;
+#ifndef Py_GIL_DISABLED
+ /* Historical: padding to ensure that PyUnicode_DATA() is always aligned to
+ 4 bytes (see issue gh-63736 on m68k) */
+ unsigned int :24;
+#endif
+};
+
/* ASCII-only strings created through PyUnicode_New use the PyASCIIObject
structure. state.ascii and state.compact are set, and the data
immediately follow the structure. utf8_length can be found
@@ -99,67 +156,8 @@ typedef struct {
PyObject_HEAD
Py_ssize_t length; /* Number of code points in the string */
Py_hash_t hash; /* Hash value; -1 if not set */
-#ifdef Py_GIL_DISABLED
- /* Ensure 4 byte alignment for PyUnicode_DATA(), see gh-63736 on m68k.
- In the non-free-threaded build, we'll use explicit padding instead */
- _Py_ALIGN_AS(4)
-#endif
- struct {
- /* If interned is non-zero, the two references from the
- dictionary to this object are *not* counted in ob_refcnt.
- The possible values here are:
- 0: Not Interned
- 1: Interned
- 2: Interned and Immortal
- 3: Interned, Immortal, and Static
- This categorization allows the runtime to determine the right
- cleanup mechanism at runtime shutdown. */
-#ifdef Py_GIL_DISABLED
- // Needs to be accessed atomically, so can't be a bit field.
- unsigned char interned;
-#else
- unsigned int interned:2;
-#endif
- /* Character size:
-
- - PyUnicode_1BYTE_KIND (1):
-
- * character type = Py_UCS1 (8 bits, unsigned)
- * all characters are in the range U+0000-U+00FF (latin1)
- * if ascii is set, all characters are in the range U+0000-U+007F
- (ASCII), otherwise at least one character is in the range
- U+0080-U+00FF
-
- - PyUnicode_2BYTE_KIND (2):
-
- * character type = Py_UCS2 (16 bits, unsigned)
- * all characters are in the range U+0000-U+FFFF (BMP)
- * at least one character is in the range U+0100-U+FFFF
-
- - PyUnicode_4BYTE_KIND (4):
-
- * character type = Py_UCS4 (32 bits, unsigned)
- * all characters are in the range U+0000-U+10FFFF
- * at least one character is in the range U+10000-U+10FFFF
- */
- unsigned int kind:3;
- /* Compact is with respect to the allocation scheme. Compact unicode
- objects only require one memory block while non-compact objects use
- one block for the PyUnicodeObject struct and another for its data
- buffer. */
- unsigned int compact:1;
- /* The string only contains characters in the range U+0000-U+007F (ASCII)
- and the kind is PyUnicode_1BYTE_KIND. If ascii is set and compact is
- set, use the PyASCIIObject structure. */
- unsigned int ascii:1;
- /* The object is statically allocated. */
- unsigned int statically_allocated:1;
-#ifndef Py_GIL_DISABLED
- /* Padding to ensure that PyUnicode_DATA() is always aligned to
- 4 bytes (see issue gh-63736 on m68k) */
- unsigned int :24;
-#endif
- } state;
+ /* Ensure 4 byte alignment for PyUnicode_DATA(), see gh-63736 on m68k. */
+ _Py_ALIGNED_DEF(4, struct _PyUnicodeObject_state) state;
} PyASCIIObject;
/* Non-ASCII strings allocated through PyUnicode_New use the
@@ -300,6 +298,17 @@ static inline Py_ssize_t PyUnicode_GET_LENGTH(PyObject *op) {
}
#define PyUnicode_GET_LENGTH(op) PyUnicode_GET_LENGTH(_PyObject_CAST(op))
+/* Returns the cached hash, or -1 if not cached yet. */
+static inline Py_hash_t
+PyUnstable_Unicode_GET_CACHED_HASH(PyObject *op) {
+ assert(PyUnicode_Check(op));
+#ifdef Py_GIL_DISABLED
+ return _Py_atomic_load_ssize_relaxed(&_PyASCIIObject_CAST(op)->hash);
+#else
+ return _PyASCIIObject_CAST(op)->hash;
+#endif
+}
+
/* Write into the canonical representation, this function does not do any sanity
checks and is intended for usage in loops. The caller should cache the
kind and data pointers obtained from other function calls.
diff --git a/Include/internal/mimalloc/mimalloc/internal.h b/Include/internal/mimalloc/mimalloc/internal.h
index 71b7ea702d6..a7daa3a40a4 100644
--- a/Include/internal/mimalloc/mimalloc/internal.h
+++ b/Include/internal/mimalloc/mimalloc/internal.h
@@ -634,10 +634,10 @@ static inline mi_block_t* mi_block_nextx( const void* null, const mi_block_t* bl
mi_track_mem_defined(block,sizeof(mi_block_t));
mi_block_t* next;
#ifdef MI_ENCODE_FREELIST
- next = (mi_block_t*)mi_ptr_decode(null, mi_atomic_load_relaxed(&block->next), keys);
+ next = (mi_block_t*)mi_ptr_decode(null, mi_atomic_load_relaxed((_Atomic(mi_encoded_t)*)&block->next), keys);
#else
MI_UNUSED(keys); MI_UNUSED(null);
- next = (mi_block_t*)mi_atomic_load_relaxed(&block->next);
+ next = (mi_block_t*)mi_atomic_load_relaxed((_Atomic(mi_encoded_t)*)&block->next);
#endif
mi_track_mem_noaccess(block,sizeof(mi_block_t));
return next;
diff --git a/Include/internal/pycore_ceval.h b/Include/internal/pycore_ceval.h
index 092feeb40b0..18623cc8f1c 100644
--- a/Include/internal/pycore_ceval.h
+++ b/Include/internal/pycore_ceval.h
@@ -239,6 +239,16 @@ static inline void _Py_LeaveRecursiveCall(void) {
extern _PyInterpreterFrame* _PyEval_GetFrame(void);
+extern PyObject * _PyEval_GetGlobalsFromRunningMain(PyThreadState *);
+extern int _PyEval_EnsureBuiltins(
+ PyThreadState *,
+ PyObject *,
+ PyObject **p_builtins);
+extern int _PyEval_EnsureBuiltinsWithModule(
+ PyThreadState *,
+ PyObject *,
+ PyObject **p_builtins);
+
PyAPI_FUNC(PyObject *)_Py_MakeCoro(PyFunctionObject *func);
/* Handle signals, pending calls, GIL drop request
@@ -353,7 +363,8 @@ PyAPI_FUNC(_PyStackRef) _PyFloat_FromDouble_ConsumeInputs(_PyStackRef left, _PyS
extern int _PyRunRemoteDebugger(PyThreadState *tstate);
#endif
-_PyStackRef _PyForIter_NextWithIndex(PyObject *seq, _PyStackRef index);
+PyAPI_FUNC(_PyStackRef)
+_PyForIter_VirtualIteratorNext(PyThreadState* tstate, struct _PyInterpreterFrame* frame, _PyStackRef iter, _PyStackRef *index_ptr);
#ifdef __cplusplus
}
diff --git a/Include/internal/pycore_critical_section.h b/Include/internal/pycore_critical_section.h
index 42f06b935bd..62460c5f8fa 100644
--- a/Include/internal/pycore_critical_section.h
+++ b/Include/internal/pycore_critical_section.h
@@ -64,7 +64,7 @@ extern "C" {
# define _Py_CRITICAL_SECTION_ASSERT_OBJECT_LOCKED(op) \
if (Py_REFCNT(op) != 1) { \
- _Py_CRITICAL_SECTION_ASSERT_MUTEX_LOCKED(&_PyObject_CAST(op)->ob_mutex); \
+ _PyCriticalSection_AssertHeldObj(_PyObject_CAST(op)); \
}
#else /* Py_DEBUG */
@@ -239,6 +239,28 @@ _PyCriticalSection_AssertHeld(PyMutex *mutex)
#endif
}
+static inline void
+_PyCriticalSection_AssertHeldObj(PyObject *op)
+{
+#ifdef Py_DEBUG
+ PyMutex *mutex = &_PyObject_CAST(op)->ob_mutex;
+ PyThreadState *tstate = _PyThreadState_GET();
+ uintptr_t prev = tstate->critical_section;
+ if (prev & _Py_CRITICAL_SECTION_TWO_MUTEXES) {
+ PyCriticalSection2 *cs = (PyCriticalSection2 *)(prev & ~_Py_CRITICAL_SECTION_MASK);
+ _PyObject_ASSERT_WITH_MSG(op,
+ (cs != NULL && (cs->_cs_base._cs_mutex == mutex || cs->_cs_mutex2 == mutex)),
+ "Critical section of object is not held");
+ }
+ else {
+ PyCriticalSection *cs = (PyCriticalSection *)(prev & ~_Py_CRITICAL_SECTION_MASK);
+ _PyObject_ASSERT_WITH_MSG(op,
+ (cs != NULL && cs->_cs_mutex == mutex),
+ "Critical section of object is not held");
+ }
+
+#endif
+}
#endif /* Py_GIL_DISABLED */
#ifdef __cplusplus
diff --git a/Include/internal/pycore_crossinterp.h b/Include/internal/pycore_crossinterp.h
index 713ddc66ba7..81faffac194 100644
--- a/Include/internal/pycore_crossinterp.h
+++ b/Include/internal/pycore_crossinterp.h
@@ -303,10 +303,10 @@ typedef struct _excinfo {
const char *errdisplay;
} _PyXI_excinfo;
-PyAPI_FUNC(int) _PyXI_InitExcInfo(_PyXI_excinfo *info, PyObject *exc);
+PyAPI_FUNC(_PyXI_excinfo *) _PyXI_NewExcInfo(PyObject *exc);
+PyAPI_FUNC(void) _PyXI_FreeExcInfo(_PyXI_excinfo *info);
PyAPI_FUNC(PyObject *) _PyXI_FormatExcInfo(_PyXI_excinfo *info);
PyAPI_FUNC(PyObject *) _PyXI_ExcInfoAsObject(_PyXI_excinfo *info);
-PyAPI_FUNC(void) _PyXI_ClearExcInfo(_PyXI_excinfo *info);
typedef enum error_code {
@@ -322,19 +322,20 @@ typedef enum error_code {
_PyXI_ERR_NOT_SHAREABLE = -9,
} _PyXI_errcode;
+typedef struct xi_failure _PyXI_failure;
-typedef struct _sharedexception {
- // The originating interpreter.
- PyInterpreterState *interp;
- // The kind of error to propagate.
- _PyXI_errcode code;
- // The exception information to propagate, if applicable.
- // This is populated only for some error codes,
- // but always for _PyXI_ERR_UNCAUGHT_EXCEPTION.
- _PyXI_excinfo uncaught;
-} _PyXI_error;
+PyAPI_FUNC(_PyXI_failure *) _PyXI_NewFailure(void);
+PyAPI_FUNC(void) _PyXI_FreeFailure(_PyXI_failure *);
+PyAPI_FUNC(_PyXI_errcode) _PyXI_GetFailureCode(_PyXI_failure *);
+PyAPI_FUNC(int) _PyXI_InitFailure(_PyXI_failure *, _PyXI_errcode, PyObject *);
+PyAPI_FUNC(void) _PyXI_InitFailureUTF8(
+ _PyXI_failure *,
+ _PyXI_errcode,
+ const char *);
-PyAPI_FUNC(PyObject *) _PyXI_ApplyError(_PyXI_error *err);
+PyAPI_FUNC(int) _PyXI_UnwrapNotShareableError(
+ PyThreadState *,
+ _PyXI_failure *);
// A cross-interpreter session involves entering an interpreter
@@ -366,19 +367,21 @@ PyAPI_FUNC(int) _PyXI_Enter(
_PyXI_session_result *);
PyAPI_FUNC(int) _PyXI_Exit(
_PyXI_session *,
- _PyXI_errcode,
+ _PyXI_failure *,
_PyXI_session_result *);
PyAPI_FUNC(PyObject *) _PyXI_GetMainNamespace(
_PyXI_session *,
- _PyXI_errcode *);
+ _PyXI_failure *);
PyAPI_FUNC(int) _PyXI_Preserve(
_PyXI_session *,
const char *,
PyObject *,
- _PyXI_errcode *);
-PyAPI_FUNC(PyObject *) _PyXI_GetPreserved(_PyXI_session_result *, const char *);
+ _PyXI_failure *);
+PyAPI_FUNC(PyObject *) _PyXI_GetPreserved(
+ _PyXI_session_result *,
+ const char *);
/*************/
diff --git a/Include/internal/pycore_freelist_state.h b/Include/internal/pycore_freelist_state.h
index 4828dfd948f..59beb92f3f7 100644
--- a/Include/internal/pycore_freelist_state.h
+++ b/Include/internal/pycore_freelist_state.h
@@ -16,6 +16,7 @@ extern "C" {
# define Py_dicts_MAXFREELIST 80
# define Py_dictkeys_MAXFREELIST 80
# define Py_floats_MAXFREELIST 100
+# define Py_complexes_MAXFREELIST 100
# define Py_ints_MAXFREELIST 100
# define Py_slices_MAXFREELIST 1
# define Py_ranges_MAXFREELIST 6
@@ -43,6 +44,7 @@ struct _Py_freelist {
struct _Py_freelists {
struct _Py_freelist floats;
+ struct _Py_freelist complexes;
struct _Py_freelist ints;
struct _Py_freelist tuples[PyTuple_MAXSAVESIZE];
struct _Py_freelist lists;
diff --git a/Include/internal/pycore_interp_structs.h b/Include/internal/pycore_interp_structs.h
index f25f5847b3b..f1f427d99de 100644
--- a/Include/internal/pycore_interp_structs.h
+++ b/Include/internal/pycore_interp_structs.h
@@ -159,10 +159,11 @@ struct atexit_state {
typedef struct {
// Tagged pointer to next object in the list.
// 0 means the object is not tracked
- uintptr_t _gc_next;
+ _Py_ALIGNED_DEF(_PyObject_MIN_ALIGNMENT, uintptr_t) _gc_next;
// Tagged pointer to previous object in the list.
// Lowest two bits are used for flags documented later.
+ // Those bits are made available by the struct's minimum alignment.
uintptr_t _gc_prev;
} PyGC_Head;
diff --git a/Include/internal/pycore_long.h b/Include/internal/pycore_long.h
index 3196d1b8208..3c213783cd4 100644
--- a/Include/internal/pycore_long.h
+++ b/Include/internal/pycore_long.h
@@ -112,9 +112,9 @@ PyAPI_DATA(PyObject*) _PyLong_Rshift(PyObject *, int64_t);
// Export for 'math' shared extension
PyAPI_DATA(PyObject*) _PyLong_Lshift(PyObject *, int64_t);
-PyAPI_FUNC(PyObject*) _PyLong_Add(PyLongObject *left, PyLongObject *right);
-PyAPI_FUNC(PyObject*) _PyLong_Multiply(PyLongObject *left, PyLongObject *right);
-PyAPI_FUNC(PyObject*) _PyLong_Subtract(PyLongObject *left, PyLongObject *right);
+PyAPI_FUNC(_PyStackRef) _PyCompactLong_Add(PyLongObject *left, PyLongObject *right);
+PyAPI_FUNC(_PyStackRef) _PyCompactLong_Multiply(PyLongObject *left, PyLongObject *right);
+PyAPI_FUNC(_PyStackRef) _PyCompactLong_Subtract(PyLongObject *left, PyLongObject *right);
// Export for 'binascii' shared extension.
PyAPI_DATA(unsigned char) _PyLong_DigitValue[256];
@@ -213,7 +213,6 @@ _PyLong_BothAreCompact(const PyLongObject* a, const PyLongObject* b) {
assert(PyLong_Check(b));
return (a->long_value.lv_tag | b->long_value.lv_tag) < (2 << NON_SIZE_BITS);
}
-
static inline bool
_PyLong_IsZero(const PyLongObject *op)
{
@@ -313,6 +312,12 @@ _PyLong_FlipSign(PyLongObject *op) {
#define _PyLong_FALSE_TAG TAG_FROM_SIGN_AND_SIZE(0, 0)
#define _PyLong_TRUE_TAG TAG_FROM_SIGN_AND_SIZE(1, 1)
+static inline int
+_PyLong_CheckExactAndCompact(PyObject *op)
+{
+ return PyLong_CheckExact(op) && _PyLong_IsCompact((const PyLongObject *)op);
+}
+
#ifdef __cplusplus
}
#endif
diff --git a/Include/internal/pycore_magic_number.h b/Include/internal/pycore_magic_number.h
index cd1fc873623..347d9762f26 100644
--- a/Include/internal/pycore_magic_number.h
+++ b/Include/internal/pycore_magic_number.h
@@ -280,6 +280,7 @@ Known values:
Python 3.15a0 3650 (Initial version)
Python 3.15a1 3651 (Simplify LOAD_CONST)
Python 3.15a1 3652 (Virtual iterators)
+ Python 3.15a1 3653 (Fix handling of opcodes that may leave operands on the stack when optimizing LOAD_FAST)
Python 3.16 will start with 3700
@@ -293,7 +294,7 @@ PC/launcher.c must also be updated.
*/
-#define PYC_MAGIC_NUMBER 3652
+#define PYC_MAGIC_NUMBER 3653
/* This is equivalent to converting PYC_MAGIC_NUMBER to 2 bytes
(little-endian) and then appending b'\r\n'. */
#define PYC_MAGIC_NUMBER_TOKEN \
diff --git a/Include/internal/pycore_object.h b/Include/internal/pycore_object.h
index 50225623fe5..50807e68e9a 100644
--- a/Include/internal/pycore_object.h
+++ b/Include/internal/pycore_object.h
@@ -767,6 +767,27 @@ _Py_TryIncref(PyObject *op)
#endif
}
+// Enqueue an object to be freed possibly after some delay
+#ifdef Py_GIL_DISABLED
+PyAPI_FUNC(void) _PyObject_XDecRefDelayed(PyObject *obj);
+#else
+static inline void _PyObject_XDecRefDelayed(PyObject *obj)
+{
+ Py_XDECREF(obj);
+}
+#endif
+
+#ifdef Py_GIL_DISABLED
+// Same as `Py_XSETREF` but in free-threading, it stores the object atomically
+// and queues the old object to be decrefed at a safe point using QSBR.
+PyAPI_FUNC(void) _PyObject_XSetRefDelayed(PyObject **p_obj, PyObject *obj);
+#else
+static inline void _PyObject_XSetRefDelayed(PyObject **p_obj, PyObject *obj)
+{
+ Py_XSETREF(*p_obj, obj);
+}
+#endif
+
#ifdef Py_REF_DEBUG
extern void _PyInterpreterState_FinalizeRefTotal(PyInterpreterState *);
extern void _Py_FinalizeRefTotal(_PyRuntimeState *);
diff --git a/Include/internal/pycore_opcode_metadata.h b/Include/internal/pycore_opcode_metadata.h
index 00e918cb8f0..dd1bf2d1d2b 100644
--- a/Include/internal/pycore_opcode_metadata.h
+++ b/Include/internal/pycore_opcode_metadata.h
@@ -1072,12 +1072,12 @@ extern const struct opcode_metadata _PyOpcode_opcode_metadata[267];
const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
[BINARY_OP] = { true, INSTR_FMT_IBC0000, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[BINARY_OP_ADD_FLOAT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
- [BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [BINARY_OP_ADD_INT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG },
[BINARY_OP_ADD_UNICODE] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
[BINARY_OP_EXTEND] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG },
[BINARY_OP_INPLACE_ADD_UNICODE] = { true, INSTR_FMT_IXC0000, HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[BINARY_OP_MULTIPLY_FLOAT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
- [BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [BINARY_OP_MULTIPLY_INT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG },
[BINARY_OP_SUBSCR_DICT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[BINARY_OP_SUBSCR_GETITEM] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG },
[BINARY_OP_SUBSCR_LIST_INT] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
@@ -1085,7 +1085,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
[BINARY_OP_SUBSCR_STR_INT] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
[BINARY_OP_SUBSCR_TUPLE_INT] = { true, INSTR_FMT_IXC0000, HAS_DEOPT_FLAG | HAS_EXIT_FLAG | HAS_ESCAPES_FLAG },
[BINARY_OP_SUBTRACT_FLOAT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG },
- [BINARY_OP_SUBTRACT_INT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
+ [BINARY_OP_SUBTRACT_INT] = { true, INSTR_FMT_IXC0000, HAS_EXIT_FLAG },
[BINARY_SLICE] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[BUILD_INTERPOLATION] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[BUILD_LIST] = { true, INSTR_FMT_IB, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
@@ -1129,7 +1129,7 @@ const struct opcode_metadata _PyOpcode_opcode_metadata[267] = {
[CLEANUP_THROW] = { true, INSTR_FMT_IX, HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG },
[COMPARE_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[COMPARE_OP_FLOAT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EXIT_FLAG },
- [COMPARE_OP_INT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_DEOPT_FLAG | HAS_EXIT_FLAG },
+ [COMPARE_OP_INT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EXIT_FLAG },
[COMPARE_OP_STR] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EXIT_FLAG },
[CONTAINS_OP] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
[CONTAINS_OP_DICT] = { true, INSTR_FMT_IBC, HAS_ARG_FLAG | HAS_EXIT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG },
diff --git a/Include/internal/pycore_optimizer.h b/Include/internal/pycore_optimizer.h
index d3674726997..576c2794782 100644
--- a/Include/internal/pycore_optimizer.h
+++ b/Include/internal/pycore_optimizer.h
@@ -10,6 +10,7 @@ extern "C" {
#include "pycore_typedefs.h" // _PyInterpreterFrame
#include "pycore_uop_ids.h"
+#include "pycore_stackref.h"
#include <stdbool.h>
@@ -178,6 +179,7 @@ typedef enum _JitSymType {
JIT_SYM_KNOWN_VALUE_TAG = 7,
JIT_SYM_TUPLE_TAG = 8,
JIT_SYM_TRUTHINESS_TAG = 9,
+ JIT_SYM_COMPACT_INT = 10,
} JitSymType;
typedef struct _jit_opt_known_class {
@@ -210,6 +212,10 @@ typedef struct {
uint16_t value;
} JitOptTruthiness;
+typedef struct {
+ uint8_t tag;
+} JitOptCompactInt;
+
typedef union _jit_opt_symbol {
uint8_t tag;
JitOptKnownClass cls;
@@ -217,18 +223,62 @@ typedef union _jit_opt_symbol {
JitOptKnownVersion version;
JitOptTuple tuple;
JitOptTruthiness truthiness;
+ JitOptCompactInt compact;
} JitOptSymbol;
+// This mimics the _PyStackRef API
+typedef union {
+ uintptr_t bits;
+} JitOptRef;
+
+#define REF_IS_BORROWED 1
+
+#define JIT_BITS_TO_PTR_MASKED(REF) ((JitOptSymbol *)(((REF).bits) & (~REF_IS_BORROWED)))
+
+static inline JitOptSymbol *
+PyJitRef_Unwrap(JitOptRef ref)
+{
+ return JIT_BITS_TO_PTR_MASKED(ref);
+}
+
+bool _Py_uop_symbol_is_immortal(JitOptSymbol *sym);
+
+
+static inline JitOptRef
+PyJitRef_Wrap(JitOptSymbol *sym)
+{
+ return (JitOptRef){.bits=(uintptr_t)sym};
+}
+
+static inline JitOptRef
+PyJitRef_Borrow(JitOptRef ref)
+{
+ return (JitOptRef){ .bits = ref.bits | REF_IS_BORROWED };
+}
+
+static const JitOptRef PyJitRef_NULL = {.bits = REF_IS_BORROWED};
+
+static inline bool
+PyJitRef_IsNull(JitOptRef ref)
+{
+ return ref.bits == PyJitRef_NULL.bits;
+}
+
+static inline int
+PyJitRef_IsBorrowed(JitOptRef ref)
+{
+ return (ref.bits & REF_IS_BORROWED) == REF_IS_BORROWED;
+}
struct _Py_UOpsAbstractFrame {
// Max stacklen
int stack_len;
int locals_len;
- JitOptSymbol **stack_pointer;
- JitOptSymbol **stack;
- JitOptSymbol **locals;
+ JitOptRef *stack_pointer;
+ JitOptRef *stack;
+ JitOptRef *locals;
};
typedef struct _Py_UOpsAbstractFrame _Py_UOpsAbstractFrame;
@@ -251,37 +301,40 @@ typedef struct _JitOptContext {
// Arena for the symbolic types.
ty_arena t_arena;
- JitOptSymbol **n_consumed;
- JitOptSymbol **limit;
- JitOptSymbol *locals_and_stack[MAX_ABSTRACT_INTERP_SIZE];
+ JitOptRef *n_consumed;
+ JitOptRef *limit;
+ JitOptRef locals_and_stack[MAX_ABSTRACT_INTERP_SIZE];
} JitOptContext;
-extern bool _Py_uop_sym_is_null(JitOptSymbol *sym);
-extern bool _Py_uop_sym_is_not_null(JitOptSymbol *sym);
-extern bool _Py_uop_sym_is_const(JitOptContext *ctx, JitOptSymbol *sym);
-extern PyObject *_Py_uop_sym_get_const(JitOptContext *ctx, JitOptSymbol *sym);
-extern JitOptSymbol *_Py_uop_sym_new_unknown(JitOptContext *ctx);
-extern JitOptSymbol *_Py_uop_sym_new_not_null(JitOptContext *ctx);
-extern JitOptSymbol *_Py_uop_sym_new_type(
+extern bool _Py_uop_sym_is_null(JitOptRef sym);
+extern bool _Py_uop_sym_is_not_null(JitOptRef sym);
+extern bool _Py_uop_sym_is_const(JitOptContext *ctx, JitOptRef sym);
+extern PyObject *_Py_uop_sym_get_const(JitOptContext *ctx, JitOptRef sym);
+extern JitOptRef _Py_uop_sym_new_unknown(JitOptContext *ctx);
+extern JitOptRef _Py_uop_sym_new_not_null(JitOptContext *ctx);
+extern JitOptRef _Py_uop_sym_new_type(
JitOptContext *ctx, PyTypeObject *typ);
-extern JitOptSymbol *_Py_uop_sym_new_const(JitOptContext *ctx, PyObject *const_val);
-extern JitOptSymbol *_Py_uop_sym_new_null(JitOptContext *ctx);
-extern bool _Py_uop_sym_has_type(JitOptSymbol *sym);
-extern bool _Py_uop_sym_matches_type(JitOptSymbol *sym, PyTypeObject *typ);
-extern bool _Py_uop_sym_matches_type_version(JitOptSymbol *sym, unsigned int version);
-extern void _Py_uop_sym_set_null(JitOptContext *ctx, JitOptSymbol *sym);
-extern void _Py_uop_sym_set_non_null(JitOptContext *ctx, JitOptSymbol *sym);
-extern void _Py_uop_sym_set_type(JitOptContext *ctx, JitOptSymbol *sym, PyTypeObject *typ);
-extern bool _Py_uop_sym_set_type_version(JitOptContext *ctx, JitOptSymbol *sym, unsigned int version);
-extern void _Py_uop_sym_set_const(JitOptContext *ctx, JitOptSymbol *sym, PyObject *const_val);
-extern bool _Py_uop_sym_is_bottom(JitOptSymbol *sym);
-extern int _Py_uop_sym_truthiness(JitOptContext *ctx, JitOptSymbol *sym);
-extern PyTypeObject *_Py_uop_sym_get_type(JitOptSymbol *sym);
-extern bool _Py_uop_sym_is_immortal(JitOptSymbol *sym);
-extern JitOptSymbol *_Py_uop_sym_new_tuple(JitOptContext *ctx, int size, JitOptSymbol **args);
-extern JitOptSymbol *_Py_uop_sym_tuple_getitem(JitOptContext *ctx, JitOptSymbol *sym, int item);
-extern int _Py_uop_sym_tuple_length(JitOptSymbol *sym);
-extern JitOptSymbol *_Py_uop_sym_new_truthiness(JitOptContext *ctx, JitOptSymbol *value, bool truthy);
+
+extern JitOptRef _Py_uop_sym_new_const(JitOptContext *ctx, PyObject *const_val);
+extern JitOptRef _Py_uop_sym_new_null(JitOptContext *ctx);
+extern bool _Py_uop_sym_has_type(JitOptRef sym);
+extern bool _Py_uop_sym_matches_type(JitOptRef sym, PyTypeObject *typ);
+extern bool _Py_uop_sym_matches_type_version(JitOptRef sym, unsigned int version);
+extern void _Py_uop_sym_set_null(JitOptContext *ctx, JitOptRef sym);
+extern void _Py_uop_sym_set_non_null(JitOptContext *ctx, JitOptRef sym);
+extern void _Py_uop_sym_set_type(JitOptContext *ctx, JitOptRef sym, PyTypeObject *typ);
+extern bool _Py_uop_sym_set_type_version(JitOptContext *ctx, JitOptRef sym, unsigned int version);
+extern void _Py_uop_sym_set_const(JitOptContext *ctx, JitOptRef sym, PyObject *const_val);
+extern bool _Py_uop_sym_is_bottom(JitOptRef sym);
+extern int _Py_uop_sym_truthiness(JitOptContext *ctx, JitOptRef sym);
+extern PyTypeObject *_Py_uop_sym_get_type(JitOptRef sym);
+extern JitOptRef _Py_uop_sym_new_tuple(JitOptContext *ctx, int size, JitOptRef *args);
+extern JitOptRef _Py_uop_sym_tuple_getitem(JitOptContext *ctx, JitOptRef sym, int item);
+extern int _Py_uop_sym_tuple_length(JitOptRef sym);
+extern JitOptRef _Py_uop_sym_new_truthiness(JitOptContext *ctx, JitOptRef value, bool truthy);
+extern bool _Py_uop_sym_is_compact_int(JitOptRef sym);
+extern JitOptRef _Py_uop_sym_new_compact_int(JitOptContext *ctx);
+extern void _Py_uop_sym_set_compact_int(JitOptContext *ctx, JitOptRef sym);
extern void _Py_uop_abstractcontext_init(JitOptContext *ctx);
extern void _Py_uop_abstractcontext_fini(JitOptContext *ctx);
@@ -290,7 +343,7 @@ extern _Py_UOpsAbstractFrame *_Py_uop_frame_new(
JitOptContext *ctx,
PyCodeObject *co,
int curr_stackentries,
- JitOptSymbol **args,
+ JitOptRef *args,
int arg_len);
extern int _Py_uop_frame_pop(JitOptContext *ctx);
diff --git a/Include/internal/pycore_pymem.h b/Include/internal/pycore_pymem.h
index 02537bdfef8..e669a30b072 100644
--- a/Include/internal/pycore_pymem.h
+++ b/Include/internal/pycore_pymem.h
@@ -90,16 +90,6 @@ extern int _PyMem_DebugEnabled(void);
// Enqueue a pointer to be freed possibly after some delay.
extern void _PyMem_FreeDelayed(void *ptr);
-// Enqueue an object to be freed possibly after some delay
-#ifdef Py_GIL_DISABLED
-PyAPI_FUNC(void) _PyObject_XDecRefDelayed(PyObject *obj);
-#else
-static inline void _PyObject_XDecRefDelayed(PyObject *obj)
-{
- Py_XDECREF(obj);
-}
-#endif
-
// Periodically process delayed free requests.
extern void _PyMem_ProcessDelayed(PyThreadState *tstate);
diff --git a/Include/internal/pycore_stackref.h b/Include/internal/pycore_stackref.h
index f2ecc30b053..10e7199269e 100644
--- a/Include/internal/pycore_stackref.h
+++ b/Include/internal/pycore_stackref.h
@@ -62,14 +62,15 @@ PyAPI_FUNC(void) _Py_stackref_record_borrow(_PyStackRef ref, const char *filenam
extern void _Py_stackref_associate(PyInterpreterState *interp, PyObject *obj, _PyStackRef ref);
static const _PyStackRef PyStackRef_NULL = { .index = 0 };
+static const _PyStackRef PyStackRef_ERROR = { .index = 2 };
// Use the first 3 even numbers for None, True and False.
// Odd numbers are reserved for (tagged) integers
-#define PyStackRef_None ((_PyStackRef){ .index = 2 } )
-#define PyStackRef_False ((_PyStackRef){ .index = 4 })
-#define PyStackRef_True ((_PyStackRef){ .index = 6 })
+#define PyStackRef_None ((_PyStackRef){ .index = 4 } )
+#define PyStackRef_False ((_PyStackRef){ .index = 6 })
+#define PyStackRef_True ((_PyStackRef){ .index = 8 })
-#define INITIAL_STACKREF_INDEX 8
+#define INITIAL_STACKREF_INDEX 10
static inline int
PyStackRef_IsNull(_PyStackRef ref)
@@ -77,6 +78,19 @@ PyStackRef_IsNull(_PyStackRef ref)
return ref.index == 0;
}
+static inline bool
+PyStackRef_IsError(_PyStackRef ref)
+{
+ return ref.index == 2;
+}
+
+static inline bool
+PyStackRef_IsValid(_PyStackRef ref)
+{
+ /* Invalid values are ERROR and NULL */
+ return !PyStackRef_IsError(ref) && !PyStackRef_IsNull(ref);
+}
+
static inline int
PyStackRef_IsTrue(_PyStackRef ref)
{
@@ -104,6 +118,7 @@ PyStackRef_IsTaggedInt(_PyStackRef ref)
static inline PyObject *
_PyStackRef_AsPyObjectBorrow(_PyStackRef ref, const char *filename, int linenumber)
{
+ assert(!PyStackRef_IsError(ref));
assert(!PyStackRef_IsTaggedInt(ref));
_Py_stackref_record_borrow(ref, filename, linenumber);
return _Py_stackref_get_object(ref);
@@ -155,6 +170,7 @@ _PyStackRef_CLOSE(_PyStackRef ref, const char *filename, int linenumber)
static inline void
_PyStackRef_XCLOSE(_PyStackRef ref, const char *filename, int linenumber)
{
+ assert(!PyStackRef_IsError(ref));
if (PyStackRef_IsNull(ref)) {
return;
}
@@ -165,6 +181,7 @@ _PyStackRef_XCLOSE(_PyStackRef ref, const char *filename, int linenumber)
static inline _PyStackRef
_PyStackRef_DUP(_PyStackRef ref, const char *filename, int linenumber)
{
+ assert(!PyStackRef_IsError(ref));
if (PyStackRef_IsTaggedInt(ref)) {
return ref;
}
@@ -241,9 +258,51 @@ PyStackRef_IsNullOrInt(_PyStackRef ref);
#else
#define Py_INT_TAG 3
+#define Py_TAG_INVALID 2
#define Py_TAG_REFCNT 1
#define Py_TAG_BITS 3
+static const _PyStackRef PyStackRef_ERROR = { .bits = Py_TAG_INVALID };
+
+/* Wrap a pointer in a stack ref.
+ * The resulting stack reference is not safe and should only be used
+ * in the interpreter to pass values from one uop to another.
+ * The GC should never see one of these stack refs. */
+static inline _PyStackRef
+PyStackRef_Wrap(void *ptr)
+{
+ assert(ptr != NULL);
+#ifdef Py_DEBUG
+ return (_PyStackRef){ .bits = ((uintptr_t)ptr) | Py_TAG_INVALID };
+#else
+ return (_PyStackRef){ .bits = (uintptr_t)ptr };
+#endif
+}
+
+static inline void *
+PyStackRef_Unwrap(_PyStackRef ref)
+{
+#ifdef Py_DEBUG
+ assert ((ref.bits & Py_TAG_BITS) == Py_TAG_INVALID);
+ return (void *)(ref.bits & ~Py_TAG_BITS);
+#else
+ return (void *)(ref.bits);
+#endif
+}
+
+static inline bool
+PyStackRef_IsError(_PyStackRef ref)
+{
+ return ref.bits == Py_TAG_INVALID;
+}
+
+static inline bool
+PyStackRef_IsValid(_PyStackRef ref)
+{
+ /* Invalid values are ERROR and NULL */
+ return ref.bits >= Py_INT_TAG;
+}
+
static inline bool
PyStackRef_IsTaggedInt(_PyStackRef i)
{
@@ -284,6 +343,7 @@ PyStackRef_IncrementTaggedIntNoOverflow(_PyStackRef ref)
static const _PyStackRef PyStackRef_NULL = { .bits = Py_TAG_DEFERRED};
+
#define PyStackRef_IsNull(stackref) ((stackref).bits == PyStackRef_NULL.bits)
#define PyStackRef_True ((_PyStackRef){.bits = ((uintptr_t)&_Py_TrueStruct) | Py_TAG_DEFERRED })
#define PyStackRef_False ((_PyStackRef){.bits = ((uintptr_t)&_Py_FalseStruct) | Py_TAG_DEFERRED })
diff --git a/Include/internal/pycore_uop_ids.h b/Include/internal/pycore_uop_ids.h
index 2b845527cf2..a9432401525 100644
--- a/Include/internal/pycore_uop_ids.h
+++ b/Include/internal/pycore_uop_ids.h
@@ -13,22 +13,25 @@ extern "C" {
#define _SET_IP 301
#define _BINARY_OP 302
#define _BINARY_OP_ADD_FLOAT 303
-#define _BINARY_OP_ADD_INT 304
-#define _BINARY_OP_ADD_UNICODE 305
-#define _BINARY_OP_EXTEND 306
-#define _BINARY_OP_INPLACE_ADD_UNICODE 307
-#define _BINARY_OP_MULTIPLY_FLOAT 308
-#define _BINARY_OP_MULTIPLY_INT 309
-#define _BINARY_OP_SUBSCR_CHECK_FUNC 310
-#define _BINARY_OP_SUBSCR_DICT 311
-#define _BINARY_OP_SUBSCR_INIT_CALL 312
-#define _BINARY_OP_SUBSCR_LIST_INT 313
-#define _BINARY_OP_SUBSCR_LIST_SLICE 314
-#define _BINARY_OP_SUBSCR_STR_INT 315
-#define _BINARY_OP_SUBSCR_TUPLE_INT 316
-#define _BINARY_OP_SUBTRACT_FLOAT 317
-#define _BINARY_OP_SUBTRACT_INT 318
-#define _BINARY_SLICE 319
+#define _BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS 304
+#define _BINARY_OP_ADD_INT 305
+#define _BINARY_OP_ADD_UNICODE 306
+#define _BINARY_OP_EXTEND 307
+#define _BINARY_OP_INPLACE_ADD_UNICODE 308
+#define _BINARY_OP_MULTIPLY_FLOAT 309
+#define _BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS 310
+#define _BINARY_OP_MULTIPLY_INT 311
+#define _BINARY_OP_SUBSCR_CHECK_FUNC 312
+#define _BINARY_OP_SUBSCR_DICT 313
+#define _BINARY_OP_SUBSCR_INIT_CALL 314
+#define _BINARY_OP_SUBSCR_LIST_INT 315
+#define _BINARY_OP_SUBSCR_LIST_SLICE 316
+#define _BINARY_OP_SUBSCR_STR_INT 317
+#define _BINARY_OP_SUBSCR_TUPLE_INT 318
+#define _BINARY_OP_SUBTRACT_FLOAT 319
+#define _BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS 320
+#define _BINARY_OP_SUBTRACT_INT 321
+#define _BINARY_SLICE 322
#define _BUILD_INTERPOLATION BUILD_INTERPOLATION
#define _BUILD_LIST BUILD_LIST
#define _BUILD_MAP BUILD_MAP
@@ -37,135 +40,140 @@ extern "C" {
#define _BUILD_STRING BUILD_STRING
#define _BUILD_TEMPLATE BUILD_TEMPLATE
#define _BUILD_TUPLE BUILD_TUPLE
-#define _CALL_BUILTIN_CLASS 320
-#define _CALL_BUILTIN_FAST 321
-#define _CALL_BUILTIN_FAST_WITH_KEYWORDS 322
-#define _CALL_BUILTIN_O 323
+#define _CALL_BUILTIN_CLASS 323
+#define _CALL_BUILTIN_FAST 324
+#define _CALL_BUILTIN_FAST_WITH_KEYWORDS 325
+#define _CALL_BUILTIN_O 326
#define _CALL_INTRINSIC_1 CALL_INTRINSIC_1
#define _CALL_INTRINSIC_2 CALL_INTRINSIC_2
-#define _CALL_ISINSTANCE 324
-#define _CALL_KW_NON_PY 325
-#define _CALL_LEN 326
-#define _CALL_LIST_APPEND 327
-#define _CALL_METHOD_DESCRIPTOR_FAST 328
-#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 329
-#define _CALL_METHOD_DESCRIPTOR_NOARGS 330
-#define _CALL_METHOD_DESCRIPTOR_O 331
-#define _CALL_NON_PY_GENERAL 332
-#define _CALL_STR_1 333
-#define _CALL_TUPLE_1 334
-#define _CALL_TYPE_1 335
-#define _CHECK_AND_ALLOCATE_OBJECT 336
-#define _CHECK_ATTR_CLASS 337
-#define _CHECK_ATTR_METHOD_LAZY_DICT 338
-#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS 339
+#define _CALL_ISINSTANCE 327
+#define _CALL_KW_NON_PY 328
+#define _CALL_LEN 329
+#define _CALL_LIST_APPEND 330
+#define _CALL_METHOD_DESCRIPTOR_FAST 331
+#define _CALL_METHOD_DESCRIPTOR_FAST_WITH_KEYWORDS 332
+#define _CALL_METHOD_DESCRIPTOR_NOARGS 333
+#define _CALL_METHOD_DESCRIPTOR_O 334
+#define _CALL_NON_PY_GENERAL 335
+#define _CALL_STR_1 336
+#define _CALL_TUPLE_1 337
+#define _CALL_TYPE_1 338
+#define _CHECK_AND_ALLOCATE_OBJECT 339
+#define _CHECK_ATTR_CLASS 340
+#define _CHECK_ATTR_METHOD_LAZY_DICT 341
+#define _CHECK_CALL_BOUND_METHOD_EXACT_ARGS 342
#define _CHECK_EG_MATCH CHECK_EG_MATCH
#define _CHECK_EXC_MATCH CHECK_EXC_MATCH
-#define _CHECK_FUNCTION 340
-#define _CHECK_FUNCTION_EXACT_ARGS 341
-#define _CHECK_FUNCTION_VERSION 342
-#define _CHECK_FUNCTION_VERSION_INLINE 343
-#define _CHECK_FUNCTION_VERSION_KW 344
-#define _CHECK_IS_NOT_PY_CALLABLE 345
-#define _CHECK_IS_NOT_PY_CALLABLE_KW 346
-#define _CHECK_MANAGED_OBJECT_HAS_VALUES 347
-#define _CHECK_METHOD_VERSION 348
-#define _CHECK_METHOD_VERSION_KW 349
-#define _CHECK_PEP_523 350
-#define _CHECK_PERIODIC 351
-#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM 352
-#define _CHECK_RECURSION_REMAINING 353
-#define _CHECK_STACK_SPACE 354
-#define _CHECK_STACK_SPACE_OPERAND 355
-#define _CHECK_VALIDITY 356
-#define _COMPARE_OP 357
-#define _COMPARE_OP_FLOAT 358
-#define _COMPARE_OP_INT 359
-#define _COMPARE_OP_STR 360
-#define _CONTAINS_OP 361
-#define _CONTAINS_OP_DICT 362
-#define _CONTAINS_OP_SET 363
+#define _CHECK_FUNCTION 343
+#define _CHECK_FUNCTION_EXACT_ARGS 344
+#define _CHECK_FUNCTION_VERSION 345
+#define _CHECK_FUNCTION_VERSION_INLINE 346
+#define _CHECK_FUNCTION_VERSION_KW 347
+#define _CHECK_IS_NOT_PY_CALLABLE 348
+#define _CHECK_IS_NOT_PY_CALLABLE_KW 349
+#define _CHECK_MANAGED_OBJECT_HAS_VALUES 350
+#define _CHECK_METHOD_VERSION 351
+#define _CHECK_METHOD_VERSION_KW 352
+#define _CHECK_PEP_523 353
+#define _CHECK_PERIODIC 354
+#define _CHECK_PERIODIC_IF_NOT_YIELD_FROM 355
+#define _CHECK_RECURSION_REMAINING 356
+#define _CHECK_STACK_SPACE 357
+#define _CHECK_STACK_SPACE_OPERAND 358
+#define _CHECK_VALIDITY 359
+#define _COMPARE_OP 360
+#define _COMPARE_OP_FLOAT 361
+#define _COMPARE_OP_INT 362
+#define _COMPARE_OP_STR 363
+#define _CONTAINS_OP 364
+#define _CONTAINS_OP_DICT 365
+#define _CONTAINS_OP_SET 366
#define _CONVERT_VALUE CONVERT_VALUE
-#define _COPY COPY
+#define _COPY 367
+#define _COPY_1 368
+#define _COPY_2 369
+#define _COPY_3 370
#define _COPY_FREE_VARS COPY_FREE_VARS
-#define _CREATE_INIT_FRAME 364
+#define _CREATE_INIT_FRAME 371
#define _DELETE_ATTR DELETE_ATTR
#define _DELETE_DEREF DELETE_DEREF
#define _DELETE_FAST DELETE_FAST
#define _DELETE_GLOBAL DELETE_GLOBAL
#define _DELETE_NAME DELETE_NAME
#define _DELETE_SUBSCR DELETE_SUBSCR
-#define _DEOPT 365
+#define _DEOPT 372
#define _DICT_MERGE DICT_MERGE
#define _DICT_UPDATE DICT_UPDATE
-#define _DO_CALL 366
-#define _DO_CALL_FUNCTION_EX 367
-#define _DO_CALL_KW 368
+#define _DO_CALL 373
+#define _DO_CALL_FUNCTION_EX 374
+#define _DO_CALL_KW 375
#define _END_FOR END_FOR
#define _END_SEND END_SEND
-#define _ERROR_POP_N 369
+#define _ERROR_POP_N 376
#define _EXIT_INIT_CHECK EXIT_INIT_CHECK
-#define _EXPAND_METHOD 370
-#define _EXPAND_METHOD_KW 371
-#define _FATAL_ERROR 372
+#define _EXPAND_METHOD 377
+#define _EXPAND_METHOD_KW 378
+#define _FATAL_ERROR 379
#define _FORMAT_SIMPLE FORMAT_SIMPLE
#define _FORMAT_WITH_SPEC FORMAT_WITH_SPEC
-#define _FOR_ITER 373
-#define _FOR_ITER_GEN_FRAME 374
-#define _FOR_ITER_TIER_TWO 375
+#define _FOR_ITER 380
+#define _FOR_ITER_GEN_FRAME 381
+#define _FOR_ITER_TIER_TWO 382
#define _GET_AITER GET_AITER
#define _GET_ANEXT GET_ANEXT
#define _GET_AWAITABLE GET_AWAITABLE
#define _GET_ITER GET_ITER
#define _GET_LEN GET_LEN
#define _GET_YIELD_FROM_ITER GET_YIELD_FROM_ITER
-#define _GUARD_BINARY_OP_EXTEND 376
-#define _GUARD_CALLABLE_ISINSTANCE 377
-#define _GUARD_CALLABLE_LEN 378
-#define _GUARD_CALLABLE_LIST_APPEND 379
-#define _GUARD_CALLABLE_STR_1 380
-#define _GUARD_CALLABLE_TUPLE_1 381
-#define _GUARD_CALLABLE_TYPE_1 382
-#define _GUARD_DORV_NO_DICT 383
-#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 384
-#define _GUARD_GLOBALS_VERSION 385
-#define _GUARD_IS_FALSE_POP 386
-#define _GUARD_IS_NONE_POP 387
-#define _GUARD_IS_NOT_NONE_POP 388
-#define _GUARD_IS_TRUE_POP 389
-#define _GUARD_KEYS_VERSION 390
-#define _GUARD_NOS_DICT 391
-#define _GUARD_NOS_FLOAT 392
-#define _GUARD_NOS_INT 393
-#define _GUARD_NOS_LIST 394
-#define _GUARD_NOS_NOT_NULL 395
-#define _GUARD_NOS_NULL 396
-#define _GUARD_NOS_TUPLE 397
-#define _GUARD_NOS_UNICODE 398
-#define _GUARD_NOT_EXHAUSTED_LIST 399
-#define _GUARD_NOT_EXHAUSTED_RANGE 400
-#define _GUARD_NOT_EXHAUSTED_TUPLE 401
-#define _GUARD_THIRD_NULL 402
-#define _GUARD_TOS_ANY_SET 403
-#define _GUARD_TOS_DICT 404
-#define _GUARD_TOS_FLOAT 405
-#define _GUARD_TOS_INT 406
-#define _GUARD_TOS_LIST 407
-#define _GUARD_TOS_SLICE 408
-#define _GUARD_TOS_TUPLE 409
-#define _GUARD_TOS_UNICODE 410
-#define _GUARD_TYPE_VERSION 411
-#define _GUARD_TYPE_VERSION_AND_LOCK 412
+#define _GUARD_BINARY_OP_EXTEND 383
+#define _GUARD_CALLABLE_ISINSTANCE 384
+#define _GUARD_CALLABLE_LEN 385
+#define _GUARD_CALLABLE_LIST_APPEND 386
+#define _GUARD_CALLABLE_STR_1 387
+#define _GUARD_CALLABLE_TUPLE_1 388
+#define _GUARD_CALLABLE_TYPE_1 389
+#define _GUARD_DORV_NO_DICT 390
+#define _GUARD_DORV_VALUES_INST_ATTR_FROM_DICT 391
+#define _GUARD_GLOBALS_VERSION 392
+#define _GUARD_IS_FALSE_POP 393
+#define _GUARD_IS_NONE_POP 394
+#define _GUARD_IS_NOT_NONE_POP 395
+#define _GUARD_IS_TRUE_POP 396
+#define _GUARD_KEYS_VERSION 397
+#define _GUARD_NOS_DICT 398
+#define _GUARD_NOS_FLOAT 399
+#define _GUARD_NOS_INT 400
+#define _GUARD_NOS_LIST 401
+#define _GUARD_NOS_NOT_NULL 402
+#define _GUARD_NOS_NULL 403
+#define _GUARD_NOS_OVERFLOWED 404
+#define _GUARD_NOS_TUPLE 405
+#define _GUARD_NOS_UNICODE 406
+#define _GUARD_NOT_EXHAUSTED_LIST 407
+#define _GUARD_NOT_EXHAUSTED_RANGE 408
+#define _GUARD_NOT_EXHAUSTED_TUPLE 409
+#define _GUARD_THIRD_NULL 410
+#define _GUARD_TOS_ANY_SET 411
+#define _GUARD_TOS_DICT 412
+#define _GUARD_TOS_FLOAT 413
+#define _GUARD_TOS_INT 414
+#define _GUARD_TOS_LIST 415
+#define _GUARD_TOS_OVERFLOWED 416
+#define _GUARD_TOS_SLICE 417
+#define _GUARD_TOS_TUPLE 418
+#define _GUARD_TOS_UNICODE 419
+#define _GUARD_TYPE_VERSION 420
+#define _GUARD_TYPE_VERSION_AND_LOCK 421
#define _IMPORT_FROM IMPORT_FROM
#define _IMPORT_NAME IMPORT_NAME
-#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 413
-#define _INIT_CALL_PY_EXACT_ARGS 414
-#define _INIT_CALL_PY_EXACT_ARGS_0 415
-#define _INIT_CALL_PY_EXACT_ARGS_1 416
-#define _INIT_CALL_PY_EXACT_ARGS_2 417
-#define _INIT_CALL_PY_EXACT_ARGS_3 418
-#define _INIT_CALL_PY_EXACT_ARGS_4 419
-#define _INSERT_NULL 420
+#define _INIT_CALL_BOUND_METHOD_EXACT_ARGS 422
+#define _INIT_CALL_PY_EXACT_ARGS 423
+#define _INIT_CALL_PY_EXACT_ARGS_0 424
+#define _INIT_CALL_PY_EXACT_ARGS_1 425
+#define _INIT_CALL_PY_EXACT_ARGS_2 426
+#define _INIT_CALL_PY_EXACT_ARGS_3 427
+#define _INIT_CALL_PY_EXACT_ARGS_4 428
+#define _INSERT_NULL 429
#define _INSTRUMENTED_FOR_ITER INSTRUMENTED_FOR_ITER
#define _INSTRUMENTED_INSTRUCTION INSTRUMENTED_INSTRUCTION
#define _INSTRUMENTED_JUMP_FORWARD INSTRUMENTED_JUMP_FORWARD
@@ -175,171 +183,177 @@ extern "C" {
#define _INSTRUMENTED_POP_JUMP_IF_NONE INSTRUMENTED_POP_JUMP_IF_NONE
#define _INSTRUMENTED_POP_JUMP_IF_NOT_NONE INSTRUMENTED_POP_JUMP_IF_NOT_NONE
#define _INSTRUMENTED_POP_JUMP_IF_TRUE INSTRUMENTED_POP_JUMP_IF_TRUE
-#define _IS_NONE 421
+#define _IS_NONE 430
#define _IS_OP IS_OP
-#define _ITER_CHECK_LIST 422
-#define _ITER_CHECK_RANGE 423
-#define _ITER_CHECK_TUPLE 424
-#define _ITER_JUMP_LIST 425
-#define _ITER_JUMP_RANGE 426
-#define _ITER_JUMP_TUPLE 427
-#define _ITER_NEXT_LIST 428
-#define _ITER_NEXT_LIST_TIER_TWO 429
-#define _ITER_NEXT_RANGE 430
-#define _ITER_NEXT_TUPLE 431
-#define _JUMP_TO_TOP 432
+#define _ITER_CHECK_LIST 431
+#define _ITER_CHECK_RANGE 432
+#define _ITER_CHECK_TUPLE 433
+#define _ITER_JUMP_LIST 434
+#define _ITER_JUMP_RANGE 435
+#define _ITER_JUMP_TUPLE 436
+#define _ITER_NEXT_LIST 437
+#define _ITER_NEXT_LIST_TIER_TWO 438
+#define _ITER_NEXT_RANGE 439
+#define _ITER_NEXT_TUPLE 440
+#define _JUMP_TO_TOP 441
#define _LIST_APPEND LIST_APPEND
#define _LIST_EXTEND LIST_EXTEND
-#define _LOAD_ATTR 433
-#define _LOAD_ATTR_CLASS 434
+#define _LOAD_ATTR 442
+#define _LOAD_ATTR_CLASS 443
#define _LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN LOAD_ATTR_GETATTRIBUTE_OVERRIDDEN
-#define _LOAD_ATTR_INSTANCE_VALUE 435
-#define _LOAD_ATTR_METHOD_LAZY_DICT 436
-#define _LOAD_ATTR_METHOD_NO_DICT 437
-#define _LOAD_ATTR_METHOD_WITH_VALUES 438
-#define _LOAD_ATTR_MODULE 439
-#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 440
-#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 441
-#define _LOAD_ATTR_PROPERTY_FRAME 442
-#define _LOAD_ATTR_SLOT 443
-#define _LOAD_ATTR_WITH_HINT 444
+#define _LOAD_ATTR_INSTANCE_VALUE 444
+#define _LOAD_ATTR_METHOD_LAZY_DICT 445
+#define _LOAD_ATTR_METHOD_NO_DICT 446
+#define _LOAD_ATTR_METHOD_WITH_VALUES 447
+#define _LOAD_ATTR_MODULE 448
+#define _LOAD_ATTR_NONDESCRIPTOR_NO_DICT 449
+#define _LOAD_ATTR_NONDESCRIPTOR_WITH_VALUES 450
+#define _LOAD_ATTR_PROPERTY_FRAME 451
+#define _LOAD_ATTR_SLOT 452
+#define _LOAD_ATTR_WITH_HINT 453
#define _LOAD_BUILD_CLASS LOAD_BUILD_CLASS
-#define _LOAD_BYTECODE 445
+#define _LOAD_BYTECODE 454
#define _LOAD_COMMON_CONSTANT LOAD_COMMON_CONSTANT
#define _LOAD_CONST LOAD_CONST
-#define _LOAD_CONST_INLINE 446
-#define _LOAD_CONST_INLINE_BORROW 447
-#define _LOAD_CONST_UNDER_INLINE 448
-#define _LOAD_CONST_UNDER_INLINE_BORROW 449
+#define _LOAD_CONST_INLINE 455
+#define _LOAD_CONST_INLINE_BORROW 456
+#define _LOAD_CONST_UNDER_INLINE 457
+#define _LOAD_CONST_UNDER_INLINE_BORROW 458
#define _LOAD_DEREF LOAD_DEREF
-#define _LOAD_FAST 450
-#define _LOAD_FAST_0 451
-#define _LOAD_FAST_1 452
-#define _LOAD_FAST_2 453
-#define _LOAD_FAST_3 454
-#define _LOAD_FAST_4 455
-#define _LOAD_FAST_5 456
-#define _LOAD_FAST_6 457
-#define _LOAD_FAST_7 458
+#define _LOAD_FAST 459
+#define _LOAD_FAST_0 460
+#define _LOAD_FAST_1 461
+#define _LOAD_FAST_2 462
+#define _LOAD_FAST_3 463
+#define _LOAD_FAST_4 464
+#define _LOAD_FAST_5 465
+#define _LOAD_FAST_6 466
+#define _LOAD_FAST_7 467
#define _LOAD_FAST_AND_CLEAR LOAD_FAST_AND_CLEAR
-#define _LOAD_FAST_BORROW 459
-#define _LOAD_FAST_BORROW_0 460
-#define _LOAD_FAST_BORROW_1 461
-#define _LOAD_FAST_BORROW_2 462
-#define _LOAD_FAST_BORROW_3 463
-#define _LOAD_FAST_BORROW_4 464
-#define _LOAD_FAST_BORROW_5 465
-#define _LOAD_FAST_BORROW_6 466
-#define _LOAD_FAST_BORROW_7 467
+#define _LOAD_FAST_BORROW 468
+#define _LOAD_FAST_BORROW_0 469
+#define _LOAD_FAST_BORROW_1 470
+#define _LOAD_FAST_BORROW_2 471
+#define _LOAD_FAST_BORROW_3 472
+#define _LOAD_FAST_BORROW_4 473
+#define _LOAD_FAST_BORROW_5 474
+#define _LOAD_FAST_BORROW_6 475
+#define _LOAD_FAST_BORROW_7 476
#define _LOAD_FAST_BORROW_LOAD_FAST_BORROW LOAD_FAST_BORROW_LOAD_FAST_BORROW
#define _LOAD_FAST_CHECK LOAD_FAST_CHECK
#define _LOAD_FAST_LOAD_FAST LOAD_FAST_LOAD_FAST
#define _LOAD_FROM_DICT_OR_DEREF LOAD_FROM_DICT_OR_DEREF
#define _LOAD_FROM_DICT_OR_GLOBALS LOAD_FROM_DICT_OR_GLOBALS
-#define _LOAD_GLOBAL 468
-#define _LOAD_GLOBAL_BUILTINS 469
-#define _LOAD_GLOBAL_MODULE 470
+#define _LOAD_GLOBAL 477
+#define _LOAD_GLOBAL_BUILTINS 478
+#define _LOAD_GLOBAL_MODULE 479
#define _LOAD_LOCALS LOAD_LOCALS
#define _LOAD_NAME LOAD_NAME
-#define _LOAD_SMALL_INT 471
-#define _LOAD_SMALL_INT_0 472
-#define _LOAD_SMALL_INT_1 473
-#define _LOAD_SMALL_INT_2 474
-#define _LOAD_SMALL_INT_3 475
-#define _LOAD_SPECIAL 476
+#define _LOAD_SMALL_INT 480
+#define _LOAD_SMALL_INT_0 481
+#define _LOAD_SMALL_INT_1 482
+#define _LOAD_SMALL_INT_2 483
+#define _LOAD_SMALL_INT_3 484
+#define _LOAD_SPECIAL 485
#define _LOAD_SUPER_ATTR_ATTR LOAD_SUPER_ATTR_ATTR
#define _LOAD_SUPER_ATTR_METHOD LOAD_SUPER_ATTR_METHOD
-#define _MAKE_CALLARGS_A_TUPLE 477
+#define _MAKE_CALLARGS_A_TUPLE 486
#define _MAKE_CELL MAKE_CELL
#define _MAKE_FUNCTION MAKE_FUNCTION
-#define _MAKE_WARM 478
+#define _MAKE_WARM 487
#define _MAP_ADD MAP_ADD
#define _MATCH_CLASS MATCH_CLASS
#define _MATCH_KEYS MATCH_KEYS
#define _MATCH_MAPPING MATCH_MAPPING
#define _MATCH_SEQUENCE MATCH_SEQUENCE
-#define _MAYBE_EXPAND_METHOD 479
-#define _MAYBE_EXPAND_METHOD_KW 480
-#define _MONITOR_CALL 481
-#define _MONITOR_CALL_KW 482
-#define _MONITOR_JUMP_BACKWARD 483
-#define _MONITOR_RESUME 484
+#define _MAYBE_EXPAND_METHOD 488
+#define _MAYBE_EXPAND_METHOD_KW 489
+#define _MONITOR_CALL 490
+#define _MONITOR_CALL_KW 491
+#define _MONITOR_JUMP_BACKWARD 492
+#define _MONITOR_RESUME 493
#define _NOP NOP
-#define _POP_CALL 485
-#define _POP_CALL_LOAD_CONST_INLINE_BORROW 486
-#define _POP_CALL_ONE 487
-#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 488
-#define _POP_CALL_TWO 489
-#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 490
+#define _POP_CALL 494
+#define _POP_CALL_LOAD_CONST_INLINE_BORROW 495
+#define _POP_CALL_ONE 496
+#define _POP_CALL_ONE_LOAD_CONST_INLINE_BORROW 497
+#define _POP_CALL_TWO 498
+#define _POP_CALL_TWO_LOAD_CONST_INLINE_BORROW 499
#define _POP_EXCEPT POP_EXCEPT
#define _POP_ITER POP_ITER
-#define _POP_JUMP_IF_FALSE 491
-#define _POP_JUMP_IF_TRUE 492
+#define _POP_JUMP_IF_FALSE 500
+#define _POP_JUMP_IF_TRUE 501
#define _POP_TOP POP_TOP
-#define _POP_TOP_LOAD_CONST_INLINE 493
-#define _POP_TOP_LOAD_CONST_INLINE_BORROW 494
-#define _POP_TWO 495
-#define _POP_TWO_LOAD_CONST_INLINE_BORROW 496
+#define _POP_TOP_FLOAT 502
+#define _POP_TOP_INT 503
+#define _POP_TOP_LOAD_CONST_INLINE 504
+#define _POP_TOP_LOAD_CONST_INLINE_BORROW 505
+#define _POP_TOP_NOP 506
+#define _POP_TOP_UNICODE 507
+#define _POP_TWO 508
+#define _POP_TWO_LOAD_CONST_INLINE_BORROW 509
#define _PUSH_EXC_INFO PUSH_EXC_INFO
-#define _PUSH_FRAME 497
+#define _PUSH_FRAME 510
#define _PUSH_NULL PUSH_NULL
-#define _PUSH_NULL_CONDITIONAL 498
-#define _PY_FRAME_GENERAL 499
-#define _PY_FRAME_KW 500
-#define _QUICKEN_RESUME 501
-#define _REPLACE_WITH_TRUE 502
+#define _PUSH_NULL_CONDITIONAL 511
+#define _PY_FRAME_GENERAL 512
+#define _PY_FRAME_KW 513
+#define _QUICKEN_RESUME 514
+#define _REPLACE_WITH_TRUE 515
#define _RESUME_CHECK RESUME_CHECK
#define _RETURN_GENERATOR RETURN_GENERATOR
#define _RETURN_VALUE RETURN_VALUE
-#define _SAVE_RETURN_OFFSET 503
-#define _SEND 504
-#define _SEND_GEN_FRAME 505
+#define _SAVE_RETURN_OFFSET 516
+#define _SEND 517
+#define _SEND_GEN_FRAME 518
#define _SETUP_ANNOTATIONS SETUP_ANNOTATIONS
#define _SET_ADD SET_ADD
#define _SET_FUNCTION_ATTRIBUTE SET_FUNCTION_ATTRIBUTE
#define _SET_UPDATE SET_UPDATE
-#define _START_EXECUTOR 506
-#define _STORE_ATTR 507
-#define _STORE_ATTR_INSTANCE_VALUE 508
-#define _STORE_ATTR_SLOT 509
-#define _STORE_ATTR_WITH_HINT 510
+#define _START_EXECUTOR 519
+#define _STORE_ATTR 520
+#define _STORE_ATTR_INSTANCE_VALUE 521
+#define _STORE_ATTR_SLOT 522
+#define _STORE_ATTR_WITH_HINT 523
#define _STORE_DEREF STORE_DEREF
-#define _STORE_FAST 511
-#define _STORE_FAST_0 512
-#define _STORE_FAST_1 513
-#define _STORE_FAST_2 514
-#define _STORE_FAST_3 515
-#define _STORE_FAST_4 516
-#define _STORE_FAST_5 517
-#define _STORE_FAST_6 518
-#define _STORE_FAST_7 519
+#define _STORE_FAST 524
+#define _STORE_FAST_0 525
+#define _STORE_FAST_1 526
+#define _STORE_FAST_2 527
+#define _STORE_FAST_3 528
+#define _STORE_FAST_4 529
+#define _STORE_FAST_5 530
+#define _STORE_FAST_6 531
+#define _STORE_FAST_7 532
#define _STORE_FAST_LOAD_FAST STORE_FAST_LOAD_FAST
#define _STORE_FAST_STORE_FAST STORE_FAST_STORE_FAST
#define _STORE_GLOBAL STORE_GLOBAL
#define _STORE_NAME STORE_NAME
-#define _STORE_SLICE 520
-#define _STORE_SUBSCR 521
-#define _STORE_SUBSCR_DICT 522
-#define _STORE_SUBSCR_LIST_INT 523
-#define _SWAP SWAP
-#define _TIER2_RESUME_CHECK 524
-#define _TO_BOOL 525
+#define _STORE_SLICE 533
+#define _STORE_SUBSCR 534
+#define _STORE_SUBSCR_DICT 535
+#define _STORE_SUBSCR_LIST_INT 536
+#define _SWAP 537
+#define _SWAP_2 538
+#define _SWAP_3 539
+#define _TIER2_RESUME_CHECK 540
+#define _TO_BOOL 541
#define _TO_BOOL_BOOL TO_BOOL_BOOL
#define _TO_BOOL_INT TO_BOOL_INT
-#define _TO_BOOL_LIST 526
+#define _TO_BOOL_LIST 542
#define _TO_BOOL_NONE TO_BOOL_NONE
-#define _TO_BOOL_STR 527
+#define _TO_BOOL_STR 543
#define _UNARY_INVERT UNARY_INVERT
#define _UNARY_NEGATIVE UNARY_NEGATIVE
#define _UNARY_NOT UNARY_NOT
#define _UNPACK_EX UNPACK_EX
-#define _UNPACK_SEQUENCE 528
-#define _UNPACK_SEQUENCE_LIST 529
-#define _UNPACK_SEQUENCE_TUPLE 530
-#define _UNPACK_SEQUENCE_TWO_TUPLE 531
+#define _UNPACK_SEQUENCE 544
+#define _UNPACK_SEQUENCE_LIST 545
+#define _UNPACK_SEQUENCE_TUPLE 546
+#define _UNPACK_SEQUENCE_TWO_TUPLE 547
#define _WITH_EXCEPT_START WITH_EXCEPT_START
#define _YIELD_VALUE YIELD_VALUE
-#define MAX_UOP_ID 531
+#define MAX_UOP_ID 547
#ifdef __cplusplus
}
diff --git a/Include/internal/pycore_uop_metadata.h b/Include/internal/pycore_uop_metadata.h
index b08909e72c4..52cbc2fffe4 100644
--- a/Include/internal/pycore_uop_metadata.h
+++ b/Include/internal/pycore_uop_metadata.h
@@ -12,7 +12,8 @@ extern "C" {
#include <stdint.h>
#include "pycore_uop_ids.h"
extern const uint16_t _PyUop_Flags[MAX_UOP_ID+1];
-extern const uint8_t _PyUop_Replication[MAX_UOP_ID+1];
+typedef struct _rep_range { uint8_t start; uint8_t stop; } ReplicationRange;
+extern const ReplicationRange _PyUop_Replication[MAX_UOP_ID+1];
extern const char * const _PyOpcode_uop_name[MAX_UOP_ID+1];
extern int _PyUop_num_popped(int opcode, int oparg);
@@ -63,6 +64,10 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_STORE_FAST_LOAD_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ESCAPES_FLAG,
[_STORE_FAST_STORE_FAST] = HAS_ARG_FLAG | HAS_LOCAL_FLAG | HAS_ESCAPES_FLAG,
[_POP_TOP] = HAS_ESCAPES_FLAG | HAS_PURE_FLAG,
+ [_POP_TOP_NOP] = 0,
+ [_POP_TOP_INT] = 0,
+ [_POP_TOP_FLOAT] = 0,
+ [_POP_TOP_UNICODE] = 0,
[_POP_TWO] = HAS_ESCAPES_FLAG,
[_PUSH_NULL] = HAS_PURE_FLAG,
[_END_FOR] = HAS_ESCAPES_FLAG | HAS_NO_SAVE_IP_FLAG,
@@ -85,14 +90,19 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_UNARY_INVERT] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_GUARD_NOS_INT] = HAS_EXIT_FLAG,
[_GUARD_TOS_INT] = HAS_EXIT_FLAG,
- [_BINARY_OP_MULTIPLY_INT] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_PURE_FLAG,
- [_BINARY_OP_ADD_INT] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_PURE_FLAG,
- [_BINARY_OP_SUBTRACT_INT] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG | HAS_PURE_FLAG,
+ [_GUARD_NOS_OVERFLOWED] = HAS_EXIT_FLAG,
+ [_GUARD_TOS_OVERFLOWED] = HAS_EXIT_FLAG,
+ [_BINARY_OP_MULTIPLY_INT] = HAS_EXIT_FLAG | HAS_PURE_FLAG,
+ [_BINARY_OP_ADD_INT] = HAS_EXIT_FLAG | HAS_PURE_FLAG,
+ [_BINARY_OP_SUBTRACT_INT] = HAS_EXIT_FLAG | HAS_PURE_FLAG,
[_GUARD_NOS_FLOAT] = HAS_EXIT_FLAG,
[_GUARD_TOS_FLOAT] = HAS_EXIT_FLAG,
[_BINARY_OP_MULTIPLY_FLOAT] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
[_BINARY_OP_ADD_FLOAT] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
[_BINARY_OP_SUBTRACT_FLOAT] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
+ [_BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
+ [_BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
+ [_BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
[_BINARY_OP_ADD_UNICODE] = HAS_ERROR_FLAG | HAS_PURE_FLAG,
[_BINARY_OP_INPLACE_ADD_UNICODE] = HAS_LOCAL_FLAG | HAS_DEOPT_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_GUARD_BINARY_OP_EXTEND] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
@@ -184,7 +194,7 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_STORE_ATTR_SLOT] = HAS_DEOPT_FLAG | HAS_ESCAPES_FLAG,
[_COMPARE_OP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_COMPARE_OP_FLOAT] = HAS_ARG_FLAG,
- [_COMPARE_OP_INT] = HAS_ARG_FLAG | HAS_DEOPT_FLAG,
+ [_COMPARE_OP_INT] = HAS_ARG_FLAG,
[_COMPARE_OP_STR] = HAS_ARG_FLAG,
[_IS_OP] = HAS_ARG_FLAG | HAS_ESCAPES_FLAG,
[_CONTAINS_OP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
@@ -288,8 +298,13 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_CONVERT_VALUE] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_FORMAT_SIMPLE] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
[_FORMAT_WITH_SPEC] = HAS_ERROR_FLAG | HAS_ESCAPES_FLAG,
+ [_COPY_1] = HAS_PURE_FLAG,
+ [_COPY_2] = HAS_PURE_FLAG,
+ [_COPY_3] = HAS_PURE_FLAG,
[_COPY] = HAS_ARG_FLAG | HAS_PURE_FLAG,
[_BINARY_OP] = HAS_ARG_FLAG | HAS_ERROR_FLAG | HAS_ERROR_NO_POP_FLAG | HAS_ESCAPES_FLAG,
+ [_SWAP_2] = HAS_PURE_FLAG,
+ [_SWAP_3] = HAS_PURE_FLAG,
[_SWAP] = HAS_ARG_FLAG | HAS_PURE_FLAG,
[_GUARD_IS_TRUE_POP] = HAS_EXIT_FLAG,
[_GUARD_IS_FALSE_POP] = HAS_EXIT_FLAG,
@@ -323,22 +338,26 @@ const uint16_t _PyUop_Flags[MAX_UOP_ID+1] = {
[_TIER2_RESUME_CHECK] = HAS_DEOPT_FLAG,
};
-const uint8_t _PyUop_Replication[MAX_UOP_ID+1] = {
- [_LOAD_FAST] = 8,
- [_LOAD_FAST_BORROW] = 8,
- [_LOAD_SMALL_INT] = 4,
- [_STORE_FAST] = 8,
- [_INIT_CALL_PY_EXACT_ARGS] = 5,
+const ReplicationRange _PyUop_Replication[MAX_UOP_ID+1] = {
+ [_LOAD_FAST] = { 0, 8 },
+ [_LOAD_FAST_BORROW] = { 0, 8 },
+ [_LOAD_SMALL_INT] = { 0, 4 },
+ [_STORE_FAST] = { 0, 8 },
+ [_INIT_CALL_PY_EXACT_ARGS] = { 0, 5 },
+ [_COPY] = { 1, 4 },
+ [_SWAP] = { 2, 4 },
};
const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
[_BINARY_OP] = "_BINARY_OP",
[_BINARY_OP_ADD_FLOAT] = "_BINARY_OP_ADD_FLOAT",
+ [_BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS] = "_BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS",
[_BINARY_OP_ADD_INT] = "_BINARY_OP_ADD_INT",
[_BINARY_OP_ADD_UNICODE] = "_BINARY_OP_ADD_UNICODE",
[_BINARY_OP_EXTEND] = "_BINARY_OP_EXTEND",
[_BINARY_OP_INPLACE_ADD_UNICODE] = "_BINARY_OP_INPLACE_ADD_UNICODE",
[_BINARY_OP_MULTIPLY_FLOAT] = "_BINARY_OP_MULTIPLY_FLOAT",
+ [_BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS] = "_BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS",
[_BINARY_OP_MULTIPLY_INT] = "_BINARY_OP_MULTIPLY_INT",
[_BINARY_OP_SUBSCR_CHECK_FUNC] = "_BINARY_OP_SUBSCR_CHECK_FUNC",
[_BINARY_OP_SUBSCR_DICT] = "_BINARY_OP_SUBSCR_DICT",
@@ -348,6 +367,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
[_BINARY_OP_SUBSCR_STR_INT] = "_BINARY_OP_SUBSCR_STR_INT",
[_BINARY_OP_SUBSCR_TUPLE_INT] = "_BINARY_OP_SUBSCR_TUPLE_INT",
[_BINARY_OP_SUBTRACT_FLOAT] = "_BINARY_OP_SUBTRACT_FLOAT",
+ [_BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS] = "_BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS",
[_BINARY_OP_SUBTRACT_INT] = "_BINARY_OP_SUBTRACT_INT",
[_BINARY_SLICE] = "_BINARY_SLICE",
[_BUILD_INTERPOLATION] = "_BUILD_INTERPOLATION",
@@ -408,6 +428,9 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
[_CONTAINS_OP_SET] = "_CONTAINS_OP_SET",
[_CONVERT_VALUE] = "_CONVERT_VALUE",
[_COPY] = "_COPY",
+ [_COPY_1] = "_COPY_1",
+ [_COPY_2] = "_COPY_2",
+ [_COPY_3] = "_COPY_3",
[_COPY_FREE_VARS] = "_COPY_FREE_VARS",
[_CREATE_INIT_FRAME] = "_CREATE_INIT_FRAME",
[_DELETE_ATTR] = "_DELETE_ATTR",
@@ -458,6 +481,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
[_GUARD_NOS_LIST] = "_GUARD_NOS_LIST",
[_GUARD_NOS_NOT_NULL] = "_GUARD_NOS_NOT_NULL",
[_GUARD_NOS_NULL] = "_GUARD_NOS_NULL",
+ [_GUARD_NOS_OVERFLOWED] = "_GUARD_NOS_OVERFLOWED",
[_GUARD_NOS_TUPLE] = "_GUARD_NOS_TUPLE",
[_GUARD_NOS_UNICODE] = "_GUARD_NOS_UNICODE",
[_GUARD_NOT_EXHAUSTED_LIST] = "_GUARD_NOT_EXHAUSTED_LIST",
@@ -469,6 +493,7 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
[_GUARD_TOS_FLOAT] = "_GUARD_TOS_FLOAT",
[_GUARD_TOS_INT] = "_GUARD_TOS_INT",
[_GUARD_TOS_LIST] = "_GUARD_TOS_LIST",
+ [_GUARD_TOS_OVERFLOWED] = "_GUARD_TOS_OVERFLOWED",
[_GUARD_TOS_SLICE] = "_GUARD_TOS_SLICE",
[_GUARD_TOS_TUPLE] = "_GUARD_TOS_TUPLE",
[_GUARD_TOS_UNICODE] = "_GUARD_TOS_UNICODE",
@@ -572,8 +597,12 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
[_POP_EXCEPT] = "_POP_EXCEPT",
[_POP_ITER] = "_POP_ITER",
[_POP_TOP] = "_POP_TOP",
+ [_POP_TOP_FLOAT] = "_POP_TOP_FLOAT",
+ [_POP_TOP_INT] = "_POP_TOP_INT",
[_POP_TOP_LOAD_CONST_INLINE] = "_POP_TOP_LOAD_CONST_INLINE",
[_POP_TOP_LOAD_CONST_INLINE_BORROW] = "_POP_TOP_LOAD_CONST_INLINE_BORROW",
+ [_POP_TOP_NOP] = "_POP_TOP_NOP",
+ [_POP_TOP_UNICODE] = "_POP_TOP_UNICODE",
[_POP_TWO] = "_POP_TWO",
[_POP_TWO_LOAD_CONST_INLINE_BORROW] = "_POP_TWO_LOAD_CONST_INLINE_BORROW",
[_PUSH_EXC_INFO] = "_PUSH_EXC_INFO",
@@ -617,6 +646,8 @@ const char *const _PyOpcode_uop_name[MAX_UOP_ID+1] = {
[_STORE_SUBSCR_DICT] = "_STORE_SUBSCR_DICT",
[_STORE_SUBSCR_LIST_INT] = "_STORE_SUBSCR_LIST_INT",
[_SWAP] = "_SWAP",
+ [_SWAP_2] = "_SWAP_2",
+ [_SWAP_3] = "_SWAP_3",
[_TIER2_RESUME_CHECK] = "_TIER2_RESUME_CHECK",
[_TO_BOOL] = "_TO_BOOL",
[_TO_BOOL_BOOL] = "_TO_BOOL_BOOL",
@@ -726,6 +757,14 @@ int _PyUop_num_popped(int opcode, int oparg)
return 2;
case _POP_TOP:
return 1;
+ case _POP_TOP_NOP:
+ return 1;
+ case _POP_TOP_INT:
+ return 1;
+ case _POP_TOP_FLOAT:
+ return 1;
+ case _POP_TOP_UNICODE:
+ return 1;
case _POP_TWO:
return 2;
case _PUSH_NULL:
@@ -770,6 +809,10 @@ int _PyUop_num_popped(int opcode, int oparg)
return 0;
case _GUARD_TOS_INT:
return 0;
+ case _GUARD_NOS_OVERFLOWED:
+ return 0;
+ case _GUARD_TOS_OVERFLOWED:
+ return 0;
case _BINARY_OP_MULTIPLY_INT:
return 2;
case _BINARY_OP_ADD_INT:
@@ -786,6 +829,12 @@ int _PyUop_num_popped(int opcode, int oparg)
return 2;
case _BINARY_OP_SUBTRACT_FLOAT:
return 2;
+ case _BINARY_OP_MULTIPLY_FLOAT__NO_DECREF_INPUTS:
+ return 2;
+ case _BINARY_OP_ADD_FLOAT__NO_DECREF_INPUTS:
+ return 2;
+ case _BINARY_OP_SUBTRACT_FLOAT__NO_DECREF_INPUTS:
+ return 2;
case _BINARY_OP_ADD_UNICODE:
return 2;
case _BINARY_OP_INPLACE_ADD_UNICODE:
@@ -1176,10 +1225,20 @@ int _PyUop_num_popped(int opcode, int oparg)
return 1;
case _FORMAT_WITH_SPEC:
return 2;
+ case _COPY_1:
+ return 0;
+ case _COPY_2:
+ return 0;
+ case _COPY_3:
+ return 0;
case _COPY:
return 0;
case _BINARY_OP:
return 2;
+ case _SWAP_2:
+ return 0;
+ case _SWAP_3:
+ return 0;
case _SWAP:
return 0;
case _GUARD_IS_TRUE_POP:
diff --git a/Include/object.h b/Include/object.h
index 994cac1ad17..c75e9db0cbd 100644
--- a/Include/object.h
+++ b/Include/object.h
@@ -101,6 +101,12 @@ whose size is determined when the object is allocated.
#define PyObject_VAR_HEAD PyVarObject ob_base;
#define Py_INVALID_SIZE (Py_ssize_t)-1
+/* PyObjects are given a minimum alignment so that the least significant bits
+ * of an object pointer become available for other purposes.
+ * This must be an integer literal with the value (1 << _PyGC_PREV_SHIFT), number of bytes.
+ */
+#define _PyObject_MIN_ALIGNMENT 4
+
/* Nothing is actually declared to be a PyObject, but every pointer to
* a Python object can be cast to a PyObject*. This is inheritance built
* by hand. Similarly every pointer to a variable-size Python object can,
@@ -136,6 +142,7 @@ struct _object {
#else
Py_ssize_t ob_refcnt;
#endif
+ _Py_ALIGNED_DEF(_PyObject_MIN_ALIGNMENT, char) _aligner;
};
#ifdef _MSC_VER
__pragma(warning(pop))
@@ -153,7 +160,7 @@ struct _object {
// ob_tid stores the thread id (or zero). It is also used by the GC and the
// trashcan mechanism as a linked list pointer and by the GC to store the
// computed "gc_refs" refcount.
- uintptr_t ob_tid;
+ _Py_ALIGNED_DEF(_PyObject_MIN_ALIGNMENT, uintptr_t) ob_tid;
uint16_t ob_flags;
PyMutex ob_mutex; // per-object lock
uint8_t ob_gc_bits; // gc-related state
@@ -660,8 +667,13 @@ PyAPI_DATA(PyObject) _Py_NoneStruct; /* Don't use this directly */
PyAPI_FUNC(int) Py_IsNone(PyObject *x);
#define Py_IsNone(x) Py_Is((x), Py_None)
-/* Macro for returning Py_None from a function */
-#define Py_RETURN_NONE return Py_None
+/* Macro for returning Py_None from a function.
+ * Only treat Py_None as immortal in the limited C API 3.12 and newer. */
+#if defined(Py_LIMITED_API) && Py_LIMITED_API+0 < 0x030c0000
+# define Py_RETURN_NONE return Py_NewRef(Py_None)
+#else
+# define Py_RETURN_NONE return Py_None
+#endif
/*
Py_NotImplemented is a singleton used to signal that an operation is
diff --git a/Include/pymacro.h b/Include/pymacro.h
index d410645034d..bfe660e8303 100644
--- a/Include/pymacro.h
+++ b/Include/pymacro.h
@@ -24,44 +24,66 @@
#endif
-// _Py_ALIGN_AS: this compiler's spelling of `alignas` keyword,
-// We currently use alignas for free-threaded builds only; additional compat
-// checking would be great before we add it to the default build.
-// Standards/compiler support:
+// _Py_ALIGNED_DEF(N, T): Define a variable/member with increased alignment
+//
+// `N`: the desired minimum alignment, an integer literal, number of bytes
+// `T`: the type of the defined variable
+// (or a type with at least the defined variable's alignment)
+//
+// May not be used on a struct definition.
+//
+// Standards/compiler support for `alignas` alternatives:
// - `alignas` is a keyword in C23 and C++11.
// - `_Alignas` is a keyword in C11
// - GCC & clang has __attribute__((aligned))
// (use that for older standards in pedantic mode)
// - MSVC has __declspec(align)
// - `_Alignas` is common C compiler extension
-// Older compilers may name it differently; to allow compilation on such
-// unsupported platforms, we don't redefine _Py_ALIGN_AS if it's already
+// Older compilers may name `alignas` differently; to allow compilation on such
+// unsupported platforms, we don't redefine _Py_ALIGNED_DEF if it's already
// defined. Note that defining it wrong (including defining it to nothing) will
// cause ABI incompatibilities.
-#ifdef Py_GIL_DISABLED
-# ifndef _Py_ALIGN_AS
-# ifdef __cplusplus
-# if __cplusplus >= 201103L
-# define _Py_ALIGN_AS(V) alignas(V)
-# elif defined(__GNUC__) || defined(__clang__)
-# define _Py_ALIGN_AS(V) __attribute__((aligned(V)))
-# elif defined(_MSC_VER)
-# define _Py_ALIGN_AS(V) __declspec(align(V))
-# else
-# define _Py_ALIGN_AS(V) alignas(V)
-# endif
-# elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
-# define _Py_ALIGN_AS(V) alignas(V)
-# elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
-# define _Py_ALIGN_AS(V) _Alignas(V)
-# elif (defined(__GNUC__) || defined(__clang__))
-# define _Py_ALIGN_AS(V) __attribute__((aligned(V)))
-# elif defined(_MSC_VER)
-# define _Py_ALIGN_AS(V) __declspec(align(V))
-# else
-# define _Py_ALIGN_AS(V) _Alignas(V)
-# endif
-# endif
+//
+// Behavior of `alignas` alternatives:
+// - `alignas` & `_Alignas`:
+// - Can be used multiple times; the greatest alignment applies.
+// - It is an *error* if the combined effect of all `alignas` modifiers would
+// decrease the alignment.
+// - Takes types or numbers.
+// - May not be used on a struct definition, unless also defining a variable.
+// - `__declspec(align)`:
+// - Has no effect if it would decrease alignment.
+// - Only takes an integer literal.
+// - May be used on struct or variable definitions.
+// However, when defining both the struct and the variable at once,
+// `declspec(aligned)` causes compiler warning 5274 and possible ABI
+// incompatibility.
+// - ` __attribute__((aligned))`:
+// - Has no effect if it would decrease alignment.
+// - Takes types or numbers
+// - May be used on struct or variable definitions.
+#ifndef _Py_ALIGNED_DEF
+# ifdef __cplusplus
+# if __cplusplus >= 201103L
+# define _Py_ALIGNED_DEF(N, T) alignas(N) alignas(T) T
+# elif defined(__GNUC__) || defined(__clang__)
+# define _Py_ALIGNED_DEF(N, T) __attribute__((aligned(N))) T
+# elif defined(_MSC_VER)
+# define _Py_ALIGNED_DEF(N, T) __declspec(align(N)) T
+# else
+# define _Py_ALIGNED_DEF(N, T) alignas(N) alignas(T) T
+# endif
+# elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 202311L
+# define _Py_ALIGNED_DEF(N, T) alignas(N) alignas(T) T
+# elif defined(__STDC_VERSION__) && __STDC_VERSION__ >= 201112L
+# define _Py_ALIGNED_DEF(N, T) _Alignas(N) _Alignas(T) T
+# elif (defined(__GNUC__) || defined(__clang__))
+# define _Py_ALIGNED_DEF(N, T) __attribute__((aligned(N))) T
+# elif defined(_MSC_VER)
+# define _Py_ALIGNED_DEF(N, T) __declspec(align(N)) T
+# else
+# define _Py_ALIGNED_DEF(N, T) _Alignas(N) _Alignas(T) T
+# endif
#endif
/* Minimum value between x and y */