summaryrefslogtreecommitdiffstats
path: root/contrib/tools/cython/Cython/Compiler/Code.py
diff options
context:
space:
mode:
Diffstat (limited to 'contrib/tools/cython/Cython/Compiler/Code.py')
-rw-r--r--contrib/tools/cython/Cython/Compiler/Code.py11
1 files changed, 9 insertions, 2 deletions
diff --git a/contrib/tools/cython/Cython/Compiler/Code.py b/contrib/tools/cython/Cython/Compiler/Code.py
index 630683bf166..ed783164ff8 100644
--- a/contrib/tools/cython/Cython/Compiler/Code.py
+++ b/contrib/tools/cython/Cython/Compiler/Code.py
@@ -2429,19 +2429,26 @@ class GlobalState:
writer.putln("{")
writer.putln(f"PyObject **table = {array_cname};")
writer.putln(f"for (Py_ssize_t i=0; i<{constant_count}; ++i) {{")
- writer.putln("#if CYTHON_COMPILING_IN_CPYTHON_FREETHREADING")
+ writer.putln("#if PY_VERSION_HEX >= 0x030F0000")
+ writer.putln("PyUnstable_SetImmortal(table[i]);")
+ writer.putln("#elif CYTHON_COMPILING_IN_CPYTHON_FREETHREADING")
# We don't want to set the refcount on shared constants (e.g. cached integers)
# because setting the refcount isn't thread-safe. The chances are that most of the constants
# that this applies to are already immortal though so that isn't a great loss.
+ # Overflow, e.g. on 32 bit systems.
+ writer.putln("if ((PY_SSIZE_T_MAX <= _Py_IMMORTAL_REFCNT_LOCAL)) break;")
writer.putln("#if PY_VERSION_HEX < 0x030E0000")
writer.putln("if (_Py_IsOwnedByCurrentThread(table[i]) && Py_REFCNT(table[i]) == 1)")
writer.putln("#else")
writer.putln("if (PyUnstable_Object_IsUniquelyReferenced(table[i]))")
writer.putln("#endif")
writer.putln("{")
- writer.putln("Py_SET_REFCNT(table[i], _Py_IMMORTAL_REFCNT_LOCAL);")
+ # Go one higher than we think we need to because of a bug in SET_REFCNT check in CPython
+ writer.putln("Py_SET_REFCNT(table[i], ((Py_ssize_t)_Py_IMMORTAL_REFCNT_LOCAL + 1));")
writer.putln("}")
writer.putln("#else")
+ # Overflow, e.g. on 32 bit systems.
+ writer.putln("if ((PY_SSIZE_T_MAX < _Py_IMMORTAL_INITIAL_REFCNT)) break;")
writer.putln("Py_SET_REFCNT(table[i], _Py_IMMORTAL_INITIAL_REFCNT);")
writer.putln("#endif")
writer.putln("}") # for()