-
Notifications
You must be signed in to change notification settings - Fork 248
/
greenlet_cpython_compat.hpp
142 lines (119 loc) · 3.87 KB
/
greenlet_cpython_compat.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
/* -*- indent-tabs-mode: nil; tab-width: 4; -*- */
#ifndef GREENLET_CPYTHON_COMPAT_H
#define GREENLET_CPYTHON_COMPAT_H
/**
* Helpers for compatibility with multiple versions of CPython.
*/
#define PY_SSIZE_T_CLEAN
#include "Python.h"
#if PY_VERSION_HEX >= 0x30A00B1
# define GREENLET_PY310 1
#else
# define GREENLET_PY310 0
#endif
/*
Python 3.10 beta 1 changed tstate->use_tracing to a nested cframe member.
See https://github.com/python/cpython/pull/25276
We have to save and restore this as well.
Python 3.13 removed PyThreadState.cframe (GH-108035).
*/
#if GREENLET_PY310 && PY_VERSION_HEX < 0x30D0000
# define GREENLET_USE_CFRAME 1
#else
# define GREENLET_USE_CFRAME 0
#endif
#if PY_VERSION_HEX >= 0x30B00A4
/*
Greenlet won't compile on anything older than Python 3.11 alpha 4 (see
https://bugs.python.org/issue46090). Summary of breaking internal changes:
- Python 3.11 alpha 1 changed how frame objects are represented internally.
- https://github.com/python/cpython/pull/30122
- Python 3.11 alpha 3 changed how recursion limits are stored.
- https://github.com/python/cpython/pull/29524
- Python 3.11 alpha 4 changed how exception state is stored. It also includes a
change to help greenlet save and restore the interpreter frame "data stack".
- https://github.com/python/cpython/pull/30122
- https://github.com/python/cpython/pull/30234
*/
# define GREENLET_PY311 1
#else
# define GREENLET_PY311 0
#endif
#if PY_VERSION_HEX >= 0x30C0000
# define GREENLET_PY312 1
#else
# define GREENLET_PY312 0
#endif
#if PY_VERSION_HEX >= 0x30D0000
# define GREENLET_PY313 1
#else
# define GREENLET_PY313 0
#endif
#ifndef Py_SET_REFCNT
/* Py_REFCNT and Py_SIZE macros are converted to functions
https://bugs.python.org/issue39573 */
# define Py_SET_REFCNT(obj, refcnt) Py_REFCNT(obj) = (refcnt)
#endif
#ifndef _Py_DEC_REFTOTAL
/* _Py_DEC_REFTOTAL macro has been removed from Python 3.9 by:
https://github.com/python/cpython/commit/49932fec62c616ec88da52642339d83ae719e924
The symbol we use to replace it was removed by at least 3.12.
*/
# ifdef Py_REF_DEBUG
# if GREENLET_PY312
# define _Py_DEC_REFTOTAL
# else
# define _Py_DEC_REFTOTAL _Py_RefTotal--
# endif
# else
# define _Py_DEC_REFTOTAL
# endif
#endif
// Define these flags like Cython does if we're on an old version.
#ifndef Py_TPFLAGS_CHECKTYPES
#define Py_TPFLAGS_CHECKTYPES 0
#endif
#ifndef Py_TPFLAGS_HAVE_INDEX
#define Py_TPFLAGS_HAVE_INDEX 0
#endif
#ifndef Py_TPFLAGS_HAVE_NEWBUFFER
#define Py_TPFLAGS_HAVE_NEWBUFFER 0
#endif
#ifndef Py_TPFLAGS_HAVE_VERSION_TAG
#define Py_TPFLAGS_HAVE_VERSION_TAG 0
#endif
#define G_TPFLAGS_DEFAULT Py_TPFLAGS_DEFAULT | Py_TPFLAGS_HAVE_VERSION_TAG | Py_TPFLAGS_CHECKTYPES | Py_TPFLAGS_HAVE_NEWBUFFER | Py_TPFLAGS_HAVE_GC
#if PY_VERSION_HEX < 0x03090000
// The official version only became available in 3.9
# define PyObject_GC_IsTracked(o) _PyObject_GC_IS_TRACKED(o)
#endif
// bpo-43760 added PyThreadState_EnterTracing() to Python 3.11.0a2
#if PY_VERSION_HEX < 0x030B00A2 && !defined(PYPY_VERSION)
static inline void PyThreadState_EnterTracing(PyThreadState *tstate)
{
tstate->tracing++;
#if PY_VERSION_HEX >= 0x030A00A1
tstate->cframe->use_tracing = 0;
#else
tstate->use_tracing = 0;
#endif
}
#endif
// bpo-43760 added PyThreadState_LeaveTracing() to Python 3.11.0a2
#if PY_VERSION_HEX < 0x030B00A2 && !defined(PYPY_VERSION)
static inline void PyThreadState_LeaveTracing(PyThreadState *tstate)
{
tstate->tracing--;
int use_tracing = (tstate->c_tracefunc != NULL
|| tstate->c_profilefunc != NULL);
#if PY_VERSION_HEX >= 0x030A00A1
tstate->cframe->use_tracing = use_tracing;
#else
tstate->use_tracing = use_tracing;
#endif
}
#endif
#if !defined(Py_C_RECURSION_LIMIT) && defined(C_RECURSION_LIMIT)
# define Py_C_RECURSION_LIMIT C_RECURSION_LIMIT
#endif
#endif /* GREENLET_CPYTHON_COMPAT_H */