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 import deimos.python.pythread;
14 
15 extern(C):
16 // Python-header-file: Include/pystate.h:
17 
18 enum MAX_CO_EXTRA_USERS = 255;
19 
20 version(Python_3_5_Or_Later) {
21     alias PyObject* function(PyFrameObject*, int) _PyFrameEvalFunction;
22 }
23 
24 version(Python_3_7_Or_Later) {
25     struct _PyCoreConfig {
26         int install_signal_handlers;  /* Install signal handlers? -1 means unset */
27 
28         int ignore_environment; /* -E, Py_IgnoreEnvironmentFlag */
29         int use_hash_seed;      /* PYTHONHASHSEED=x */
30         C_long hash_seed;
31         char* allocator;  /* Memory allocator: _PyMem_SetupAllocators() */
32         int dev_mode;           /* PYTHONDEVMODE, -X dev */
33         int faulthandler;       /* PYTHONFAULTHANDLER, -X faulthandler */
34         int tracemalloc;        /* PYTHONTRACEMALLOC, -X tracemalloc=N */
35         int import_time;        /* PYTHONPROFILEIMPORTTIME, -X importtime */
36         int show_ref_count;     /* -X showrefcount */
37         int show_alloc_count;   /* -X showalloccount */
38         int dump_refs;          /* PYTHONDUMPREFS */
39         int malloc_stats;       /* PYTHONMALLOCSTATS */
40         int coerce_c_locale;    /* PYTHONCOERCECLOCALE, -1 means unknown */
41         int coerce_c_locale_warn; /* PYTHONCOERCECLOCALE=warn */
42         int utf8_mode;          /* PYTHONUTF8, -X utf8; -1 means unknown */
43 
44         wchar* program_name;  /* Program name, see also Py_GetProgramName() */
45         int argc;               /* Number of command line arguments,
46                                    -1 means unset */
47         wchar** argv;         /* Command line arguments */
48         wchar* program;       /* argv[0] or "" */
49 
50         int nxoption;           /* Number of -X options */
51         wchar** xoptions;     /* -X options */
52 
53         int nwarnoption;        /* Number of warnings options */
54         wchar** warnoptions;  /* Warnings options */
55 
56         /* Path configuration inputs */
57         wchar* module_search_path_env; /* PYTHONPATH environment variable */
58         wchar* home;          /* PYTHONHOME environment variable,
59                                    see also Py_SetPythonHome(). */
60         /* Path configuration outputs */
61         int nmodule_search_path;        /* Number of sys.path paths,
62                                            -1 means unset */
63         wchar** module_search_paths;  /* sys.path paths */
64         wchar* executable;    /* sys.executable */
65         wchar* prefix;        /* sys.prefix */
66         wchar* base_prefix;   /* sys.base_prefix */
67         wchar* exec_prefix;   /* sys.exec_prefix */
68         wchar* base_exec_prefix;  /* sys.base_exec_prefix */
69 
70         /* Private fields */
71         int _disable_importlib; /* Needed by freeze_importlib */
72     }
73 
74     struct _PyMainInterpreterConfig{
75         int install_signal_handlers;   /* Install signal handlers? -1 means unset */
76         PyObject* argv;                /* sys.argv list, can be NULL */
77         PyObject* executable;          /* sys.executable str */
78         PyObject* prefix;              /* sys.prefix str */
79         PyObject* base_prefix;         /* sys.base_prefix str, can be NULL */
80         PyObject* exec_prefix;         /* sys.exec_prefix str */
81         PyObject* base_exec_prefix;    /* sys.base_exec_prefix str, can be NULL */
82         PyObject* warnoptions;         /* sys.warnoptions list, can be NULL */
83         PyObject* xoptions;            /* sys._xoptions dict, can be NULL */
84         PyObject* module_search_path;  /* sys.path list */
85     }
86 
87     struct _PyErr_StackItem{
88         /* This struct represents an entry on the exception stack, which is a
89          * per-coroutine state. (Coroutine in the computer science sense,
90          * including the thread and generators).
91          * This ensures that the exception state is not impacted by "yields"
92          * from an except handler.
93          */
94         PyObject* exc_type; 
95         PyObject* exc_value; 
96         PyObject* exc_traceback;
97 
98         _PyErr_StackItem* previous_item;
99 
100     }
101 }
102 
103 /// _
104 struct PyInterpreterState {
105     /// _
106     PyInterpreterState* next;
107     /// _
108     PyThreadState* tstate_head;
109 
110     version(Python_3_7_Or_Later) {
111         /// Availability >= 3.7
112         long id;
113         /// Availability >= 3.7
114         long id_refcount;
115         /// Availability >= 3.7
116         PyThread_type_lock id_mutex;
117     }
118     /// _
119     PyObject* modules;
120     version(Python_3_0_Or_Later) {
121         /// Availability: 3.*
122         PyObject* modules_by_index;
123     }
124     /// _
125     PyObject* sysdict;
126     /// _
127     PyObject* builtins;
128 
129     version(Python_3_0_Or_Later) {
130     }else version(Python_2_7_Or_Later) {
131         /// Availability: 2.7 (?)
132         PyObject* modules_reloading;
133     }
134 
135     version(Python_3_3_Or_Later) {
136         /// _
137         PyObject* importlib;
138     }
139     version(Python_3_7_Or_Later) {
140         /// _
141         int check_interval;
142         C_long num_threads;
143         size_t pythread_stacksize;
144     }
145 
146     /// _
147     PyObject* codec_search_path;
148     /// _
149     PyObject* codec_search_cache;
150     /// _
151     PyObject* codec_error_registry;
152     version(Python_3_0_Or_Later) {
153         /// Availability: 3.*
154         int codecs_initialized;
155         /// Availability: 3.*
156         int fscodec_initialized;
157     }
158 
159     version(Python_3_7_Or_Later) {
160         _PyCoreConfig core_config;
161         _PyMainInterpreterConfig config;
162     }
163 
164     /// _
165     int dlopenflags;
166 
167     // XXX: Not sure what WITH_TSC refers to, or how to conditionalize it in D:
168     //#ifdef WITH_TSC
169     //  int tscdump;
170     //#endif
171 
172     version(Python_3_4_Or_Later) {
173         PyObject* builtins_copy;
174     }
175     version(Python_3_6_Or_Later) {
176         PyObject* import_func;
177         _PyFrameEvalFunction eval_frame;
178     }
179 
180     version(Python_3_7_Or_Later) {
181         Py_ssize_t co_extra_user_count;
182         freefunc[MAX_CO_EXTRA_USERS] co_extra_freefuncs;
183 
184         // ifdef HAVE_FORK
185         PyObject* before_forkers;
186         PyObject* after_forkers_parent;
187         PyObject* after_forkers_child;
188         // end ifdef HAVE_FORK
189 
190         void function(PyObject*) pyexitfunc;
191         PyObject* pyexitmodule;
192 
193         ulong tstate_next_unique_id;
194 
195     }
196 }
197 
198 /// _
199 alias int function(PyObject*, PyFrameObject*, int, PyObject*) Py_tracefunc;
200 
201 /// _
202 enum PyTrace_CALL               = 0;
203 /// ditto
204 enum PyTrace_EXCEPTION          = 1;
205 /// ditto
206 enum PyTrace_LINE 		= 2;
207 /// ditto
208 enum PyTrace_RETURN 	        = 3;
209 /// ditto
210 enum PyTrace_C_CALL             = 4;
211 /// ditto
212 enum PyTrace_C_EXCEPTION        = 5;
213 /// ditto
214 enum PyTrace_C_RETURN           = 6;
215 
216 /// _
217 struct PyThreadState {
218     version(Python_3_4_Or_Later) {
219         /// Availability: >= 3.4
220         PyThreadState* prev;
221     }
222     /// _
223     PyThreadState* next;
224     /// _
225     PyInterpreterState* interp;
226 
227     /// _
228     PyFrameObject* frame;
229     /// _
230     int recursion_depth;
231     version(Python_3_0_Or_Later) {
232         /** The stack has overflowed. Allow 50 more calls
233            to handle the runtime error. */
234         /// Availability: 3.*
235         ubyte overflowed;
236         /** The current calls must not cause
237            a stack overflow. */
238         /// Availability: 3.*
239         ubyte recursion_critical;
240     }
241     version(Python_3_7_Or_Later) {
242         /// _
243         int stackcheck_counter;
244     }
245     /// _
246     int tracing;
247     /// _
248     int use_tracing;
249 
250     /// _
251     Py_tracefunc c_profilefunc;
252     /// _
253     Py_tracefunc c_tracefunc;
254     /// _
255     PyObject* c_profileobj;
256     /// _
257     PyObject* c_traceobj;
258 
259     /// _
260     PyObject* curexc_type;
261     /// _
262     PyObject* curexc_value;
263     /// _
264     PyObject* curexc_traceback;
265 
266     version(Python_3_7_Or_Later) {
267         /// _
268         _PyErr_StackItem exc_state;
269         /// _
270         _PyErr_StackItem* exc_info;
271     }else{
272         /// _
273         PyObject* exc_type;
274         /// _
275         PyObject* exc_value;
276         /// _
277         PyObject* exc_traceback;
278     }
279 
280     /// _
281     PyObject* dict;
282 
283     version(Python_3_4_Or_Later) {
284     }else{
285         /** tick_counter is incremented whenever the check_interval ticker
286          * reaches zero. The purpose is to give a useful measure of the number
287          * of interpreted bytecode instructions in a given thread.  This
288          * extremely lightweight statistic collector may be of interest to
289          * profilers (like psyco.jit()), although nothing in the core uses it.
290          */
291         /// Availability: < 3.4
292         int tick_counter;
293     }
294     /// _
295     int gilstate_counter;
296     /** Asynchronous exception to raise */
297     PyObject* async_exc;
298     /** Thread id where this tstate was created */
299     C_long thread_id;
300 
301     version(Python_3_3_Or_Later) {
302         /// Availability: >= 3.3
303         int trash_delete_nesting;
304 
305         /// Availability: >= 3.3
306         PyObject *trash_delete_later;
307     }
308     version(Python_3_4_Or_Later) {
309         /// Availability: >= 3.4
310         void function(void *) on_delete;
311         /// Availability: >= 3.4
312         void* on_delete_data;
313     }
314     version(Python_3_7_Or_Later) {
315         int coroutine_origin_tracking_depth;
316     }
317     version(Python_3_5_Or_Later) {
318         /// Availability: >= 3.5
319         PyObject* coroutine_wrapper;
320         /// Availability: >= 3.5
321         int in_coroutine_wrapper;
322     }
323 
324     version(Python_3_7_Or_Later) {
325         PyObject* async_gen_firstiter;
326         PyObject* async_gen_finalizer;
327 
328         PyObject* context;
329         ulong context_ver;
330 
331         ulong id;
332     }else version(Python_3_6_Or_Later) {
333         /// Availability: = 3.6
334         Py_ssize_t co_extra_user_count;
335         /// Availability: = 3.6
336         freefunc[MAX_CO_EXTRA_USERS] co_extra_freefuncs;
337         /// Availability: >= 3.6
338         PyObject* async_gen_firstiter;
339         /// Availability: >= 3.6
340         PyObject* async_gen_finalizer;
341     }
342 }
343 
344 /// _
345 PyInterpreterState* PyInterpreterState_New();
346 /// _
347 void PyInterpreterState_Clear(PyInterpreterState *);
348 /// _
349 void PyInterpreterState_Delete(PyInterpreterState *);
350 version(Python_3_0_Or_Later) {
351     /// Availability: 3.*
352     int _PyState_AddModule(PyObject*, PyModuleDef*);
353     /// Availability: 3.*
354     PyObject* PyState_FindModule(PyModuleDef*);
355 }
356 
357 /// _
358 PyThreadState* PyThreadState_New(PyInterpreterState *);
359 version(Python_2_6_Or_Later){
360     /// Availability: >= 2.6
361     PyThreadState * _PyThreadState_Prealloc(PyInterpreterState *);
362     /// Availability: >= 2.6
363     void _PyThreadState_Init(PyThreadState *);
364 }
365 /// _
366 void PyThreadState_Clear(PyThreadState *);
367 /// _
368 void PyThreadState_Delete(PyThreadState *);
369 /// _
370 void PyThreadState_DeleteCurrent();
371 version(Python_3_0_Or_Later) {
372     /// Availability: 3.*
373     void _PyGILState_Reinit();
374 }
375 
376 /// _
377 PyThreadState* PyThreadState_Get();
378 /// _
379 PyThreadState* PyThreadState_Swap(PyThreadState*);
380 /// _
381 PyObject_BorrowedRef* PyThreadState_GetDict();
382 /// _
383 int PyThreadState_SetAsyncExc(C_long, PyObject*);
384 
385 version(Python_3_3_Or_Later) {
386     /// _
387     auto PyThreadState_GET()() {
388         return PyThreadState_Get();
389     }
390 } else version(Python_3_0_Or_Later) {
391     /// _
392     mixin(PyAPI_DATA!"_Py_atomic_address _PyThreadState_Current");
393 
394     /// _
395     auto PyThreadState_GET()() {
396         return cast(PyThreadState*)
397                 _Py_atomic_load_relaxed(&_PyThreadState_Current);
398     }
399 } else {
400     /// _
401     mixin(PyAPI_DATA!"PyThreadState* _PyThreadState_Current");
402 
403     /// _
404     auto PyThreadState_GET()() {
405         return _PyThreadState_Current;
406     }
407 }
408 
409 /// _
410 enum PyGILState_STATE {
411     /// _
412     PyGILState_LOCKED,
413     /// _
414     PyGILState_UNLOCKED
415 };
416 
417 /** Ensure that the current thread is ready to call the Python
418    C API, regardless of the current state of Python, or of its
419    thread lock.  This may be called as many times as desired
420    by a thread so long as each call is matched with a call to
421    PyGILState_Release().  In general, other thread-state APIs may
422    be used between _Ensure() and _Release() calls, so long as the
423    thread-state is restored to its previous state before the Release().
424    For example, normal use of the Py_BEGIN_ALLOW_THREADS/
425    Py_END_ALLOW_THREADS macros are acceptable.
426 
427    The return value is an opaque "handle" to the thread state when
428    PyGILState_Ensure() was called, and must be passed to
429    PyGILState_Release() to ensure Python is left in the same state. Even
430    though recursive calls are allowed, these handles can *not* be shared -
431    each unique call to PyGILState_Ensure must save the handle for its
432    call to PyGILState_Release.
433 
434    When the function returns, the current thread will hold the GIL.
435 
436    Failure is a fatal error.
437 */
438 PyGILState_STATE PyGILState_Ensure();
439 
440 /** Release any resources previously acquired.  After this call, Python's
441    state will be the same as it was prior to the corresponding
442    PyGILState_Ensure() call (but generally this state will be unknown to
443    the caller, hence the use of the GILState API.)
444 
445    Every call to PyGILState_Ensure must be matched by a call to
446    PyGILState_Release on the same thread.
447 */
448 void PyGILState_Release(PyGILState_STATE);
449 
450 /** Helper/diagnostic function - get the current thread state for
451    this thread.  May return NULL if no GILState API has been used
452    on the current thread.  Note that the main thread always has such a
453    thread-state, even if no auto-thread-state call has been made
454    on the main thread.
455 */
456 PyThreadState* PyGILState_GetThisThreadState();
457 /// _
458 PyInterpreterState* PyInterpreterState_Head();
459 /// _
460 PyInterpreterState* PyInterpreterState_Next(PyInterpreterState*);
461 /// _
462 PyThreadState* PyInterpreterState_ThreadHead(PyInterpreterState*);
463 /// _
464 PyThreadState* PyThreadState_Next(PyThreadState*);
465 
466 /// _
467 alias PyFrameObject* function(PyThreadState* self_) PyThreadFrameGetter;
468 
469 /// _
470 mixin(PyAPI_DATA!"PyThreadFrameGetter _PyThreadState_GetFrame");