Coverage Report

Created: 2025-07-04 06:49

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