python.h
1 // Python Tools for Visual Studio 2 // Copyright(c) Microsoft Corporation 3 // All rights reserved. 4 // 5 // Licensed under the Apache License, Version 2.0 (the License); you may not use 6 // this file except in compliance with the License. You may obtain a copy of the 7 // License at http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // THIS CODE IS PROVIDED ON AN *AS IS* BASIS, WITHOUT WARRANTIES OR CONDITIONS 10 // OF ANY KIND, EITHER EXPRESS OR IMPLIED, INCLUDING WITHOUT LIMITATION ANY 11 // IMPLIED WARRANTIES OR CONDITIONS OF TITLE, FITNESS FOR A PARTICULAR PURPOSE, 12 // MERCHANTABILITY OR NON-INFRINGEMENT. 13 // 14 // See the Apache Version 2.0 License for specific language governing 15 // permissions and limitations under the License. 16 17 #ifndef __PYTHON_H__ 18 #define __PYTHON_H__ 19 20 #include "../common/py_version.hpp" 21 22 #include <cstdint> 23 24 #ifndef _WIN32 25 typedef unsigned int DWORD; 26 typedef ssize_t SSIZE_T; 27 #endif 28 typedef SSIZE_T Py_ssize_t; 29 30 // defines limited header of Python API for compatible access across a number of Pythons. 31 32 class PyTypeObject; 33 class PyThreadState; 34 35 #define PyObject_HEAD \ 36 size_t ob_refcnt; \ 37 PyTypeObject *ob_type; 38 39 #define PyObject_VAR_HEAD \ 40 PyObject_HEAD \ 41 size_t ob_size; /* Number of items in variable part */ 42 43 class PyObject { 44 public: 45 PyObject_HEAD 46 }; 47 48 class PyVarObject : public PyObject { 49 public: 50 size_t ob_size; /* Number of items in variable part */ 51 }; 52 53 // 2.5 - 3.7 54 class PyFunctionObject : public PyObject { 55 public: 56 PyObject *func_code; /* A code object */ 57 }; 58 59 // 2.5 - 2.7 compatible 60 class PyStringObject : public PyVarObject { 61 public: 62 long ob_shash; 63 int ob_sstate; 64 char ob_sval[1]; 65 66 /* Invariants: 67 * ob_sval contains space for 'ob_size+1' elements. 68 * ob_sval[ob_size] == 0. 69 * ob_shash is the hash of the string or -1 if not computed yet. 70 * ob_sstate != 0 iff the string object is in stringobject.c's 71 * 'interned' dictionary; in this case the two references 72 * from 'interned' to this object are *not counted* in ob_refcnt. 73 */ 74 }; 75 76 // 2.4 - 3.7 compatible 77 typedef struct { 78 PyObject_HEAD 79 size_t length; /* Length of raw Unicode data in buffer */ 80 wchar_t *str; /* Raw Unicode buffer */ 81 long hash; /* Hash value; -1 if not set */ 82 } PyUnicodeObject; 83 84 85 class PyFrameObject : public PyObject { 86 // After 3.10 we don't really have things we want to reuse common, so, 87 // create an empty base (it's not based on PyVarObject because on Python 3.11 88 // it's just a PyObject and no longer a PyVarObject -- the part related to 89 // the var object must be declared in ech subclass in this case). 90 }; 91 92 // 2.4 - 3.7 compatible 93 class PyFrameObjectBaseUpTo39 : public PyFrameObject { 94 public: 95 size_t ob_size; /* Number of items in variable part -- i.e.: PyVarObject*/ 96 97 PyFrameObjectBaseUpTo39 *f_back; /* previous frame, or nullptr */ 98 PyObject *f_code; /* code segment */ 99 PyObject *f_builtins; /* builtin symbol table (PyDictObject) */ 100 PyObject *f_globals; /* global symbol table (PyDictObject) */ 101 PyObject *f_locals; /* local symbol table (any mapping) */ 102 PyObject **f_valuestack; /* points after the last local */ 103 /* Next free slot in f_valuestack. Frame creation sets to f_valuestack. 104 Frame evaluation usually NULLs it, but a frame that yields sets it 105 to the current stack top. */ 106 PyObject **f_stacktop; 107 PyObject *f_trace; /* Trace function */ 108 109 // It has more things, but we're only interested in things up to f_trace. 110 111 }; 112 113 114 // https://github.com/python/cpython/blob/3.10/Include/cpython/frameobject.h 115 class PyFrameObject310 : public PyFrameObject { 116 public: 117 size_t ob_size; /* Number of items in variable part -- i.e.: PyVarObject*/ 118 119 PyFrameObject310 *f_back; /* previous frame, or NULL */ 120 PyObject *f_code; /* code segment */ 121 PyObject *f_builtins; /* builtin symbol table (PyDictObject) */ 122 PyObject *f_globals; /* global symbol table (PyDictObject) */ 123 PyObject *f_locals; /* local symbol table (any mapping) */ 124 PyObject **f_valuestack; /* points after the last local */ 125 PyObject *f_trace; /* Trace function */ 126 127 // It has more things, but we're only interested in things up to f_trace. 128 }; 129 130 typedef uint16_t _Py_CODEUNIT; 131 132 // https://github.com/python/cpython/blob/3.11/Include/internal/pycore_frame.h 133 typedef struct _PyInterpreterFrame311 { 134 /* "Specials" section */ 135 PyFunctionObject *f_func; /* Strong reference */ 136 PyObject *f_globals; /* Borrowed reference */ 137 PyObject *f_builtins; /* Borrowed reference */ 138 PyObject *f_locals; /* Strong reference, may be NULL */ 139 void *f_code; /* Strong reference */ 140 void *frame_obj; /* Strong reference, may be NULL */ 141 /* Linkage section */ 142 struct _PyInterpreterFrame311 *previous; 143 // NOTE: This is not necessarily the last instruction started in the given 144 // frame. Rather, it is the code unit *prior to* the *next* instruction. For 145 // example, it may be an inline CACHE entry, an instruction we just jumped 146 // over, or (in the case of a newly-created frame) a totally invalid value: 147 _Py_CODEUNIT *prev_instr; 148 int stacktop; /* Offset of TOS from localsplus */ 149 bool is_entry; // Whether this is the "root" frame for the current _PyCFrame. 150 char owner; 151 /* Locals and stack */ 152 PyObject *localsplus[1]; 153 } _PyInterpreterFrame311; 154 155 // https://github.com/python/cpython/blob/3.11/Include/internal/pycore_frame.h 156 // Note that in 3.11 it's no longer a "PyVarObject". 157 class PyFrameObject311 : public PyFrameObject { 158 public: 159 PyFrameObject311 *f_back; /* previous frame, or NULL */ 160 struct _PyInterpreterFrame311 *f_frame; /* points to the frame data */ 161 PyObject *f_trace; /* Trace function */ 162 int f_lineno; /* Current line number. Only valid if non-zero */ 163 char f_trace_lines; /* Emit per-line trace events? */ 164 char f_trace_opcodes; /* Emit per-opcode trace events? */ 165 char f_fast_as_locals; /* Have the fast locals of this frame been converted to a dict? */ 166 // It has more things, but we're not interested on those. 167 }; 168 169 170 typedef void (*destructor)(PyObject *); 171 172 // 2.4 - 3.7 173 class PyMethodDef { 174 public: 175 char *ml_name; /* The name of the built-in function/method */ 176 }; 177 178 179 // 180 // 2.5 - 3.7 181 // While these are compatible there are fields only available on later versions. 182 class PyTypeObject : public PyVarObject { 183 public: 184 const char *tp_name; /* For printing, in format "<module>.<name>" */ 185 size_t tp_basicsize, tp_itemsize; /* For allocation */ 186 187 /* Methods to implement standard operations */ 188 189 destructor tp_dealloc; 190 void *tp_print; 191 void *tp_getattr; 192 void *tp_setattr; 193 union { 194 void *tp_compare; /* 2.4 - 3.4 */ 195 void *tp_as_async; /* 3.5 - 3.7 */ 196 }; 197 void *tp_repr; 198 199 /* Method suites for standard classes */ 200 201 void *tp_as_number; 202 void *tp_as_sequence; 203 void *tp_as_mapping; 204 205 /* More standard operations (here for binary compatibility) */ 206 207 void *tp_hash; 208 void *tp_call; 209 void *tp_str; 210 void *tp_getattro; 211 void *tp_setattro; 212 213 /* Functions to access object as input/output buffer */ 214 void *tp_as_buffer; 215 216 /* Flags to define presence of optional/expanded features */ 217 long tp_flags; 218 219 const char *tp_doc; /* Documentation string */ 220 221 /* Assigned meaning in release 2.0 */ 222 /* call function for all accessible objects */ 223 void *tp_traverse; 224 225 /* delete references to contained objects */ 226 void *tp_clear; 227 228 /* Assigned meaning in release 2.1 */ 229 /* rich comparisons */ 230 void *tp_richcompare; 231 232 /* weak reference enabler */ 233 size_t tp_weaklistoffset; 234 235 /* Added in release 2.2 */ 236 /* Iterators */ 237 void *tp_iter; 238 void *tp_iternext; 239 240 /* Attribute descriptor and subclassing stuff */ 241 PyMethodDef *tp_methods; 242 struct PyMemberDef *tp_members; 243 struct PyGetSetDef *tp_getset; 244 struct _typeobject *tp_base; 245 PyObject *tp_dict; 246 void *tp_descr_get; 247 void *tp_descr_set; 248 size_t tp_dictoffset; 249 void *tp_init; 250 void *tp_alloc; 251 void *tp_new; 252 void *tp_free; /* Low-level free-memory routine */ 253 void *tp_is_gc; /* For PyObject_IS_GC */ 254 PyObject *tp_bases; 255 PyObject *tp_mro; /* method resolution order */ 256 PyObject *tp_cache; 257 PyObject *tp_subclasses; 258 PyObject *tp_weaklist; 259 void *tp_del; 260 261 /* Type attribute cache version tag. Added in version 2.6 */ 262 unsigned int tp_version_tag; 263 }; 264 265 // 2.4 - 3.7 266 class PyTupleObject : public PyVarObject { 267 public: 268 PyObject *ob_item[1]; 269 270 /* ob_item contains space for 'ob_size' elements. 271 * Items must normally not be nullptr, except during construction when 272 * the tuple is not yet visible outside the function that builds it. 273 */ 274 }; 275 276 // 2.4 - 3.7 277 class PyCFunctionObject : public PyObject { 278 public: 279 PyMethodDef *m_ml; /* Description of the C function to call */ 280 PyObject *m_self; /* Passed as 'self' arg to the C func, can be nullptr */ 281 PyObject *m_module; /* The __module__ attribute, can be anything */ 282 }; 283 284 typedef int (*Py_tracefunc)(PyObject *, PyFrameObject *, int, PyObject *); 285 286 #define PyTrace_CALL 0 287 #define PyTrace_EXCEPTION 1 288 #define PyTrace_LINE 2 289 #define PyTrace_RETURN 3 290 #define PyTrace_C_CALL 4 291 #define PyTrace_C_EXCEPTION 5 292 #define PyTrace_C_RETURN 6 293 294 class PyInterpreterState { 295 }; 296 297 class PyThreadState { }; 298 299 class PyThreadState_25_27 : public PyThreadState { 300 public: 301 /* See Python/ceval.c for comments explaining most fields */ 302 303 PyThreadState *next; 304 PyInterpreterState *interp; 305 306 PyFrameObjectBaseUpTo39 *frame; 307 int recursion_depth; 308 /* 'tracing' keeps track of the execution depth when tracing/profiling. 309 This is to prevent the actual trace/profile code from being recorded in 310 the trace/profile. */ 311 int tracing; 312 int use_tracing; 313 314 Py_tracefunc c_profilefunc; 315 Py_tracefunc c_tracefunc; 316 PyObject *c_profileobj; 317 PyObject *c_traceobj; 318 319 PyObject *curexc_type; 320 PyObject *curexc_value; 321 PyObject *curexc_traceback; 322 323 PyObject *exc_type; 324 PyObject *exc_value; 325 PyObject *exc_traceback; 326 327 PyObject *dict; /* Stores per-thread state */ 328 329 /* tick_counter is incremented whenever the check_interval ticker 330 * reaches zero. The purpose is to give a useful measure of the number 331 * of interpreted bytecode instructions in a given thread. This 332 * extremely lightweight statistic collector may be of interest to 333 * profilers (like psyco.jit()), although nothing in the core uses it. 334 */ 335 int tick_counter; 336 337 int gilstate_counter; 338 339 PyObject *async_exc; /* Asynchronous exception to raise */ 340 long thread_id; /* Thread id where this tstate was created */ 341 342 /* XXX signal handlers should also be here */ 343 static bool IsFor(int majorVersion, int minorVersion) { 344 return majorVersion == 2 && (minorVersion >= 5 && minorVersion <= 7); 345 } 346 347 static bool IsFor(PythonVersion version) { 348 return version >= PythonVersion_25 && version <= PythonVersion_27; 349 } 350 }; 351 352 class PyThreadState_30_33 : public PyThreadState { 353 public: 354 PyThreadState *next; 355 PyInterpreterState *interp; 356 357 PyFrameObjectBaseUpTo39 *frame; 358 int recursion_depth; 359 char overflowed; /* The stack has overflowed. Allow 50 more calls 360 to handle the runtime error. */ 361 char recursion_critical; /* The current calls must not cause 362 a stack overflow. */ 363 /* 'tracing' keeps track of the execution depth when tracing/profiling. 364 This is to prevent the actual trace/profile code from being recorded in 365 the trace/profile. */ 366 int tracing; 367 int use_tracing; 368 369 Py_tracefunc c_profilefunc; 370 Py_tracefunc c_tracefunc; 371 PyObject *c_profileobj; 372 PyObject *c_traceobj; 373 374 PyObject *curexc_type; 375 PyObject *curexc_value; 376 PyObject *curexc_traceback; 377 378 PyObject *exc_type; 379 PyObject *exc_value; 380 PyObject *exc_traceback; 381 382 PyObject *dict; /* Stores per-thread state */ 383 384 /* tick_counter is incremented whenever the check_interval ticker 385 * reaches zero. The purpose is to give a useful measure of the number 386 * of interpreted bytecode instructions in a given thread. This 387 * extremely lightweight statistic collector may be of interest to 388 * profilers (like psyco.jit()), although nothing in the core uses it. 389 */ 390 int tick_counter; 391 392 int gilstate_counter; 393 394 PyObject *async_exc; /* Asynchronous exception to raise */ 395 long thread_id; /* Thread id where this tstate was created */ 396 397 /* XXX signal handlers should also be here */ 398 static bool IsFor(int majorVersion, int minorVersion) { 399 return majorVersion == 3 && (minorVersion >= 0 && minorVersion <= 3); 400 } 401 402 static bool IsFor(PythonVersion version) { 403 return version >= PythonVersion_30 && version <= PythonVersion_33; 404 } 405 }; 406 407 class PyThreadState_34_36 : public PyThreadState { 408 public: 409 PyThreadState *prev; 410 PyThreadState *next; 411 PyInterpreterState *interp; 412 413 PyFrameObjectBaseUpTo39 *frame; 414 int recursion_depth; 415 char overflowed; /* The stack has overflowed. Allow 50 more calls 416 to handle the runtime error. */ 417 char recursion_critical; /* The current calls must not cause 418 a stack overflow. */ 419 /* 'tracing' keeps track of the execution depth when tracing/profiling. 420 This is to prevent the actual trace/profile code from being recorded in 421 the trace/profile. */ 422 int tracing; 423 int use_tracing; 424 425 Py_tracefunc c_profilefunc; 426 Py_tracefunc c_tracefunc; 427 PyObject *c_profileobj; 428 PyObject *c_traceobj; 429 430 PyObject *curexc_type; 431 PyObject *curexc_value; 432 PyObject *curexc_traceback; 433 434 PyObject *exc_type; 435 PyObject *exc_value; 436 PyObject *exc_traceback; 437 438 PyObject *dict; /* Stores per-thread state */ 439 440 int gilstate_counter; 441 442 PyObject *async_exc; /* Asynchronous exception to raise */ 443 444 long thread_id; /* Thread id where this tstate was created */ 445 /* XXX signal handlers should also be here */ 446 447 static bool IsFor(int majorVersion, int minorVersion) { 448 return majorVersion == 3 && minorVersion >= 4 && minorVersion <= 6; 449 } 450 451 static bool IsFor(PythonVersion version) { 452 return version >= PythonVersion_34 && version <= PythonVersion_36; 453 } 454 }; 455 456 struct _PyErr_StackItem { 457 PyObject *exc_type, *exc_value, *exc_traceback; 458 struct _PyErr_StackItem *previous_item; 459 }; 460 461 462 class PyThreadState_37_38 : public PyThreadState { 463 public: 464 PyThreadState *prev; 465 PyThreadState *next; 466 PyInterpreterState *interp; 467 468 PyFrameObjectBaseUpTo39 *frame; 469 int recursion_depth; 470 char overflowed; /* The stack has overflowed. Allow 50 more calls 471 to handle the runtime error. */ 472 char recursion_critical; /* The current calls must not cause 473 a stack overflow. */ 474 /* 'tracing' keeps track of the execution depth when tracing/profiling. 475 This is to prevent the actual trace/profile code from being recorded in 476 the trace/profile. */ 477 int stackcheck_counter; 478 479 int tracing; 480 int use_tracing; 481 482 Py_tracefunc c_profilefunc; 483 Py_tracefunc c_tracefunc; 484 PyObject *c_profileobj; 485 PyObject *c_traceobj; 486 487 PyObject *curexc_type; 488 PyObject *curexc_value; 489 PyObject *curexc_traceback; 490 491 _PyErr_StackItem exc_state; 492 _PyErr_StackItem *exc_info; 493 494 PyObject *dict; /* Stores per-thread state */ 495 496 int gilstate_counter; 497 498 PyObject *async_exc; /* Asynchronous exception to raise */ 499 500 unsigned long thread_id; /* Thread id where this tstate was created */ 501 502 static bool IsFor(int majorVersion, int minorVersion) { 503 return majorVersion == 3 && (minorVersion == 7 || minorVersion == 8); 504 } 505 506 static bool IsFor(PythonVersion version) { 507 return version == PythonVersion_37 || version == PythonVersion_38; 508 } 509 }; 510 511 // i.e.: https://github.com/python/cpython/blob/master/Include/cpython/pystate.h 512 class PyThreadState_39 : public PyThreadState { 513 public: 514 PyThreadState *prev; 515 PyThreadState *next; 516 PyInterpreterState *interp; 517 518 PyFrameObjectBaseUpTo39 *frame; 519 int recursion_depth; 520 char overflowed; /* The stack has overflowed. Allow 50 more calls 521 to handle the runtime error. */ 522 int stackcheck_counter; 523 524 int tracing; 525 int use_tracing; 526 527 Py_tracefunc c_profilefunc; 528 Py_tracefunc c_tracefunc; 529 PyObject *c_profileobj; 530 PyObject *c_traceobj; 531 532 PyObject *curexc_type; 533 PyObject *curexc_value; 534 PyObject *curexc_traceback; 535 536 _PyErr_StackItem exc_state; 537 _PyErr_StackItem *exc_info; 538 539 PyObject *dict; /* Stores per-thread state */ 540 541 int gilstate_counter; 542 543 PyObject *async_exc; /* Asynchronous exception to raise */ 544 545 unsigned long thread_id; /* Thread id where this tstate was created */ 546 547 static bool IsFor(int majorVersion, int minorVersion) { 548 return majorVersion == 3 && minorVersion == 9; 549 } 550 551 static bool IsFor(PythonVersion version) { 552 return version == PythonVersion_39; 553 } 554 }; 555 556 typedef struct _cframe { 557 /* This struct will be threaded through the C stack 558 * allowing fast access to per-thread state that needs 559 * to be accessed quickly by the interpreter, but can 560 * be modified outside of the interpreter. 561 * 562 * WARNING: This makes data on the C stack accessible from 563 * heap objects. Care must be taken to maintain stack 564 * discipline and make sure that instances of this struct cannot 565 * accessed outside of their lifetime. 566 */ 567 int use_tracing; 568 struct _cframe *previous; 569 } CFrame; 570 571 // i.e.: https://github.com/python/cpython/blob/master/Include/cpython/pystate.h 572 class PyThreadState_310 : public PyThreadState { 573 public: 574 PyThreadState *prev; 575 PyThreadState *next; 576 PyInterpreterState *interp; 577 578 PyFrameObject310 *frame; 579 int recursion_depth; 580 int recursion_headroom; /* Allow 50 more calls to handle any errors. */ 581 int stackcheck_counter; 582 583 /* 'tracing' keeps track of the execution depth when tracing/profiling. 584 This is to prevent the actual trace/profile code from being recorded in 585 the trace/profile. */ 586 int tracing; 587 588 /* Pointer to current CFrame in the C stack frame of the currently, 589 * or most recently, executing _PyEval_EvalFrameDefault. */ 590 CFrame *cframe; 591 592 593 Py_tracefunc c_profilefunc; 594 Py_tracefunc c_tracefunc; 595 PyObject *c_profileobj; 596 PyObject *c_traceobj; 597 598 PyObject *curexc_type; 599 PyObject *curexc_value; 600 PyObject *curexc_traceback; 601 602 _PyErr_StackItem exc_state; 603 _PyErr_StackItem *exc_info; 604 605 PyObject *dict; /* Stores per-thread state */ 606 607 int gilstate_counter; 608 609 PyObject *async_exc; /* Asynchronous exception to raise */ 610 611 unsigned long thread_id; /* Thread id where this tstate was created */ 612 613 static bool IsFor(int majorVersion, int minorVersion) { 614 return majorVersion == 3 && minorVersion == 10; 615 } 616 617 static bool IsFor(PythonVersion version) { 618 return version == PythonVersion_310; 619 } 620 }; 621 622 // i.e.: https://github.com/python/cpython/blob/3.11/Include/cpython/pystate.h 623 class PyThreadState_311 : public PyThreadState { 624 public: 625 PyThreadState *prev; 626 PyThreadState *next; 627 PyInterpreterState *interp; 628 629 int _initialized; 630 631 int _static; 632 633 int recursion_remaining; 634 int recursion_limit; 635 int recursion_headroom; /* Allow 50 more calls to handle any errors. */ 636 637 /* 'tracing' keeps track of the execution depth when tracing/profiling. 638 This is to prevent the actual trace/profile code from being recorded in 639 the trace/profile. */ 640 int tracing; 641 int tracing_what; 642 643 /* Pointer to current CFrame in the C stack frame of the currently, 644 * or most recently, executing _PyEval_EvalFrameDefault. */ 645 CFrame *cframe; 646 647 648 Py_tracefunc c_profilefunc; 649 Py_tracefunc c_tracefunc; 650 PyObject *c_profileobj; 651 PyObject *c_traceobj; 652 653 PyObject *curexc_type; 654 PyObject *curexc_value; 655 PyObject *curexc_traceback; 656 657 _PyErr_StackItem *exc_info; 658 659 PyObject *dict; /* Stores per-thread state */ 660 661 int gilstate_counter; 662 663 PyObject *async_exc; /* Asynchronous exception to raise */ 664 665 unsigned long thread_id; /* Thread id where this tstate was created */ 666 667 static bool IsFor(int majorVersion, int minorVersion) { 668 return majorVersion == 3 && minorVersion == 11; 669 } 670 671 static bool IsFor(PythonVersion version) { 672 return version == PythonVersion_311; 673 } 674 }; 675 676 class PyIntObject : public PyObject { 677 public: 678 long ob_ival; 679 }; 680 681 class Py3kLongObject : public PyVarObject { 682 public: 683 DWORD ob_digit[1]; 684 }; 685 686 class PyOldStyleClassObject : public PyObject { 687 public: 688 PyObject *cl_bases; /* A tuple of class objects */ 689 PyObject *cl_dict; /* A dictionary */ 690 PyObject *cl_name; /* A string */ 691 /* The following three are functions or nullptr */ 692 PyObject *cl_getattr; 693 PyObject *cl_setattr; 694 PyObject *cl_delattr; 695 }; 696 697 class PyInstanceObject : public PyObject { 698 public: 699 PyOldStyleClassObject *in_class; /* The class object */ 700 PyObject *in_dict; /* A dictionary */ 701 PyObject *in_weakreflist; /* List of weak references */ 702 }; 703 704 #endif