LCOV - code coverage report
Current view: top level - Include/cpython - code.h (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit 5e6661bce9] Lines: 6 10 60.0 %
Date: 2023-03-20 08:15:36 Functions: 3 5 60.0 %
Branches: 0 0 -

           Branch data     Line data    Source code
       1                 :            : /* Definitions for bytecode */
       2                 :            : 
       3                 :            : #ifndef Py_LIMITED_API
       4                 :            : #ifndef Py_CODE_H
       5                 :            : #define Py_CODE_H
       6                 :            : #ifdef __cplusplus
       7                 :            : extern "C" {
       8                 :            : #endif
       9                 :            : 
      10                 :            : /* Each instruction in a code object is a fixed-width value,
      11                 :            :  * currently 2 bytes: 1-byte opcode + 1-byte oparg.  The EXTENDED_ARG
      12                 :            :  * opcode allows for larger values but the current limit is 3 uses
      13                 :            :  * of EXTENDED_ARG (see Python/compile.c), for a maximum
      14                 :            :  * 32-bit value.  This aligns with the note in Python/compile.c
      15                 :            :  * (compiler_addop_i_line) indicating that the max oparg value is
      16                 :            :  * 2**32 - 1, rather than INT_MAX.
      17                 :            :  */
      18                 :            : 
      19                 :            : typedef union {
      20                 :            :     uint16_t cache;
      21                 :            :     struct {
      22                 :            :         uint8_t code;
      23                 :            :         uint8_t arg;
      24                 :            :     } op;
      25                 :            : } _Py_CODEUNIT;
      26                 :            : 
      27                 :            : 
      28                 :            : /* These macros only remain defined for compatibility. */
      29                 :            : #define _Py_OPCODE(word) ((word).op.code)
      30                 :            : #define _Py_OPARG(word) ((word).op.arg)
      31                 :            : 
      32                 :            : static inline _Py_CODEUNIT
      33                 :            : _py_make_codeunit(uint8_t opcode, uint8_t oparg)
      34                 :            : {
      35                 :            :     // No designated initialisers because of C++ compat
      36                 :            :     _Py_CODEUNIT word;
      37                 :            :     word.op.code = opcode;
      38                 :            :     word.op.arg = oparg;
      39                 :            :     return word;
      40                 :            : }
      41                 :            : 
      42                 :            : static inline void
      43                 :            : _py_set_opcode(_Py_CODEUNIT *word, uint8_t opcode)
      44                 :            : {
      45                 :            :     word->op.code = opcode;
      46                 :            : }
      47                 :            : 
      48                 :            : #define _Py_MAKE_CODEUNIT(opcode, oparg) _py_make_codeunit((opcode), (oparg))
      49                 :            : #define _Py_SET_OPCODE(word, opcode) _py_set_opcode(&(word), (opcode))
      50                 :            : 
      51                 :            : 
      52                 :            : typedef struct {
      53                 :            :     PyObject *_co_code;
      54                 :            :     PyObject *_co_varnames;
      55                 :            :     PyObject *_co_cellvars;
      56                 :            :     PyObject *_co_freevars;
      57                 :            : } _PyCoCached;
      58                 :            : 
      59                 :            : // To avoid repeating ourselves in deepfreeze.py, all PyCodeObject members are
      60                 :            : // defined in this macro:
      61                 :            : #define _PyCode_DEF(SIZE) {                                                    \
      62                 :            :     PyObject_VAR_HEAD                                                          \
      63                 :            :                                                                                \
      64                 :            :     /* Note only the following fields are used in hash and/or comparisons      \
      65                 :            :      *                                                                         \
      66                 :            :      * - co_name                                                               \
      67                 :            :      * - co_argcount                                                           \
      68                 :            :      * - co_posonlyargcount                                                    \
      69                 :            :      * - co_kwonlyargcount                                                     \
      70                 :            :      * - co_nlocals                                                            \
      71                 :            :      * - co_stacksize                                                          \
      72                 :            :      * - co_flags                                                              \
      73                 :            :      * - co_firstlineno                                                        \
      74                 :            :      * - co_consts                                                             \
      75                 :            :      * - co_names                                                              \
      76                 :            :      * - co_localsplusnames                                                    \
      77                 :            :      * This is done to preserve the name and line number for tracebacks        \
      78                 :            :      * and debuggers; otherwise, constant de-duplication would collapse        \
      79                 :            :      * identical functions/lambdas defined on different lines.                 \
      80                 :            :      */                                                                        \
      81                 :            :                                                                                \
      82                 :            :     /* These fields are set with provided values on new code objects. */       \
      83                 :            :                                                                                \
      84                 :            :     /* The hottest fields (in the eval loop) are grouped here at the top. */   \
      85                 :            :     PyObject *co_consts;           /* list (constants used) */                 \
      86                 :            :     PyObject *co_names;            /* list of strings (names used) */          \
      87                 :            :     PyObject *co_exceptiontable;   /* Byte string encoding exception handling  \
      88                 :            :                                       table */                                 \
      89                 :            :     int co_flags;                  /* CO_..., see below */                     \
      90                 :            :     short _co_linearray_entry_size;  /* Size of each entry in _co_linearray */ \
      91                 :            :                                                                                \
      92                 :            :     /* The rest are not so impactful on performance. */                        \
      93                 :            :     int co_argcount;              /* #arguments, except *args */               \
      94                 :            :     int co_posonlyargcount;       /* #positional only arguments */             \
      95                 :            :     int co_kwonlyargcount;        /* #keyword only arguments */                \
      96                 :            :     int co_stacksize;             /* #entries needed for evaluation stack */   \
      97                 :            :     int co_firstlineno;           /* first source line number */               \
      98                 :            :                                                                                \
      99                 :            :     /* redundant values (derived from co_localsplusnames and                   \
     100                 :            :        co_localspluskinds) */                                                  \
     101                 :            :     int co_nlocalsplus;           /* number of local + cell + free variables */ \
     102                 :            :     int co_framesize;             /* Size of frame in words */                 \
     103                 :            :     int co_nlocals;               /* number of local variables */              \
     104                 :            :     int co_ncellvars;             /* total number of cell variables */         \
     105                 :            :     int co_nfreevars;             /* number of free variables */               \
     106                 :            :     uint32_t co_version;          /* version number */                         \
     107                 :            :                                                                                \
     108                 :            :     PyObject *co_localsplusnames; /* tuple mapping offsets to names */         \
     109                 :            :     PyObject *co_localspluskinds; /* Bytes mapping to local kinds (one byte    \
     110                 :            :                                      per variable) */                          \
     111                 :            :     PyObject *co_filename;        /* unicode (where it was loaded from) */     \
     112                 :            :     PyObject *co_name;            /* unicode (name, for reference) */          \
     113                 :            :     PyObject *co_qualname;        /* unicode (qualname, for reference) */      \
     114                 :            :     PyObject *co_linetable;       /* bytes object that holds location info */  \
     115                 :            :     PyObject *co_weakreflist;     /* to support weakrefs to code objects */    \
     116                 :            :     _PyCoCached *_co_cached;      /* cached co_* attributes */                 \
     117                 :            :     int _co_firsttraceable;       /* index of first traceable instruction */   \
     118                 :            :     char *_co_linearray;          /* array of line offsets */                  \
     119                 :            :     /* Scratch space for extra data relating to the code object.               \
     120                 :            :        Type is a void* to keep the format private in codeobject.c to force     \
     121                 :            :        people to go through the proper APIs. */                                \
     122                 :            :     void *co_extra;                                                            \
     123                 :            :     char co_code_adaptive[(SIZE)];                                             \
     124                 :            : }
     125                 :            : 
     126                 :            : /* Bytecode object */
     127                 :            : struct PyCodeObject _PyCode_DEF(1);
     128                 :            : 
     129                 :            : /* Masks for co_flags above */
     130                 :            : #define CO_OPTIMIZED    0x0001
     131                 :            : #define CO_NEWLOCALS    0x0002
     132                 :            : #define CO_VARARGS      0x0004
     133                 :            : #define CO_VARKEYWORDS  0x0008
     134                 :            : #define CO_NESTED       0x0010
     135                 :            : #define CO_GENERATOR    0x0020
     136                 :            : 
     137                 :            : /* The CO_COROUTINE flag is set for coroutine functions (defined with
     138                 :            :    ``async def`` keywords) */
     139                 :            : #define CO_COROUTINE            0x0080
     140                 :            : #define CO_ITERABLE_COROUTINE   0x0100
     141                 :            : #define CO_ASYNC_GENERATOR      0x0200
     142                 :            : 
     143                 :            : /* bpo-39562: These constant values are changed in Python 3.9
     144                 :            :    to prevent collision with compiler flags. CO_FUTURE_ and PyCF_
     145                 :            :    constants must be kept unique. PyCF_ constants can use bits from
     146                 :            :    0x0100 to 0x10000. CO_FUTURE_ constants use bits starting at 0x20000. */
     147                 :            : #define CO_FUTURE_DIVISION      0x20000
     148                 :            : #define CO_FUTURE_ABSOLUTE_IMPORT 0x40000 /* do absolute imports by default */
     149                 :            : #define CO_FUTURE_WITH_STATEMENT  0x80000
     150                 :            : #define CO_FUTURE_PRINT_FUNCTION  0x100000
     151                 :            : #define CO_FUTURE_UNICODE_LITERALS 0x200000
     152                 :            : 
     153                 :            : #define CO_FUTURE_BARRY_AS_BDFL  0x400000
     154                 :            : #define CO_FUTURE_GENERATOR_STOP  0x800000
     155                 :            : #define CO_FUTURE_ANNOTATIONS    0x1000000
     156                 :            : 
     157                 :            : /* This should be defined if a future statement modifies the syntax.
     158                 :            :    For example, when a keyword is added.
     159                 :            : */
     160                 :            : #define PY_PARSER_REQUIRES_FUTURE_KEYWORD
     161                 :            : 
     162                 :            : #define CO_MAXBLOCKS 20 /* Max static block nesting within a function */
     163                 :            : 
     164                 :            : PyAPI_DATA(PyTypeObject) PyCode_Type;
     165                 :            : 
     166                 :            : #define PyCode_Check(op) Py_IS_TYPE((op), &PyCode_Type)
     167                 :            : 
     168                 :        698 : static inline Py_ssize_t PyCode_GetNumFree(PyCodeObject *op) {
     169                 :            :     assert(PyCode_Check(op));
     170                 :        698 :     return op->co_nfreevars;
     171                 :            : }
     172                 :            : 
     173                 :      18824 : static inline int PyCode_GetFirstFree(PyCodeObject *op) {
     174                 :            :     assert(PyCode_Check(op));
     175                 :      18824 :     return op->co_nlocalsplus - op->co_nfreevars;
     176                 :            : }
     177                 :            : 
     178                 :            : #define _PyCode_CODE(CO) _Py_RVALUE((_Py_CODEUNIT *)(CO)->co_code_adaptive)
     179                 :            : #define _PyCode_NBYTES(CO) (Py_SIZE(CO) * (Py_ssize_t)sizeof(_Py_CODEUNIT))
     180                 :            : 
     181                 :            : /* Unstable public interface */
     182                 :            : PyAPI_FUNC(PyCodeObject *) PyUnstable_Code_New(
     183                 :            :         int, int, int, int, int, PyObject *, PyObject *,
     184                 :            :         PyObject *, PyObject *, PyObject *, PyObject *,
     185                 :            :         PyObject *, PyObject *, PyObject *, int, PyObject *,
     186                 :            :         PyObject *);
     187                 :            : 
     188                 :            : PyAPI_FUNC(PyCodeObject *) PyUnstable_Code_NewWithPosOnlyArgs(
     189                 :            :         int, int, int, int, int, int, PyObject *, PyObject *,
     190                 :            :         PyObject *, PyObject *, PyObject *, PyObject *,
     191                 :            :         PyObject *, PyObject *, PyObject *, int, PyObject *,
     192                 :            :         PyObject *);
     193                 :            :         /* same as struct above */
     194                 :            : // Old names -- remove when this API changes:
     195                 :            : _Py_DEPRECATED_EXTERNALLY(3.12) static inline PyCodeObject *
     196                 :            : PyCode_New(
     197                 :            :         int a, int b, int c, int d, int e, PyObject *f, PyObject *g,
     198                 :            :         PyObject *h, PyObject *i, PyObject *j, PyObject *k,
     199                 :            :         PyObject *l, PyObject *m, PyObject *n, int o, PyObject *p,
     200                 :            :         PyObject *q)
     201                 :            : {
     202                 :            :     return PyUnstable_Code_New(
     203                 :            :         a, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q);
     204                 :            : }
     205                 :            : _Py_DEPRECATED_EXTERNALLY(3.12) static inline PyCodeObject *
     206                 :          1 : PyCode_NewWithPosOnlyArgs(
     207                 :            :         int a, int poac, int b, int c, int d, int e, PyObject *f, PyObject *g,
     208                 :            :         PyObject *h, PyObject *i, PyObject *j, PyObject *k,
     209                 :            :         PyObject *l, PyObject *m, PyObject *n, int o, PyObject *p,
     210                 :            :         PyObject *q)
     211                 :            : {
     212                 :          1 :     return PyUnstable_Code_NewWithPosOnlyArgs(
     213                 :            :         a, poac, b, c, d, e, f, g, h, i, j, k, l, m, n, o, p, q);
     214                 :            : }
     215                 :            : 
     216                 :            : /* Creates a new empty code object with the specified source location. */
     217                 :            : PyAPI_FUNC(PyCodeObject *)
     218                 :            : PyCode_NewEmpty(const char *filename, const char *funcname, int firstlineno);
     219                 :            : 
     220                 :            : /* Return the line number associated with the specified bytecode index
     221                 :            :    in this code object.  If you just need the line number of a frame,
     222                 :            :    use PyFrame_GetLineNumber() instead. */
     223                 :            : PyAPI_FUNC(int) PyCode_Addr2Line(PyCodeObject *, int);
     224                 :            : 
     225                 :            : PyAPI_FUNC(int) PyCode_Addr2Location(PyCodeObject *, int, int *, int *, int *, int *);
     226                 :            : 
     227                 :            : #define PY_FOREACH_CODE_EVENT(V) \
     228                 :            :     V(CREATE)                 \
     229                 :            :     V(DESTROY)
     230                 :            : 
     231                 :            : typedef enum {
     232                 :            :     #define PY_DEF_EVENT(op) PY_CODE_EVENT_##op,
     233                 :            :     PY_FOREACH_CODE_EVENT(PY_DEF_EVENT)
     234                 :            :     #undef PY_DEF_EVENT
     235                 :            : } PyCodeEvent;
     236                 :            : 
     237                 :            : 
     238                 :            : /*
     239                 :            :  * A callback that is invoked for different events in a code object's lifecycle.
     240                 :            :  *
     241                 :            :  * The callback is invoked with a borrowed reference to co, after it is
     242                 :            :  * created and before it is destroyed.
     243                 :            :  *
     244                 :            :  * If the callback sets an exception, it must return -1. Otherwise
     245                 :            :  * it should return 0.
     246                 :            :  */
     247                 :            : typedef int (*PyCode_WatchCallback)(
     248                 :            :   PyCodeEvent event,
     249                 :            :   PyCodeObject* co);
     250                 :            : 
     251                 :            : /*
     252                 :            :  * Register a per-interpreter callback that will be invoked for code object
     253                 :            :  * lifecycle events.
     254                 :            :  *
     255                 :            :  * Returns a handle that may be passed to PyCode_ClearWatcher on success,
     256                 :            :  * or -1 and sets an error if no more handles are available.
     257                 :            :  */
     258                 :            : PyAPI_FUNC(int) PyCode_AddWatcher(PyCode_WatchCallback callback);
     259                 :            : 
     260                 :            : /*
     261                 :            :  * Clear the watcher associated with the watcher_id handle.
     262                 :            :  *
     263                 :            :  * Returns 0 on success or -1 if no watcher exists for the provided id.
     264                 :            :  */
     265                 :            : PyAPI_FUNC(int) PyCode_ClearWatcher(int watcher_id);
     266                 :            : 
     267                 :            : /* for internal use only */
     268                 :            : struct _opaque {
     269                 :            :     int computed_line;
     270                 :            :     const uint8_t *lo_next;
     271                 :            :     const uint8_t *limit;
     272                 :            : };
     273                 :            : 
     274                 :            : typedef struct _line_offsets {
     275                 :            :     int ar_start;
     276                 :            :     int ar_end;
     277                 :            :     int ar_line;
     278                 :            :     struct _opaque opaque;
     279                 :            : } PyCodeAddressRange;
     280                 :            : 
     281                 :            : /* Update *bounds to describe the first and one-past-the-last instructions in the
     282                 :            :    same line as lasti.  Return the number of that line.
     283                 :            : */
     284                 :            : PyAPI_FUNC(int) _PyCode_CheckLineNumber(int lasti, PyCodeAddressRange *bounds);
     285                 :            : 
     286                 :            : /* Create a comparable key used to compare constants taking in account the
     287                 :            :  * object type. It is used to make sure types are not coerced (e.g., float and
     288                 :            :  * complex) _and_ to distinguish 0.0 from -0.0 e.g. on IEEE platforms
     289                 :            :  *
     290                 :            :  * Return (type(obj), obj, ...): a tuple with variable size (at least 2 items)
     291                 :            :  * depending on the type and the value. The type is the first item to not
     292                 :            :  * compare bytes and str which can raise a BytesWarning exception. */
     293                 :            : PyAPI_FUNC(PyObject*) _PyCode_ConstantKey(PyObject *obj);
     294                 :            : 
     295                 :            : PyAPI_FUNC(PyObject*) PyCode_Optimize(PyObject *code, PyObject* consts,
     296                 :            :                                       PyObject *names, PyObject *lnotab);
     297                 :            : 
     298                 :            : PyAPI_FUNC(int) PyUnstable_Code_GetExtra(
     299                 :            :     PyObject *code, Py_ssize_t index, void **extra);
     300                 :            : PyAPI_FUNC(int) PyUnstable_Code_SetExtra(
     301                 :            :     PyObject *code, Py_ssize_t index, void *extra);
     302                 :            : // Old names -- remove when this API changes:
     303                 :            : _Py_DEPRECATED_EXTERNALLY(3.12) static inline int
     304                 :          0 : _PyCode_GetExtra(PyObject *code, Py_ssize_t index, void **extra)
     305                 :            : {
     306                 :          0 :     return PyUnstable_Code_GetExtra(code, index, extra);
     307                 :            : }
     308                 :            : _Py_DEPRECATED_EXTERNALLY(3.12) static inline int
     309                 :          0 : _PyCode_SetExtra(PyObject *code, Py_ssize_t index, void *extra)
     310                 :            : {
     311                 :          0 :     return PyUnstable_Code_SetExtra(code, index, extra);
     312                 :            : }
     313                 :            : 
     314                 :            : /* Equivalent to getattr(code, 'co_code') in Python.
     315                 :            :    Returns a strong reference to a bytes object. */
     316                 :            : PyAPI_FUNC(PyObject *) PyCode_GetCode(PyCodeObject *code);
     317                 :            : /* Equivalent to getattr(code, 'co_varnames') in Python. */
     318                 :            : PyAPI_FUNC(PyObject *) PyCode_GetVarnames(PyCodeObject *code);
     319                 :            : /* Equivalent to getattr(code, 'co_cellvars') in Python. */
     320                 :            : PyAPI_FUNC(PyObject *) PyCode_GetCellvars(PyCodeObject *code);
     321                 :            : /* Equivalent to getattr(code, 'co_freevars') in Python. */
     322                 :            : PyAPI_FUNC(PyObject *) PyCode_GetFreevars(PyCodeObject *code);
     323                 :            : 
     324                 :            : typedef enum _PyCodeLocationInfoKind {
     325                 :            :     /* short forms are 0 to 9 */
     326                 :            :     PY_CODE_LOCATION_INFO_SHORT0 = 0,
     327                 :            :     /* one lineforms are 10 to 12 */
     328                 :            :     PY_CODE_LOCATION_INFO_ONE_LINE0 = 10,
     329                 :            :     PY_CODE_LOCATION_INFO_ONE_LINE1 = 11,
     330                 :            :     PY_CODE_LOCATION_INFO_ONE_LINE2 = 12,
     331                 :            : 
     332                 :            :     PY_CODE_LOCATION_INFO_NO_COLUMNS = 13,
     333                 :            :     PY_CODE_LOCATION_INFO_LONG = 14,
     334                 :            :     PY_CODE_LOCATION_INFO_NONE = 15
     335                 :            : } _PyCodeLocationInfoKind;
     336                 :            : 
     337                 :            : #ifdef __cplusplus
     338                 :            : }
     339                 :            : #endif
     340                 :            : #endif  // !Py_CODE_H
     341                 :            : #endif  // !Py_LIMITED_API

Generated by: LCOV version 1.14