Coverage Report

Created: 2026-07-14 06:16

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