1 | #ifndef Py_CEVAL_H |
2 | #define Py_CEVAL_H |
3 | #ifdef __cplusplus |
4 | extern "C" { |
5 | #endif |
6 | |
7 | |
8 | /* Interface to random parts in ceval.c */ |
9 | |
10 | PyAPI_FUNC(PyObject *) PyEval_CallObjectWithKeywords( |
11 | PyObject *, PyObject *, PyObject *); |
12 | |
13 | /* Inline this */ |
14 | #define PyEval_CallObject(func,arg) \ |
15 | PyEval_CallObjectWithKeywords(func, arg, (PyObject *)NULL) |
16 | |
17 | PyAPI_FUNC(PyObject *) PyEval_CallFunction(PyObject *obj, |
18 | const char *format, ...); |
19 | PyAPI_FUNC(PyObject *) PyEval_CallMethod(PyObject *obj, |
20 | const char *methodname, |
21 | const char *format, ...); |
22 | |
23 | #ifndef Py_LIMITED_API |
24 | PyAPI_FUNC(void) PyEval_SetProfile(Py_tracefunc, PyObject *); |
25 | PyAPI_FUNC(void) PyEval_SetTrace(Py_tracefunc, PyObject *); |
26 | PyAPI_FUNC(void) _PyEval_SetCoroutineWrapper(PyObject *); |
27 | PyAPI_FUNC(PyObject *) _PyEval_GetCoroutineWrapper(void); |
28 | #endif |
29 | |
30 | struct _frame; /* Avoid including frameobject.h */ |
31 | |
32 | PyAPI_FUNC(PyObject *) PyEval_GetBuiltins(void); |
33 | PyAPI_FUNC(PyObject *) PyEval_GetGlobals(void); |
34 | PyAPI_FUNC(PyObject *) PyEval_GetLocals(void); |
35 | PyAPI_FUNC(struct _frame *) PyEval_GetFrame(void); |
36 | |
37 | /* Look at the current frame's (if any) code's co_flags, and turn on |
38 | the corresponding compiler flags in cf->cf_flags. Return 1 if any |
39 | flag was set, else return 0. */ |
40 | #ifndef Py_LIMITED_API |
41 | PyAPI_FUNC(int) PyEval_MergeCompilerFlags(PyCompilerFlags *cf); |
42 | #endif |
43 | |
44 | PyAPI_FUNC(int) Py_AddPendingCall(int (*func)(void *), void *arg); |
45 | PyAPI_FUNC(int) Py_MakePendingCalls(void); |
46 | |
47 | /* Protection against deeply nested recursive calls |
48 | |
49 | In Python 3.0, this protection has two levels: |
50 | * normal anti-recursion protection is triggered when the recursion level |
51 | exceeds the current recursion limit. It raises a RecursionError, and sets |
52 | the "overflowed" flag in the thread state structure. This flag |
53 | temporarily *disables* the normal protection; this allows cleanup code |
54 | to potentially outgrow the recursion limit while processing the |
55 | RecursionError. |
56 | * "last chance" anti-recursion protection is triggered when the recursion |
57 | level exceeds "current recursion limit + 50". By construction, this |
58 | protection can only be triggered when the "overflowed" flag is set. It |
59 | means the cleanup code has itself gone into an infinite loop, or the |
60 | RecursionError has been mistakingly ignored. When this protection is |
61 | triggered, the interpreter aborts with a Fatal Error. |
62 | |
63 | In addition, the "overflowed" flag is automatically reset when the |
64 | recursion level drops below "current recursion limit - 50". This heuristic |
65 | is meant to ensure that the normal anti-recursion protection doesn't get |
66 | disabled too long. |
67 | |
68 | Please note: this scheme has its own limitations. See: |
69 | http://mail.python.org/pipermail/python-dev/2008-August/082106.html |
70 | for some observations. |
71 | */ |
72 | PyAPI_FUNC(void) Py_SetRecursionLimit(int); |
73 | PyAPI_FUNC(int) Py_GetRecursionLimit(void); |
74 | |
75 | #define Py_EnterRecursiveCall(where) \ |
76 | (_Py_MakeRecCheck(PyThreadState_GET()->recursion_depth) && \ |
77 | _Py_CheckRecursiveCall(where)) |
78 | #define Py_LeaveRecursiveCall() \ |
79 | do{ if(_Py_MakeEndRecCheck(PyThreadState_GET()->recursion_depth)) \ |
80 | PyThreadState_GET()->overflowed = 0; \ |
81 | } while(0) |
82 | PyAPI_FUNC(int) _Py_CheckRecursiveCall(const char *where); |
83 | PyAPI_DATA(int) _Py_CheckRecursionLimit; |
84 | |
85 | #ifdef USE_STACKCHECK |
86 | /* With USE_STACKCHECK, we artificially decrement the recursion limit in order |
87 | to trigger regular stack checks in _Py_CheckRecursiveCall(), except if |
88 | the "overflowed" flag is set, in which case we need the true value |
89 | of _Py_CheckRecursionLimit for _Py_MakeEndRecCheck() to function properly. |
90 | */ |
91 | # define _Py_MakeRecCheck(x) \ |
92 | (++(x) > (_Py_CheckRecursionLimit += PyThreadState_GET()->overflowed - 1)) |
93 | #else |
94 | # define _Py_MakeRecCheck(x) (++(x) > _Py_CheckRecursionLimit) |
95 | #endif |
96 | |
97 | /* Compute the "lower-water mark" for a recursion limit. When |
98 | * Py_LeaveRecursiveCall() is called with a recursion depth below this mark, |
99 | * the overflowed flag is reset to 0. */ |
100 | #define _Py_RecursionLimitLowerWaterMark(limit) \ |
101 | (((limit) > 200) \ |
102 | ? ((limit) - 50) \ |
103 | : (3 * ((limit) >> 2))) |
104 | |
105 | #define _Py_MakeEndRecCheck(x) \ |
106 | (--(x) < _Py_RecursionLimitLowerWaterMark(_Py_CheckRecursionLimit)) |
107 | |
108 | #define Py_ALLOW_RECURSION \ |
109 | do { unsigned char _old = PyThreadState_GET()->recursion_critical;\ |
110 | PyThreadState_GET()->recursion_critical = 1; |
111 | |
112 | #define Py_END_ALLOW_RECURSION \ |
113 | PyThreadState_GET()->recursion_critical = _old; \ |
114 | } while(0); |
115 | |
116 | PyAPI_FUNC(const char *) PyEval_GetFuncName(PyObject *); |
117 | PyAPI_FUNC(const char *) PyEval_GetFuncDesc(PyObject *); |
118 | |
119 | PyAPI_FUNC(PyObject *) PyEval_GetCallStats(PyObject *); |
120 | PyAPI_FUNC(PyObject *) PyEval_EvalFrame(struct _frame *); |
121 | PyAPI_FUNC(PyObject *) PyEval_EvalFrameEx(struct _frame *f, int exc); |
122 | |
123 | /* Interface for threads. |
124 | |
125 | A module that plans to do a blocking system call (or something else |
126 | that lasts a long time and doesn't touch Python data) can allow other |
127 | threads to run as follows: |
128 | |
129 | ...preparations here... |
130 | Py_BEGIN_ALLOW_THREADS |
131 | ...blocking system call here... |
132 | Py_END_ALLOW_THREADS |
133 | ...interpret result here... |
134 | |
135 | The Py_BEGIN_ALLOW_THREADS/Py_END_ALLOW_THREADS pair expands to a |
136 | {}-surrounded block. |
137 | To leave the block in the middle (e.g., with return), you must insert |
138 | a line containing Py_BLOCK_THREADS before the return, e.g. |
139 | |
140 | if (...premature_exit...) { |
141 | Py_BLOCK_THREADS |
142 | PyErr_SetFromErrno(PyExc_IOError); |
143 | return NULL; |
144 | } |
145 | |
146 | An alternative is: |
147 | |
148 | Py_BLOCK_THREADS |
149 | if (...premature_exit...) { |
150 | PyErr_SetFromErrno(PyExc_IOError); |
151 | return NULL; |
152 | } |
153 | Py_UNBLOCK_THREADS |
154 | |
155 | For convenience, that the value of 'errno' is restored across |
156 | Py_END_ALLOW_THREADS and Py_BLOCK_THREADS. |
157 | |
158 | WARNING: NEVER NEST CALLS TO Py_BEGIN_ALLOW_THREADS AND |
159 | Py_END_ALLOW_THREADS!!! |
160 | |
161 | The function PyEval_InitThreads() should be called only from |
162 | init_thread() in "_threadmodule.c". |
163 | |
164 | Note that not yet all candidates have been converted to use this |
165 | mechanism! |
166 | */ |
167 | |
168 | PyAPI_FUNC(PyThreadState *) PyEval_SaveThread(void); |
169 | PyAPI_FUNC(void) PyEval_RestoreThread(PyThreadState *); |
170 | |
171 | #ifdef WITH_THREAD |
172 | |
173 | PyAPI_FUNC(int) PyEval_ThreadsInitialized(void); |
174 | PyAPI_FUNC(void) PyEval_InitThreads(void); |
175 | PyAPI_FUNC(void) _PyEval_FiniThreads(void); |
176 | PyAPI_FUNC(void) PyEval_AcquireLock(void); |
177 | PyAPI_FUNC(void) PyEval_ReleaseLock(void); |
178 | PyAPI_FUNC(void) PyEval_AcquireThread(PyThreadState *tstate); |
179 | PyAPI_FUNC(void) PyEval_ReleaseThread(PyThreadState *tstate); |
180 | PyAPI_FUNC(void) PyEval_ReInitThreads(void); |
181 | |
182 | #ifndef Py_LIMITED_API |
183 | PyAPI_FUNC(void) _PyEval_SetSwitchInterval(unsigned long microseconds); |
184 | PyAPI_FUNC(unsigned long) _PyEval_GetSwitchInterval(void); |
185 | #endif |
186 | |
187 | #define Py_BEGIN_ALLOW_THREADS { \ |
188 | PyThreadState *_save; \ |
189 | _save = PyEval_SaveThread(); |
190 | #define Py_BLOCK_THREADS PyEval_RestoreThread(_save); |
191 | #define Py_UNBLOCK_THREADS _save = PyEval_SaveThread(); |
192 | #define Py_END_ALLOW_THREADS PyEval_RestoreThread(_save); \ |
193 | } |
194 | |
195 | #else /* !WITH_THREAD */ |
196 | |
197 | #define Py_BEGIN_ALLOW_THREADS { |
198 | #define Py_BLOCK_THREADS |
199 | #define Py_UNBLOCK_THREADS |
200 | #define Py_END_ALLOW_THREADS } |
201 | |
202 | #endif /* !WITH_THREAD */ |
203 | |
204 | #ifndef Py_LIMITED_API |
205 | PyAPI_FUNC(int) _PyEval_SliceIndex(PyObject *, Py_ssize_t *); |
206 | PyAPI_FUNC(void) _PyEval_SignalAsyncExc(void); |
207 | #endif |
208 | |
209 | |
210 | #ifdef __cplusplus |
211 | } |
212 | #endif |
213 | #endif /* !Py_CEVAL_H */ |
214 | |