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");