1 /**
2   Mirror _pystate.h
3 
4   Thread and interpreter state structures and their interfaces
5   */
6 module deimos.python.pystate;
7 
8 import deimos.python.pyport;
9 import deimos.python.object;
10 import deimos.python.frameobject;
11 import deimos.python.pyatomic;
12 import deimos.python.moduleobject;
13 
14 extern(C):
15 // Python-header-file: Include/pystate.h:
16 
17 enum MAX_CO_EXTRA_USERS = 255;
18 
19 version(Python_3_5_Or_Later) {
20     alias PyObject* function(PyFrameObject*, int) _PyFrameEvalFunction;
21 }
22 
23 /// _
24 struct PyInterpreterState {
25     /// _
26     PyInterpreterState* next;
27     /// _
28     PyThreadState* tstate_head;
29 
30     /// _
31     PyObject* modules;
32     version(Python_3_0_Or_Later) {
33         /// Availability: 3.*
34         PyObject* modules_by_index;
35     }
36     /// _
37     PyObject* sysdict;
38     /// _
39     PyObject* builtins;
40 
41     /// _
42     PyObject* codec_search_path;
43     /// _
44     PyObject* codec_search_cache;
45     /// _
46     PyObject* codec_error_registry;
47     version(Python_3_0_Or_Later) {
48         /// Availability: 3.*
49         int codecs_initialized;
50         /// Availability: 3.*
51         int fscodec_initialized;
52     }
53 
54     /// _
55     int dlopenflags;
56 
57     // XXX: Not sure what WITH_TSC refers to, or how to conditionalize it in D:
58     //#ifdef WITH_TSC
59     //  int tscdump;
60     //#endif
61 
62     version(Python_3_4_Or_Later) {
63         PyObject* builtins_copy;
64     }
65     version(Python_3_6_Or_Later) {
66         PyObject* import_func;
67     }
68 
69     version(Python_3_5_Or_Later) {
70         _PyFrameEvalFunction eval_frame;
71     }
72 }
73 
74 /// _
75 alias int function(PyObject*, PyFrameObject*, int, PyObject*) Py_tracefunc;
76 
77 /// _
78 enum PyTrace_CALL               = 0;
79 /// ditto
80 enum PyTrace_EXCEPTION          = 1;
81 /// ditto
82 enum PyTrace_LINE 		= 2;
83 /// ditto
84 enum PyTrace_RETURN 	        = 3;
85 /// ditto
86 enum PyTrace_C_CALL             = 4;
87 /// ditto
88 enum PyTrace_C_EXCEPTION        = 5;
89 /// ditto
90 enum PyTrace_C_RETURN           = 6;
91 
92 /// _
93 struct PyThreadState {
94     version(Python_3_4_Or_Later) {
95         /// Availability: >= 3.4
96         PyThreadState* prev;
97     }
98     /// _
99     PyThreadState* next;
100     /// _
101     PyInterpreterState* interp;
102 
103     /// _
104     PyFrameObject* frame;
105     /// _
106     int recursion_depth;
107     version(Python_3_0_Or_Later) {
108         /** The stack has overflowed. Allow 50 more calls
109            to handle the runtime error. */
110         /// Availability: 3.*
111         ubyte overflowed;
112         /** The current calls must not cause
113            a stack overflow. */
114         /// Availability: 3.*
115         ubyte recursion_critical;
116     }
117     /// _
118     int tracing;
119     /// _
120     int use_tracing;
121 
122     /// _
123     Py_tracefunc c_profilefunc;
124     /// _
125     Py_tracefunc c_tracefunc;
126     /// _
127     PyObject* c_profileobj;
128     /// _
129     PyObject* c_traceobj;
130 
131     /// _
132     PyObject* curexc_type;
133     /// _
134     PyObject* curexc_value;
135     /// _
136     PyObject* curexc_traceback;
137 
138     /// _
139     PyObject* exc_type;
140     /// _
141     PyObject* exc_value;
142     /// _
143     PyObject* exc_traceback;
144 
145     /// _
146     PyObject* dict;
147 
148     version(Python_3_4_Or_Later) {
149     }else{
150         /** tick_counter is incremented whenever the check_interval ticker
151          * reaches zero. The purpose is to give a useful measure of the number
152          * of interpreted bytecode instructions in a given thread.  This
153          * extremely lightweight statistic collector may be of interest to
154          * profilers (like psyco.jit()), although nothing in the core uses it.
155          */
156         /// Availability: < 3.4
157         int tick_counter;
158     }
159     /// _
160     int gilstate_counter;
161     /** Asynchronous exception to raise */
162     PyObject* async_exc;
163     /** Thread id where this tstate was created */
164     C_long thread_id;
165 
166     version(Python_3_3_Or_Later) {
167         /// Availability: >= 3.3
168         int trash_delete_nesting;
169 
170         /// Availability: >= 3.3
171         PyObject *trash_delete_later;
172     }
173     version(Python_3_4_Or_Later) {
174         /// Availability: >= 3.4
175         void function(void *) on_delete;
176         /// Availability: >= 3.4
177         void* on_delete_data;
178     }
179     version(Python_3_5_Or_Later) {
180         /// Availability: >= 3.5
181         PyObject* coroutine_wrapper;
182         /// Availability: >= 3.5
183         int in_coroutine_wrapper;
184     }
185 
186     version(Python_3_6_Or_Later) {
187         /// Availability: >= 3.6
188         Py_ssize_t co_extra_user_count;
189         /// Availability: >= 3.6
190         freefunc[MAX_CO_EXTRA_USERS] co_extra_freefuncs;
191         /// Availability: >= 3.6
192         PyObject* async_gen_firstiter;
193         /// Availability: >= 3.6
194         PyObject* async_gen_finalizer;
195     }
196 }
197 
198 /// _
199 PyInterpreterState* PyInterpreterState_New();
200 /// _
201 void PyInterpreterState_Clear(PyInterpreterState *);
202 /// _
203 void PyInterpreterState_Delete(PyInterpreterState *);
204 version(Python_3_0_Or_Later) {
205     /// Availability: 3.*
206     int _PyState_AddModule(PyObject*, PyModuleDef*);
207     /// Availability: 3.*
208     PyObject* PyState_FindModule(PyModuleDef*);
209 }
210 
211 /// _
212 PyThreadState* PyThreadState_New(PyInterpreterState *);
213 version(Python_2_6_Or_Later){
214     /// Availability: >= 2.6
215     PyThreadState * _PyThreadState_Prealloc(PyInterpreterState *);
216     /// Availability: >= 2.6
217     void _PyThreadState_Init(PyThreadState *);
218 }
219 /// _
220 void PyThreadState_Clear(PyThreadState *);
221 /// _
222 void PyThreadState_Delete(PyThreadState *);
223 /// _
224 void PyThreadState_DeleteCurrent();
225 version(Python_3_0_Or_Later) {
226     /// Availability: 3.*
227     void _PyGILState_Reinit();
228 }
229 
230 /// _
231 PyThreadState* PyThreadState_Get();
232 /// _
233 PyThreadState* PyThreadState_Swap(PyThreadState*);
234 /// _
235 PyObject_BorrowedRef* PyThreadState_GetDict();
236 /// _
237 int PyThreadState_SetAsyncExc(C_long, PyObject*);
238 
239 version(Python_3_0_Or_Later) {
240     /// _
241     mixin(PyAPI_DATA!"_Py_atomic_address _PyThreadState_Current");
242 
243     /// _
244     auto PyThreadState_GET()() {
245         return cast(PyThreadState*)
246                 _Py_atomic_load_relaxed(&_PyThreadState_Current);
247     }
248 }else{
249     /// _
250     mixin(PyAPI_DATA!"PyThreadState* _PyThreadState_Current");
251 
252     /// _
253     auto PyThreadState_GET()() {
254         return _PyThreadState_Current;
255     }
256 }
257 
258 /// _
259 enum PyGILState_STATE {
260     /// _
261     PyGILState_LOCKED,
262     /// _
263     PyGILState_UNLOCKED
264 };
265 
266 /** Ensure that the current thread is ready to call the Python
267    C API, regardless of the current state of Python, or of its
268    thread lock.  This may be called as many times as desired
269    by a thread so long as each call is matched with a call to
270    PyGILState_Release().  In general, other thread-state APIs may
271    be used between _Ensure() and _Release() calls, so long as the
272    thread-state is restored to its previous state before the Release().
273    For example, normal use of the Py_BEGIN_ALLOW_THREADS/
274    Py_END_ALLOW_THREADS macros are acceptable.
275 
276    The return value is an opaque "handle" to the thread state when
277    PyGILState_Ensure() was called, and must be passed to
278    PyGILState_Release() to ensure Python is left in the same state. Even
279    though recursive calls are allowed, these handles can *not* be shared -
280    each unique call to PyGILState_Ensure must save the handle for its
281    call to PyGILState_Release.
282 
283    When the function returns, the current thread will hold the GIL.
284 
285    Failure is a fatal error.
286 */
287 PyGILState_STATE PyGILState_Ensure();
288 
289 /** Release any resources previously acquired.  After this call, Python's
290    state will be the same as it was prior to the corresponding
291    PyGILState_Ensure() call (but generally this state will be unknown to
292    the caller, hence the use of the GILState API.)
293 
294    Every call to PyGILState_Ensure must be matched by a call to
295    PyGILState_Release on the same thread.
296 */
297 void PyGILState_Release(PyGILState_STATE);
298 
299 /** Helper/diagnostic function - get the current thread state for
300    this thread.  May return NULL if no GILState API has been used
301    on the current thread.  Note that the main thread always has such a
302    thread-state, even if no auto-thread-state call has been made
303    on the main thread.
304 */
305 PyThreadState* PyGILState_GetThisThreadState();
306 /// _
307 PyInterpreterState* PyInterpreterState_Head();
308 /// _
309 PyInterpreterState* PyInterpreterState_Next(PyInterpreterState*);
310 /// _
311 PyThreadState* PyInterpreterState_ThreadHead(PyInterpreterState*);
312 /// _
313 PyThreadState* PyThreadState_Next(PyThreadState*);
314 
315 /// _
316 alias PyFrameObject* function(PyThreadState* self_) PyThreadFrameGetter;
317 
318 /// _
319 mixin(PyAPI_DATA!"PyThreadFrameGetter _PyThreadState_GetFrame");