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