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