Coverage Report

Created: 2026-01-17 06:16

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython/Python/compile.c
Line
Count
Source
1
/*
2
 * This file compiles an abstract syntax tree (AST) into Python bytecode.
3
 *
4
 * The primary entry point is _PyAST_Compile(), which returns a
5
 * PyCodeObject.  The compiler makes several passes to build the code
6
 * object:
7
 *   1. Checks for future statements.  See future.c
8
 *   2. Builds a symbol table.  See symtable.c.
9
 *   3. Generate an instruction sequence. See compiler_mod() in this file, which
10
 *      calls functions from codegen.c.
11
 *   4. Generate a control flow graph and run optimizations on it.  See flowgraph.c.
12
 *   5. Assemble the basic blocks into final code.  See optimize_and_assemble() in
13
 *      this file, and assembler.c.
14
 *
15
 */
16
17
#include "Python.h"
18
#include "pycore_ast.h"           // PyAST_Check()
19
#include "pycore_code.h"
20
#include "pycore_compile.h"
21
#include "pycore_flowgraph.h"     // _PyCfg_FromInstructionSequence()
22
#include "pycore_pystate.h"       // _Py_GetConfig()
23
#include "pycore_runtime.h"       // _Py_ID()
24
#include "pycore_setobject.h"     // _PySet_NextEntry()
25
#include "pycore_stats.h"
26
#include "pycore_unicodeobject.h" // _PyUnicode_EqualToASCIIString()
27
28
#include "cpython/code.h"
29
30
#include <stdbool.h>
31
32
33
#undef SUCCESS
34
#undef ERROR
35
228k
#define SUCCESS 0
36
1
#define ERROR -1
37
38
#define RETURN_IF_ERROR(X)  \
39
82.0k
    do {                    \
40
82.0k
        if ((X) == -1) {    \
41
0
            return ERROR;   \
42
0
        }                   \
43
82.0k
    } while (0)
44
45
typedef _Py_SourceLocation location;
46
typedef _PyJumpTargetLabel jump_target_label;
47
typedef _PyInstructionSequence instr_sequence;
48
typedef struct _PyCfgBuilder cfg_builder;
49
typedef _PyCompile_FBlockInfo fblockinfo;
50
typedef enum _PyCompile_FBlockType fblocktype;
51
52
/* The following items change on entry and exit of code blocks.
53
   They must be saved and restored when returning to a block.
54
*/
55
struct compiler_unit {
56
    PySTEntryObject *u_ste;
57
58
    int u_scope_type;
59
60
    PyObject *u_private;            /* for private name mangling */
61
    PyObject *u_static_attributes;  /* for class: attributes accessed via self.X */
62
    PyObject *u_deferred_annotations; /* AnnAssign nodes deferred to the end of compilation */
63
    PyObject *u_conditional_annotation_indices;  /* indices of annotations that are conditionally executed (or -1 for unconditional annotations) */
64
    long u_next_conditional_annotation_index;  /* index of the next conditional annotation */
65
66
    instr_sequence *u_instr_sequence; /* codegen output */
67
    instr_sequence *u_stashed_instr_sequence; /* temporarily stashed parent instruction sequence */
68
69
    int u_nfblocks;
70
    int u_in_inlined_comp;
71
    int u_in_conditional_block;
72
73
    _PyCompile_FBlockInfo u_fblock[CO_MAXBLOCKS];
74
75
    _PyCompile_CodeUnitMetadata u_metadata;
76
};
77
78
/* This struct captures the global state of a compilation.
79
80
The u pointer points to the current compilation unit, while units
81
for enclosing blocks are stored in c_stack.     The u and c_stack are
82
managed by _PyCompile_EnterScope() and _PyCompile_ExitScope().
83
84
Note that we don't track recursion levels during compilation - the
85
task of detecting and rejecting excessive levels of nesting is
86
handled by the symbol analysis pass.
87
88
*/
89
90
typedef struct _PyCompiler {
91
    PyObject *c_filename;
92
    struct symtable *c_st;
93
    _PyFutureFeatures c_future;  /* module's __future__ */
94
    PyCompilerFlags c_flags;
95
96
    int c_optimize;              /* optimization level */
97
    int c_interactive;           /* true if in interactive mode */
98
    PyObject *c_const_cache;     /* Python dict holding all constants,
99
                                    including names tuple */
100
    struct compiler_unit *u;     /* compiler state for current block */
101
    PyObject *c_stack;           /* Python list holding compiler_unit ptrs */
102
103
    bool c_save_nested_seqs;     /* if true, construct recursive instruction sequences
104
                                  * (including instructions for nested code objects)
105
                                  */
106
    int c_disable_warning;
107
    PyObject *c_module;
108
} compiler;
109
110
static int
111
compiler_setup(compiler *c, mod_ty mod, PyObject *filename,
112
               PyCompilerFlags *flags, int optimize, PyArena *arena,
113
               PyObject *module)
114
444
{
115
444
    PyCompilerFlags local_flags = _PyCompilerFlags_INIT;
116
117
444
    c->c_const_cache = PyDict_New();
118
444
    if (!c->c_const_cache) {
119
0
        return ERROR;
120
0
    }
121
122
444
    c->c_stack = PyList_New(0);
123
444
    if (!c->c_stack) {
124
0
        return ERROR;
125
0
    }
126
127
444
    c->c_filename = Py_NewRef(filename);
128
444
    if (!_PyFuture_FromAST(mod, filename, &c->c_future)) {
129
0
        return ERROR;
130
0
    }
131
444
    c->c_module = Py_XNewRef(module);
132
444
    if (!flags) {
133
84
        flags = &local_flags;
134
84
    }
135
444
    int merged = c->c_future.ff_features | flags->cf_flags;
136
444
    c->c_future.ff_features = merged;
137
444
    flags->cf_flags = merged;
138
444
    c->c_flags = *flags;
139
444
    c->c_optimize = (optimize == -1) ? _Py_GetConfig()->optimization_level : optimize;
140
444
    c->c_save_nested_seqs = false;
141
142
444
    if (!_PyAST_Preprocess(mod, arena, filename, c->c_optimize, merged,
143
444
                           0, 1, module))
144
0
    {
145
0
        return ERROR;
146
0
    }
147
444
    c->c_st = _PySymtable_Build(mod, filename, &c->c_future);
148
444
    if (c->c_st == NULL) {
149
0
        if (!PyErr_Occurred()) {
150
0
            PyErr_SetString(PyExc_SystemError, "no symtable");
151
0
        }
152
0
        return ERROR;
153
0
    }
154
444
    return SUCCESS;
155
444
}
156
157
static void
158
compiler_free(compiler *c)
159
444
{
160
444
    if (c->c_st) {
161
444
        _PySymtable_Free(c->c_st);
162
444
    }
163
444
    Py_XDECREF(c->c_filename);
164
444
    Py_XDECREF(c->c_module);
165
444
    Py_XDECREF(c->c_const_cache);
166
444
    Py_XDECREF(c->c_stack);
167
444
    PyMem_Free(c);
168
444
}
169
170
static compiler*
171
new_compiler(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags,
172
             int optimize, PyArena *arena, PyObject *module)
173
444
{
174
444
    compiler *c = PyMem_Calloc(1, sizeof(compiler));
175
444
    if (c == NULL) {
176
0
        return NULL;
177
0
    }
178
444
    if (compiler_setup(c, mod, filename, pflags, optimize, arena, module) < 0) {
179
0
        compiler_free(c);
180
0
        return NULL;
181
0
    }
182
444
    return c;
183
444
}
184
185
static void
186
compiler_unit_free(struct compiler_unit *u)
187
8.29k
{
188
8.29k
    Py_CLEAR(u->u_instr_sequence);
189
8.29k
    Py_CLEAR(u->u_stashed_instr_sequence);
190
8.29k
    Py_CLEAR(u->u_ste);
191
8.29k
    Py_CLEAR(u->u_metadata.u_name);
192
8.29k
    Py_CLEAR(u->u_metadata.u_qualname);
193
8.29k
    Py_CLEAR(u->u_metadata.u_consts);
194
8.29k
    Py_CLEAR(u->u_metadata.u_names);
195
8.29k
    Py_CLEAR(u->u_metadata.u_varnames);
196
8.29k
    Py_CLEAR(u->u_metadata.u_freevars);
197
8.29k
    Py_CLEAR(u->u_metadata.u_cellvars);
198
8.29k
    Py_CLEAR(u->u_metadata.u_fasthidden);
199
8.29k
    Py_CLEAR(u->u_private);
200
8.29k
    Py_CLEAR(u->u_static_attributes);
201
8.29k
    Py_CLEAR(u->u_deferred_annotations);
202
8.29k
    Py_CLEAR(u->u_conditional_annotation_indices);
203
8.29k
    PyMem_Free(u);
204
8.29k
}
205
206
22.1k
#define CAPSULE_NAME "compile.c compiler unit"
207
208
int
209
_PyCompile_MaybeAddStaticAttributeToClass(compiler *c, expr_ty e)
210
18.9k
{
211
18.9k
    assert(e->kind == Attribute_kind);
212
18.9k
    expr_ty attr_value = e->v.Attribute.value;
213
18.9k
    if (attr_value->kind != Name_kind ||
214
17.7k
        e->v.Attribute.ctx != Store ||
215
2.50k
        !_PyUnicode_EqualToASCIIString(attr_value->v.Name.id, "self"))
216
17.1k
    {
217
17.1k
        return SUCCESS;
218
17.1k
    }
219
1.79k
    Py_ssize_t stack_size = PyList_GET_SIZE(c->c_stack);
220
1.80k
    for (Py_ssize_t i = stack_size - 1; i >= 0; i--) {
221
1.79k
        PyObject *capsule = PyList_GET_ITEM(c->c_stack, i);
222
1.79k
        struct compiler_unit *u = (struct compiler_unit *)PyCapsule_GetPointer(
223
1.79k
                                                              capsule, CAPSULE_NAME);
224
1.79k
        assert(u);
225
1.79k
        if (u->u_scope_type == COMPILE_SCOPE_CLASS) {
226
1.79k
            assert(u->u_static_attributes);
227
1.79k
            RETURN_IF_ERROR(PySet_Add(u->u_static_attributes, e->v.Attribute.attr));
228
1.79k
            break;
229
1.79k
        }
230
1.79k
    }
231
1.79k
    return SUCCESS;
232
1.79k
}
233
234
static int
235
compiler_set_qualname(compiler *c)
236
7.85k
{
237
7.85k
    Py_ssize_t stack_size;
238
7.85k
    struct compiler_unit *u = c->u;
239
7.85k
    PyObject *name, *base;
240
241
7.85k
    base = NULL;
242
7.85k
    stack_size = PyList_GET_SIZE(c->c_stack);
243
7.85k
    assert(stack_size >= 1);
244
7.85k
    if (stack_size > 1) {
245
4.62k
        int scope, force_global = 0;
246
4.62k
        struct compiler_unit *parent;
247
4.62k
        PyObject *mangled, *capsule;
248
249
4.62k
        capsule = PyList_GET_ITEM(c->c_stack, stack_size - 1);
250
4.62k
        parent = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME);
251
4.62k
        assert(parent);
252
4.62k
        if (parent->u_scope_type == COMPILE_SCOPE_ANNOTATIONS) {
253
            /* The parent is an annotation scope, so we need to
254
               look at the grandparent. */
255
9
            if (stack_size == 2) {
256
                // If we're immediately within the module, we can skip
257
                // the rest and just set the qualname to be the same as name.
258
7
                u->u_metadata.u_qualname = Py_NewRef(u->u_metadata.u_name);
259
7
                return SUCCESS;
260
7
            }
261
2
            capsule = PyList_GET_ITEM(c->c_stack, stack_size - 2);
262
2
            parent = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME);
263
2
            assert(parent);
264
2
        }
265
266
4.61k
        if (u->u_scope_type == COMPILE_SCOPE_FUNCTION
267
459
            || u->u_scope_type == COMPILE_SCOPE_ASYNC_FUNCTION
268
4.18k
            || u->u_scope_type == COMPILE_SCOPE_CLASS) {
269
4.18k
            assert(u->u_metadata.u_name);
270
4.18k
            mangled = _Py_Mangle(parent->u_private, u->u_metadata.u_name);
271
4.18k
            if (!mangled) {
272
0
                return ERROR;
273
0
            }
274
275
4.18k
            scope = _PyST_GetScope(parent->u_ste, mangled);
276
4.18k
            Py_DECREF(mangled);
277
4.18k
            RETURN_IF_ERROR(scope);
278
4.18k
            assert(scope != GLOBAL_IMPLICIT);
279
4.18k
            if (scope == GLOBAL_EXPLICIT)
280
0
                force_global = 1;
281
4.18k
        }
282
283
4.61k
        if (!force_global) {
284
4.61k
            if (parent->u_scope_type == COMPILE_SCOPE_FUNCTION
285
3.98k
                || parent->u_scope_type == COMPILE_SCOPE_ASYNC_FUNCTION
286
3.98k
                || parent->u_scope_type == COMPILE_SCOPE_LAMBDA)
287
639
            {
288
639
                _Py_DECLARE_STR(dot_locals, ".<locals>");
289
639
                base = PyUnicode_Concat(parent->u_metadata.u_qualname,
290
639
                                        &_Py_STR(dot_locals));
291
639
                if (base == NULL) {
292
0
                    return ERROR;
293
0
                }
294
639
            }
295
3.98k
            else {
296
3.98k
                base = Py_NewRef(parent->u_metadata.u_qualname);
297
3.98k
            }
298
4.61k
        }
299
4.61k
    }
300
301
7.84k
    if (base != NULL) {
302
4.61k
        name = PyUnicode_Concat(base, _Py_LATIN1_CHR('.'));
303
4.61k
        Py_DECREF(base);
304
4.61k
        if (name == NULL) {
305
0
            return ERROR;
306
0
        }
307
4.61k
        PyUnicode_Append(&name, u->u_metadata.u_name);
308
4.61k
        if (name == NULL) {
309
0
            return ERROR;
310
0
        }
311
4.61k
    }
312
3.22k
    else {
313
3.22k
        name = Py_NewRef(u->u_metadata.u_name);
314
3.22k
    }
315
7.84k
    u->u_metadata.u_qualname = name;
316
317
7.84k
    return SUCCESS;
318
7.84k
}
319
320
/* Merge const *o* and return constant key object.
321
 * If recursive, insert all elements if o is a tuple or frozen set.
322
 */
323
static PyObject*
324
const_cache_insert(PyObject *const_cache, PyObject *o, bool recursive)
325
143k
{
326
143k
    assert(PyDict_CheckExact(const_cache));
327
    // None and Ellipsis are immortal objects, and key is the singleton.
328
    // No need to merge object and key.
329
143k
    if (o == Py_None || o == Py_Ellipsis) {
330
16.9k
        return o;
331
16.9k
    }
332
333
126k
    PyObject *key = _PyCode_ConstantKey(o);
334
126k
    if (key == NULL) {
335
0
        return NULL;
336
0
    }
337
338
126k
    PyObject *t;
339
126k
    int res = PyDict_SetDefaultRef(const_cache, key, key, &t);
340
126k
    if (res != 0) {
341
        // o was not inserted into const_cache. t is either the existing value
342
        // or NULL (on error).
343
48.5k
        Py_DECREF(key);
344
48.5k
        return t;
345
48.5k
    }
346
78.0k
    Py_DECREF(t);
347
348
78.0k
    if (!recursive) {
349
35.4k
        return key;
350
35.4k
    }
351
352
    // We registered o in const_cache.
353
    // When o is a tuple or frozenset, we want to merge its
354
    // items too.
355
42.6k
    if (PyTuple_CheckExact(o)) {
356
1.48k
        Py_ssize_t len = PyTuple_GET_SIZE(o);
357
5.11k
        for (Py_ssize_t i = 0; i < len; i++) {
358
3.62k
            PyObject *item = PyTuple_GET_ITEM(o, i);
359
3.62k
            PyObject *u = const_cache_insert(const_cache, item, recursive);
360
3.62k
            if (u == NULL) {
361
0
                Py_DECREF(key);
362
0
                return NULL;
363
0
            }
364
365
            // See _PyCode_ConstantKey()
366
3.62k
            PyObject *v;  // borrowed
367
3.62k
            if (PyTuple_CheckExact(u)) {
368
0
                v = PyTuple_GET_ITEM(u, 1);
369
0
            }
370
3.62k
            else {
371
3.62k
                v = u;
372
3.62k
            }
373
3.62k
            if (v != item) {
374
252
                PyTuple_SET_ITEM(o, i, Py_NewRef(v));
375
252
                Py_DECREF(item);
376
252
            }
377
378
3.62k
            Py_DECREF(u);
379
3.62k
        }
380
1.48k
    }
381
41.1k
    else if (PyFrozenSet_CheckExact(o)) {
382
        // *key* is tuple. And its first item is frozenset of
383
        // constant keys.
384
        // See _PyCode_ConstantKey() for detail.
385
0
        assert(PyTuple_CheckExact(key));
386
0
        assert(PyTuple_GET_SIZE(key) == 2);
387
388
0
        Py_ssize_t len = PySet_GET_SIZE(o);
389
0
        if (len == 0) {  // empty frozenset should not be re-created.
390
0
            return key;
391
0
        }
392
0
        PyObject *tuple = PyTuple_New(len);
393
0
        if (tuple == NULL) {
394
0
            Py_DECREF(key);
395
0
            return NULL;
396
0
        }
397
0
        Py_ssize_t i = 0, pos = 0;
398
0
        PyObject *item;
399
0
        Py_hash_t hash;
400
0
        while (_PySet_NextEntry(o, &pos, &item, &hash)) {
401
0
            PyObject *k = const_cache_insert(const_cache, item, recursive);
402
0
            if (k == NULL) {
403
0
                Py_DECREF(tuple);
404
0
                Py_DECREF(key);
405
0
                return NULL;
406
0
            }
407
0
            PyObject *u;
408
0
            if (PyTuple_CheckExact(k)) {
409
0
                u = Py_NewRef(PyTuple_GET_ITEM(k, 1));
410
0
                Py_DECREF(k);
411
0
            }
412
0
            else {
413
0
                u = k;
414
0
            }
415
0
            PyTuple_SET_ITEM(tuple, i, u);  // Steals reference of u.
416
0
            i++;
417
0
        }
418
419
        // Instead of rewriting o, we create new frozenset and embed in the
420
        // key tuple.  Caller should get merged frozenset from the key tuple.
421
0
        PyObject *new = PyFrozenSet_New(tuple);
422
0
        Py_DECREF(tuple);
423
0
        if (new == NULL) {
424
0
            Py_DECREF(key);
425
0
            return NULL;
426
0
        }
427
0
        assert(PyTuple_GET_ITEM(key, 1) == o);
428
0
        Py_DECREF(o);
429
0
        PyTuple_SET_ITEM(key, 1, new);
430
0
    }
431
432
42.6k
    return key;
433
42.6k
}
434
435
static PyObject*
436
merge_consts_recursive(PyObject *const_cache, PyObject *o)
437
87.1k
{
438
87.1k
    return const_cache_insert(const_cache, o, true);
439
87.1k
}
440
441
Py_ssize_t
442
_PyCompile_DictAddObj(PyObject *dict, PyObject *o)
443
254k
{
444
254k
    PyObject *v;
445
254k
    Py_ssize_t arg;
446
447
254k
    if (PyDict_GetItemRef(dict, o, &v) < 0) {
448
0
        return ERROR;
449
0
    }
450
254k
    if (!v) {
451
126k
        arg = PyDict_GET_SIZE(dict);
452
126k
        v = PyLong_FromSsize_t(arg);
453
126k
        if (!v) {
454
0
            return ERROR;
455
0
        }
456
126k
        if (PyDict_SetItem(dict, o, v) < 0) {
457
0
            Py_DECREF(v);
458
0
            return ERROR;
459
0
        }
460
126k
    }
461
128k
    else
462
128k
        arg = PyLong_AsLong(v);
463
254k
    Py_DECREF(v);
464
254k
    return arg;
465
254k
}
466
467
Py_ssize_t
468
_PyCompile_AddConst(compiler *c, PyObject *o)
469
87.1k
{
470
87.1k
    PyObject *key = merge_consts_recursive(c->c_const_cache, o);
471
87.1k
    if (key == NULL) {
472
0
        return ERROR;
473
0
    }
474
475
87.1k
    Py_ssize_t arg = _PyCompile_DictAddObj(c->u->u_metadata.u_consts, key);
476
87.1k
    Py_DECREF(key);
477
87.1k
    return arg;
478
87.1k
}
479
480
static PyObject *
481
list2dict(PyObject *list)
482
8.29k
{
483
8.29k
    Py_ssize_t i, n;
484
8.29k
    PyObject *v, *k;
485
8.29k
    PyObject *dict = PyDict_New();
486
8.29k
    if (!dict) return NULL;
487
488
8.29k
    n = PyList_Size(list);
489
21.9k
    for (i = 0; i < n; i++) {
490
13.6k
        v = PyLong_FromSsize_t(i);
491
13.6k
        if (!v) {
492
0
            Py_DECREF(dict);
493
0
            return NULL;
494
0
        }
495
13.6k
        k = PyList_GET_ITEM(list, i);
496
13.6k
        if (PyDict_SetItem(dict, k, v) < 0) {
497
0
            Py_DECREF(v);
498
0
            Py_DECREF(dict);
499
0
            return NULL;
500
0
        }
501
13.6k
        Py_DECREF(v);
502
13.6k
    }
503
8.29k
    return dict;
504
8.29k
}
505
506
/* Return new dict containing names from src that match scope(s).
507
508
src is a symbol table dictionary.  If the scope of a name matches
509
either scope_type or flag is set, insert it into the new dict.  The
510
values are integers, starting at offset and increasing by one for
511
each key.
512
*/
513
514
static PyObject *
515
dictbytype(PyObject *src, int scope_type, int flag, Py_ssize_t offset)
516
16.5k
{
517
16.5k
    Py_ssize_t i = offset, num_keys, key_i;
518
16.5k
    PyObject *k, *v, *dest = PyDict_New();
519
16.5k
    PyObject *sorted_keys;
520
521
16.5k
    assert(offset >= 0);
522
16.5k
    if (dest == NULL)
523
0
        return NULL;
524
525
    /* Sort the keys so that we have a deterministic order on the indexes
526
       saved in the returned dictionary.  These indexes are used as indexes
527
       into the free and cell var storage.  Therefore if they aren't
528
       deterministic, then the generated bytecode is not deterministic.
529
    */
530
16.5k
    sorted_keys = PyDict_Keys(src);
531
16.5k
    if (sorted_keys == NULL) {
532
0
        Py_DECREF(dest);
533
0
        return NULL;
534
0
    }
535
16.5k
    if (PyList_Sort(sorted_keys) != 0) {
536
0
        Py_DECREF(sorted_keys);
537
0
        Py_DECREF(dest);
538
0
        return NULL;
539
0
    }
540
16.5k
    num_keys = PyList_GET_SIZE(sorted_keys);
541
542
122k
    for (key_i = 0; key_i < num_keys; key_i++) {
543
105k
        k = PyList_GET_ITEM(sorted_keys, key_i);
544
105k
        v = PyDict_GetItemWithError(src, k);
545
105k
        if (!v) {
546
0
            if (!PyErr_Occurred()) {
547
0
                PyErr_SetObject(PyExc_KeyError, k);
548
0
            }
549
0
            Py_DECREF(sorted_keys);
550
0
            Py_DECREF(dest);
551
0
            return NULL;
552
0
        }
553
105k
        long vi = PyLong_AsLong(v);
554
105k
        if (vi == -1 && PyErr_Occurred()) {
555
0
            Py_DECREF(sorted_keys);
556
0
            Py_DECREF(dest);
557
0
            return NULL;
558
0
        }
559
105k
        if (SYMBOL_TO_SCOPE(vi) == scope_type || vi & flag) {
560
1.57k
            PyObject *item = PyLong_FromSsize_t(i);
561
1.57k
            if (item == NULL) {
562
0
                Py_DECREF(sorted_keys);
563
0
                Py_DECREF(dest);
564
0
                return NULL;
565
0
            }
566
1.57k
            i++;
567
1.57k
            if (PyDict_SetItem(dest, k, item) < 0) {
568
0
                Py_DECREF(sorted_keys);
569
0
                Py_DECREF(item);
570
0
                Py_DECREF(dest);
571
0
                return NULL;
572
0
            }
573
1.57k
            Py_DECREF(item);
574
1.57k
        }
575
105k
    }
576
16.5k
    Py_DECREF(sorted_keys);
577
16.5k
    return dest;
578
16.5k
}
579
580
int
581
_PyCompile_EnterScope(compiler *c, identifier name, int scope_type,
582
                       void *key, int lineno, PyObject *private,
583
                      _PyCompile_CodeUnitMetadata *umd)
584
8.29k
{
585
8.29k
    struct compiler_unit *u;
586
8.29k
    u = (struct compiler_unit *)PyMem_Calloc(1, sizeof(struct compiler_unit));
587
8.29k
    if (!u) {
588
0
        PyErr_NoMemory();
589
0
        return ERROR;
590
0
    }
591
8.29k
    u->u_scope_type = scope_type;
592
8.29k
    if (umd != NULL) {
593
6.59k
        u->u_metadata = *umd;
594
6.59k
    }
595
1.70k
    else {
596
1.70k
        u->u_metadata.u_argcount = 0;
597
1.70k
        u->u_metadata.u_posonlyargcount = 0;
598
1.70k
        u->u_metadata.u_kwonlyargcount = 0;
599
1.70k
    }
600
8.29k
    u->u_ste = _PySymtable_Lookup(c->c_st, key);
601
8.29k
    if (!u->u_ste) {
602
0
        compiler_unit_free(u);
603
0
        return ERROR;
604
0
    }
605
8.29k
    u->u_metadata.u_name = Py_NewRef(name);
606
8.29k
    u->u_metadata.u_varnames = list2dict(u->u_ste->ste_varnames);
607
8.29k
    if (!u->u_metadata.u_varnames) {
608
0
        compiler_unit_free(u);
609
0
        return ERROR;
610
0
    }
611
8.29k
    u->u_metadata.u_cellvars = dictbytype(u->u_ste->ste_symbols, CELL, DEF_COMP_CELL, 0);
612
8.29k
    if (!u->u_metadata.u_cellvars) {
613
0
        compiler_unit_free(u);
614
0
        return ERROR;
615
0
    }
616
8.29k
    if (u->u_ste->ste_needs_class_closure) {
617
        /* Cook up an implicit __class__ cell. */
618
104
        Py_ssize_t res;
619
104
        assert(u->u_scope_type == COMPILE_SCOPE_CLASS);
620
104
        res = _PyCompile_DictAddObj(u->u_metadata.u_cellvars, &_Py_ID(__class__));
621
104
        if (res < 0) {
622
0
            compiler_unit_free(u);
623
0
            return ERROR;
624
0
        }
625
104
    }
626
8.29k
    if (u->u_ste->ste_needs_classdict) {
627
        /* Cook up an implicit __classdict__ cell. */
628
778
        Py_ssize_t res;
629
778
        assert(u->u_scope_type == COMPILE_SCOPE_CLASS);
630
778
        res = _PyCompile_DictAddObj(u->u_metadata.u_cellvars, &_Py_ID(__classdict__));
631
778
        if (res < 0) {
632
0
            compiler_unit_free(u);
633
0
            return ERROR;
634
0
        }
635
778
    }
636
8.29k
    if (u->u_ste->ste_has_conditional_annotations) {
637
        /* Cook up an implicit __conditional_annotations__ cell */
638
1
        Py_ssize_t res;
639
1
        assert(u->u_scope_type == COMPILE_SCOPE_CLASS || u->u_scope_type == COMPILE_SCOPE_MODULE);
640
1
        res = _PyCompile_DictAddObj(u->u_metadata.u_cellvars, &_Py_ID(__conditional_annotations__));
641
1
        if (res < 0) {
642
0
            compiler_unit_free(u);
643
0
            return ERROR;
644
0
        }
645
1
    }
646
647
8.29k
    u->u_metadata.u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS,
648
8.29k
                               PyDict_GET_SIZE(u->u_metadata.u_cellvars));
649
8.29k
    if (!u->u_metadata.u_freevars) {
650
0
        compiler_unit_free(u);
651
0
        return ERROR;
652
0
    }
653
654
8.29k
    u->u_metadata.u_fasthidden = PyDict_New();
655
8.29k
    if (!u->u_metadata.u_fasthidden) {
656
0
        compiler_unit_free(u);
657
0
        return ERROR;
658
0
    }
659
660
8.29k
    u->u_nfblocks = 0;
661
8.29k
    u->u_in_inlined_comp = 0;
662
8.29k
    u->u_metadata.u_firstlineno = lineno;
663
8.29k
    u->u_metadata.u_consts = PyDict_New();
664
8.29k
    if (!u->u_metadata.u_consts) {
665
0
        compiler_unit_free(u);
666
0
        return ERROR;
667
0
    }
668
8.29k
    u->u_metadata.u_names = PyDict_New();
669
8.29k
    if (!u->u_metadata.u_names) {
670
0
        compiler_unit_free(u);
671
0
        return ERROR;
672
0
    }
673
674
8.29k
    u->u_deferred_annotations = NULL;
675
8.29k
    u->u_conditional_annotation_indices = NULL;
676
8.29k
    u->u_next_conditional_annotation_index = 0;
677
8.29k
    if (scope_type == COMPILE_SCOPE_CLASS) {
678
1.25k
        u->u_static_attributes = PySet_New(0);
679
1.25k
        if (!u->u_static_attributes) {
680
0
            compiler_unit_free(u);
681
0
            return ERROR;
682
0
        }
683
1.25k
    }
684
7.03k
    else {
685
7.03k
        u->u_static_attributes = NULL;
686
7.03k
    }
687
688
8.29k
    u->u_instr_sequence = (instr_sequence*)_PyInstructionSequence_New();
689
8.29k
    if (!u->u_instr_sequence) {
690
0
        compiler_unit_free(u);
691
0
        return ERROR;
692
0
    }
693
8.29k
    u->u_stashed_instr_sequence = NULL;
694
695
    /* Push the old compiler_unit on the stack. */
696
8.29k
    if (c->u) {
697
7.85k
        PyObject *capsule = PyCapsule_New(c->u, CAPSULE_NAME, NULL);
698
7.85k
        if (!capsule || PyList_Append(c->c_stack, capsule) < 0) {
699
0
            Py_XDECREF(capsule);
700
0
            compiler_unit_free(u);
701
0
            return ERROR;
702
0
        }
703
7.85k
        Py_DECREF(capsule);
704
7.85k
        if (private == NULL) {
705
6.59k
            private = c->u->u_private;
706
6.59k
        }
707
7.85k
    }
708
709
8.29k
    u->u_private = Py_XNewRef(private);
710
711
8.29k
    c->u = u;
712
8.29k
    if (scope_type != COMPILE_SCOPE_MODULE) {
713
7.85k
        RETURN_IF_ERROR(compiler_set_qualname(c));
714
7.85k
    }
715
8.29k
    return SUCCESS;
716
8.29k
}
717
718
void
719
_PyCompile_ExitScope(compiler *c)
720
8.29k
{
721
    // Don't call PySequence_DelItem() with an exception raised
722
8.29k
    PyObject *exc = PyErr_GetRaisedException();
723
724
8.29k
    instr_sequence *nested_seq = NULL;
725
8.29k
    if (c->c_save_nested_seqs) {
726
0
        nested_seq = c->u->u_instr_sequence;
727
0
        Py_INCREF(nested_seq);
728
0
    }
729
8.29k
    compiler_unit_free(c->u);
730
    /* Restore c->u to the parent unit. */
731
8.29k
    Py_ssize_t n = PyList_GET_SIZE(c->c_stack) - 1;
732
8.29k
    if (n >= 0) {
733
7.85k
        PyObject *capsule = PyList_GET_ITEM(c->c_stack, n);
734
7.85k
        c->u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME);
735
7.85k
        assert(c->u);
736
        /* we are deleting from a list so this really shouldn't fail */
737
7.85k
        if (PySequence_DelItem(c->c_stack, n) < 0) {
738
0
            PyErr_FormatUnraisable("Exception ignored while removing "
739
0
                                   "the last compiler stack item");
740
0
        }
741
7.85k
        if (nested_seq != NULL) {
742
0
            if (_PyInstructionSequence_AddNested(c->u->u_instr_sequence, nested_seq) < 0) {
743
0
                PyErr_FormatUnraisable("Exception ignored while appending "
744
0
                                       "nested instruction sequence");
745
0
            }
746
0
        }
747
7.85k
    }
748
444
    else {
749
444
        c->u = NULL;
750
444
    }
751
8.29k
    Py_XDECREF(nested_seq);
752
753
8.29k
    PyErr_SetRaisedException(exc);
754
8.29k
}
755
756
/*
757
 * Frame block handling functions
758
 */
759
760
int
761
_PyCompile_PushFBlock(compiler *c, location loc,
762
                     fblocktype t, jump_target_label block_label,
763
                     jump_target_label exit, void *datum)
764
6.83k
{
765
6.83k
    fblockinfo *f;
766
6.83k
    if (c->u->u_nfblocks >= CO_MAXBLOCKS) {
767
0
        return _PyCompile_Error(c, loc, "too many statically nested blocks");
768
0
    }
769
6.83k
    f = &c->u->u_fblock[c->u->u_nfblocks++];
770
6.83k
    f->fb_type = t;
771
6.83k
    f->fb_block = block_label;
772
6.83k
    f->fb_loc = loc;
773
6.83k
    f->fb_exit = exit;
774
6.83k
    f->fb_datum = datum;
775
6.83k
    if (t == COMPILE_FBLOCK_FINALLY_END) {
776
75
        c->c_disable_warning++;
777
75
    }
778
6.83k
    return SUCCESS;
779
6.83k
}
780
781
void
782
_PyCompile_PopFBlock(compiler *c, fblocktype t, jump_target_label block_label)
783
6.83k
{
784
6.83k
    struct compiler_unit *u = c->u;
785
6.83k
    assert(u->u_nfblocks > 0);
786
6.83k
    u->u_nfblocks--;
787
6.83k
    assert(u->u_fblock[u->u_nfblocks].fb_type == t);
788
6.83k
    assert(SAME_JUMP_TARGET_LABEL(u->u_fblock[u->u_nfblocks].fb_block, block_label));
789
6.83k
    if (t == COMPILE_FBLOCK_FINALLY_END) {
790
75
        c->c_disable_warning--;
791
75
    }
792
6.83k
}
793
794
fblockinfo *
795
_PyCompile_TopFBlock(compiler *c)
796
8.73k
{
797
8.73k
    if (c->u->u_nfblocks == 0) {
798
6.60k
        return NULL;
799
6.60k
    }
800
2.13k
    return &c->u->u_fblock[c->u->u_nfblocks - 1];
801
8.73k
}
802
803
void
804
_PyCompile_DeferredAnnotations(compiler *c,
805
                               PyObject **deferred_annotations,
806
                               PyObject **conditional_annotation_indices)
807
1.60k
{
808
1.60k
    *deferred_annotations = Py_XNewRef(c->u->u_deferred_annotations);
809
1.60k
    *conditional_annotation_indices = Py_XNewRef(c->u->u_conditional_annotation_indices);
810
1.60k
}
811
812
static location
813
start_location(asdl_stmt_seq *stmts)
814
358
{
815
358
    if (asdl_seq_LEN(stmts) > 0) {
816
        /* Set current line number to the line number of first statement.
817
         * This way line number for SETUP_ANNOTATIONS will always
818
         * coincide with the line number of first "real" statement in module.
819
         * If body is empty, then lineno will be set later in the assembly stage.
820
         */
821
355
        stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
822
355
        return SRC_LOCATION_FROM_AST(st);
823
355
    }
824
3
    return (const _Py_SourceLocation){1, 1, 0, 0};
825
358
}
826
827
static int
828
compiler_codegen(compiler *c, mod_ty mod)
829
444
{
830
444
    RETURN_IF_ERROR(_PyCodegen_EnterAnonymousScope(c, mod));
831
444
    assert(c->u->u_scope_type == COMPILE_SCOPE_MODULE);
832
444
    switch (mod->kind) {
833
358
    case Module_kind: {
834
358
        asdl_stmt_seq *stmts = mod->v.Module.body;
835
358
        RETURN_IF_ERROR(_PyCodegen_Module(c, start_location(stmts), stmts, false));
836
358
        break;
837
358
    }
838
358
    case Interactive_kind: {
839
0
        c->c_interactive = 1;
840
0
        asdl_stmt_seq *stmts = mod->v.Interactive.body;
841
0
        RETURN_IF_ERROR(_PyCodegen_Module(c, start_location(stmts), stmts, true));
842
0
        break;
843
0
    }
844
86
    case Expression_kind: {
845
86
        RETURN_IF_ERROR(_PyCodegen_Expression(c, mod->v.Expression.body));
846
86
        break;
847
86
    }
848
86
    default: {
849
0
        PyErr_Format(PyExc_SystemError,
850
0
                     "module kind %d should not be possible",
851
0
                     mod->kind);
852
0
        return ERROR;
853
86
    }}
854
444
    return SUCCESS;
855
444
}
856
857
static PyCodeObject *
858
compiler_mod(compiler *c, mod_ty mod)
859
444
{
860
444
    PyCodeObject *co = NULL;
861
444
    int addNone = mod->kind != Expression_kind;
862
444
    if (compiler_codegen(c, mod) < 0) {
863
0
        goto finally;
864
0
    }
865
444
    co = _PyCompile_OptimizeAndAssemble(c, addNone);
866
444
finally:
867
444
    _PyCompile_ExitScope(c);
868
444
    return co;
869
444
}
870
871
int
872
_PyCompile_GetRefType(compiler *c, PyObject *name)
873
1.25k
{
874
1.25k
    if (c->u->u_scope_type == COMPILE_SCOPE_CLASS &&
875
293
        (_PyUnicode_EqualToASCIIString(name, "__class__") ||
876
80
         _PyUnicode_EqualToASCIIString(name, "__classdict__") ||
877
283
         _PyUnicode_EqualToASCIIString(name, "__conditional_annotations__"))) {
878
283
        return CELL;
879
283
    }
880
968
    PySTEntryObject *ste = c->u->u_ste;
881
968
    int scope = _PyST_GetScope(ste, name);
882
968
    if (scope == 0) {
883
0
        PyErr_Format(PyExc_SystemError,
884
0
                     "_PyST_GetScope(name=%R) failed: "
885
0
                     "unknown scope in unit %S (%R); "
886
0
                     "symbols: %R; locals: %R; "
887
0
                     "globals: %R",
888
0
                     name,
889
0
                     c->u->u_metadata.u_name, ste->ste_id,
890
0
                     ste->ste_symbols, c->u->u_metadata.u_varnames,
891
0
                     c->u->u_metadata.u_names);
892
0
        return ERROR;
893
0
    }
894
968
    return scope;
895
968
}
896
897
static int
898
dict_lookup_arg(PyObject *dict, PyObject *name)
899
1.92k
{
900
1.92k
    PyObject *v = PyDict_GetItemWithError(dict, name);
901
1.92k
    if (v == NULL) {
902
0
        return ERROR;
903
0
    }
904
1.92k
    return PyLong_AsLong(v);
905
1.92k
}
906
907
int
908
_PyCompile_LookupCellvar(compiler *c, PyObject *name)
909
882
{
910
882
    assert(c->u->u_metadata.u_cellvars);
911
882
    return dict_lookup_arg(c->u->u_metadata.u_cellvars, name);
912
882
}
913
914
int
915
_PyCompile_LookupArg(compiler *c, PyCodeObject *co, PyObject *name)
916
1.04k
{
917
    /* Special case: If a class contains a method with a
918
     * free variable that has the same name as a method,
919
     * the name will be considered free *and* local in the
920
     * class.  It should be handled by the closure, as
921
     * well as by the normal name lookup logic.
922
     */
923
1.04k
    int reftype = _PyCompile_GetRefType(c, name);
924
1.04k
    if (reftype == -1) {
925
0
        return ERROR;
926
0
    }
927
1.04k
    int arg;
928
1.04k
    if (reftype == CELL) {
929
990
        arg = dict_lookup_arg(c->u->u_metadata.u_cellvars, name);
930
990
    }
931
55
    else {
932
55
        arg = dict_lookup_arg(c->u->u_metadata.u_freevars, name);
933
55
    }
934
1.04k
    if (arg == -1 && !PyErr_Occurred()) {
935
0
        PyObject *freevars = _PyCode_GetFreevars(co);
936
0
        if (freevars == NULL) {
937
0
            PyErr_Clear();
938
0
        }
939
0
        PyErr_Format(PyExc_SystemError,
940
0
            "compiler_lookup_arg(name=%R) with reftype=%d failed in %S; "
941
0
            "freevars of code %S: %R",
942
0
            name,
943
0
            reftype,
944
0
            c->u->u_metadata.u_name,
945
0
            co->co_name,
946
0
            freevars);
947
0
        Py_XDECREF(freevars);
948
0
        return ERROR;
949
0
    }
950
1.04k
    return arg;
951
1.04k
}
952
953
PyObject *
954
_PyCompile_StaticAttributesAsTuple(compiler *c)
955
1.25k
{
956
1.25k
    assert(c->u->u_static_attributes);
957
1.25k
    PyObject *static_attributes_unsorted = PySequence_List(c->u->u_static_attributes);
958
1.25k
    if (static_attributes_unsorted == NULL) {
959
0
        return NULL;
960
0
    }
961
1.25k
    if (PyList_Sort(static_attributes_unsorted) != 0) {
962
0
        Py_DECREF(static_attributes_unsorted);
963
0
        return NULL;
964
0
    }
965
1.25k
    PyObject *static_attributes = PySequence_Tuple(static_attributes_unsorted);
966
1.25k
    Py_DECREF(static_attributes_unsorted);
967
1.25k
    return static_attributes;
968
1.25k
}
969
970
int
971
_PyCompile_ResolveNameop(compiler *c, PyObject *mangled, int scope,
972
                          _PyCompile_optype *optype, Py_ssize_t *arg)
973
132k
{
974
132k
    PyObject *dict = c->u->u_metadata.u_names;
975
132k
    *optype = COMPILE_OP_NAME;
976
977
132k
    assert(scope >= 0);
978
132k
    switch (scope) {
979
1.63k
    case FREE:
980
1.63k
        dict = c->u->u_metadata.u_freevars;
981
1.63k
        *optype = COMPILE_OP_DEREF;
982
1.63k
        break;
983
1.06k
    case CELL:
984
1.06k
        dict = c->u->u_metadata.u_cellvars;
985
1.06k
        *optype = COMPILE_OP_DEREF;
986
1.06k
        break;
987
97.2k
    case LOCAL:
988
97.2k
        if (_PyST_IsFunctionLike(c->u->u_ste)) {
989
82.3k
            *optype = COMPILE_OP_FAST;
990
82.3k
        }
991
14.8k
        else {
992
14.8k
            PyObject *item;
993
14.8k
            RETURN_IF_ERROR(PyDict_GetItemRef(c->u->u_metadata.u_fasthidden, mangled,
994
14.8k
                                              &item));
995
14.8k
            if (item == Py_True) {
996
58
                *optype = COMPILE_OP_FAST;
997
58
            }
998
14.8k
            Py_XDECREF(item);
999
14.8k
        }
1000
97.2k
        break;
1001
97.2k
    case GLOBAL_IMPLICIT:
1002
24.8k
        if (_PyST_IsFunctionLike(c->u->u_ste)) {
1003
22.1k
            *optype = COMPILE_OP_GLOBAL;
1004
22.1k
        }
1005
24.8k
        break;
1006
177
    case GLOBAL_EXPLICIT:
1007
177
        *optype = COMPILE_OP_GLOBAL;
1008
177
        break;
1009
7.78k
    default:
1010
        /* scope can be 0 */
1011
7.78k
        break;
1012
132k
    }
1013
132k
    if (*optype != COMPILE_OP_FAST) {
1014
50.3k
        *arg = _PyCompile_DictAddObj(dict, mangled);
1015
50.3k
        RETURN_IF_ERROR(*arg);
1016
50.3k
    }
1017
132k
    return SUCCESS;
1018
132k
}
1019
1020
int
1021
_PyCompile_TweakInlinedComprehensionScopes(compiler *c, location loc,
1022
                                            PySTEntryObject *entry,
1023
                                            _PyCompile_InlinedComprehensionState *state)
1024
262
{
1025
262
    int in_class_block = (c->u->u_ste->ste_type == ClassBlock) && !c->u->u_in_inlined_comp;
1026
262
    c->u->u_in_inlined_comp++;
1027
1028
262
    PyObject *k, *v;
1029
262
    Py_ssize_t pos = 0;
1030
1.13k
    while (PyDict_Next(entry->ste_symbols, &pos, &k, &v)) {
1031
872
        long symbol = PyLong_AsLong(v);
1032
872
        assert(symbol >= 0 || PyErr_Occurred());
1033
872
        RETURN_IF_ERROR(symbol);
1034
872
        long scope = SYMBOL_TO_SCOPE(symbol);
1035
1036
872
        long outsymbol = _PyST_GetSymbol(c->u->u_ste, k);
1037
872
        RETURN_IF_ERROR(outsymbol);
1038
872
        long outsc = SYMBOL_TO_SCOPE(outsymbol);
1039
1040
        // If a name has different scope inside than outside the comprehension,
1041
        // we need to temporarily handle it with the right scope while
1042
        // compiling the comprehension. If it's free in the comprehension
1043
        // scope, no special handling; it should be handled the same as the
1044
        // enclosing scope. (If it's free in outer scope and cell in inner
1045
        // scope, we can't treat it as both cell and free in the same function,
1046
        // but treating it as free throughout is fine; it's *_DEREF
1047
        // either way.)
1048
872
        if ((scope != outsc && scope != FREE && !(scope == CELL && outsc == FREE))
1049
596
                || in_class_block) {
1050
276
            if (state->temp_symbols == NULL) {
1051
262
                state->temp_symbols = PyDict_New();
1052
262
                if (state->temp_symbols == NULL) {
1053
0
                    return ERROR;
1054
0
                }
1055
262
            }
1056
            // update the symbol to the in-comprehension version and save
1057
            // the outer version; we'll restore it after running the
1058
            // comprehension
1059
276
            if (PyDict_SetItem(c->u->u_ste->ste_symbols, k, v) < 0) {
1060
0
                return ERROR;
1061
0
            }
1062
276
            PyObject *outv = PyLong_FromLong(outsymbol);
1063
276
            if (outv == NULL) {
1064
0
                return ERROR;
1065
0
            }
1066
276
            int res = PyDict_SetItem(state->temp_symbols, k, outv);
1067
276
            Py_DECREF(outv);
1068
276
            RETURN_IF_ERROR(res);
1069
276
        }
1070
        // locals handling for names bound in comprehension (DEF_LOCAL |
1071
        // DEF_NONLOCAL occurs in assignment expression to nonlocal)
1072
872
        if ((symbol & DEF_LOCAL && !(symbol & DEF_NONLOCAL)) || in_class_block) {
1073
348
            if (!_PyST_IsFunctionLike(c->u->u_ste)) {
1074
                // non-function scope: override this name to use fast locals
1075
23
                PyObject *orig;
1076
23
                if (PyDict_GetItemRef(c->u->u_metadata.u_fasthidden, k, &orig) < 0) {
1077
0
                    return ERROR;
1078
0
                }
1079
23
                assert(orig == NULL || orig == Py_True || orig == Py_False);
1080
23
                if (orig != Py_True) {
1081
23
                    if (PyDict_SetItem(c->u->u_metadata.u_fasthidden, k, Py_True) < 0) {
1082
0
                        return ERROR;
1083
0
                    }
1084
23
                    if (state->fast_hidden == NULL) {
1085
17
                        state->fast_hidden = PySet_New(NULL);
1086
17
                        if (state->fast_hidden == NULL) {
1087
0
                            return ERROR;
1088
0
                        }
1089
17
                    }
1090
23
                    if (PySet_Add(state->fast_hidden, k) < 0) {
1091
0
                        return ERROR;
1092
0
                    }
1093
23
                }
1094
23
            }
1095
348
        }
1096
872
    }
1097
262
    return SUCCESS;
1098
262
}
1099
1100
int
1101
_PyCompile_RevertInlinedComprehensionScopes(compiler *c, location loc,
1102
                                             _PyCompile_InlinedComprehensionState *state)
1103
262
{
1104
262
    c->u->u_in_inlined_comp--;
1105
262
    if (state->temp_symbols) {
1106
262
        PyObject *k, *v;
1107
262
        Py_ssize_t pos = 0;
1108
538
        while (PyDict_Next(state->temp_symbols, &pos, &k, &v)) {
1109
276
            if (PyDict_SetItem(c->u->u_ste->ste_symbols, k, v)) {
1110
0
                return ERROR;
1111
0
            }
1112
276
        }
1113
262
        Py_CLEAR(state->temp_symbols);
1114
262
    }
1115
262
    if (state->fast_hidden) {
1116
40
        while (PySet_Size(state->fast_hidden) > 0) {
1117
23
            PyObject *k = PySet_Pop(state->fast_hidden);
1118
23
            if (k == NULL) {
1119
0
                return ERROR;
1120
0
            }
1121
            // we set to False instead of clearing, so we can track which names
1122
            // were temporarily fast-locals and should use CO_FAST_HIDDEN
1123
23
            if (PyDict_SetItem(c->u->u_metadata.u_fasthidden, k, Py_False)) {
1124
0
                Py_DECREF(k);
1125
0
                return ERROR;
1126
0
            }
1127
23
            Py_DECREF(k);
1128
23
        }
1129
17
        Py_CLEAR(state->fast_hidden);
1130
17
    }
1131
262
    return SUCCESS;
1132
262
}
1133
1134
void
1135
_PyCompile_EnterConditionalBlock(struct _PyCompiler *c)
1136
13.8k
{
1137
13.8k
    c->u->u_in_conditional_block++;
1138
13.8k
}
1139
1140
void
1141
_PyCompile_LeaveConditionalBlock(struct _PyCompiler *c)
1142
13.8k
{
1143
13.8k
    assert(c->u->u_in_conditional_block > 0);
1144
13.8k
    c->u->u_in_conditional_block--;
1145
13.8k
}
1146
1147
int
1148
_PyCompile_AddDeferredAnnotation(compiler *c, stmt_ty s,
1149
                                 PyObject **conditional_annotation_index)
1150
104
{
1151
104
    if (c->u->u_deferred_annotations == NULL) {
1152
15
        c->u->u_deferred_annotations = PyList_New(0);
1153
15
        if (c->u->u_deferred_annotations == NULL) {
1154
0
            return ERROR;
1155
0
        }
1156
15
    }
1157
104
    if (c->u->u_conditional_annotation_indices == NULL) {
1158
15
        c->u->u_conditional_annotation_indices = PyList_New(0);
1159
15
        if (c->u->u_conditional_annotation_indices == NULL) {
1160
0
            return ERROR;
1161
0
        }
1162
15
    }
1163
104
    PyObject *ptr = PyLong_FromVoidPtr((void *)s);
1164
104
    if (ptr == NULL) {
1165
0
        return ERROR;
1166
0
    }
1167
104
    if (PyList_Append(c->u->u_deferred_annotations, ptr) < 0) {
1168
0
        Py_DECREF(ptr);
1169
0
        return ERROR;
1170
0
    }
1171
104
    Py_DECREF(ptr);
1172
104
    PyObject *index;
1173
104
    if (c->u->u_scope_type == COMPILE_SCOPE_MODULE || c->u->u_in_conditional_block) {
1174
1
        index = PyLong_FromLong(c->u->u_next_conditional_annotation_index);
1175
1
        if (index == NULL) {
1176
0
            return ERROR;
1177
0
        }
1178
1
        *conditional_annotation_index = Py_NewRef(index);
1179
1
        c->u->u_next_conditional_annotation_index++;
1180
1
    }
1181
103
    else {
1182
103
        index = PyLong_FromLong(-1);
1183
103
        if (index == NULL) {
1184
0
            return ERROR;
1185
0
        }
1186
103
    }
1187
104
    int rc = PyList_Append(c->u->u_conditional_annotation_indices, index);
1188
104
    Py_DECREF(index);
1189
104
    RETURN_IF_ERROR(rc);
1190
104
    return SUCCESS;
1191
104
}
1192
1193
/* Raises a SyntaxError and returns ERROR.
1194
 * If something goes wrong, a different exception may be raised.
1195
 */
1196
int
1197
_PyCompile_Error(compiler *c, location loc, const char *format, ...)
1198
0
{
1199
0
    va_list vargs;
1200
0
    va_start(vargs, format);
1201
0
    PyObject *msg = PyUnicode_FromFormatV(format, vargs);
1202
0
    va_end(vargs);
1203
0
    if (msg == NULL) {
1204
0
        return ERROR;
1205
0
    }
1206
0
    _PyErr_RaiseSyntaxError(msg, c->c_filename, loc.lineno, loc.col_offset + 1,
1207
0
                            loc.end_lineno, loc.end_col_offset + 1);
1208
0
    Py_DECREF(msg);
1209
0
    return ERROR;
1210
0
}
1211
1212
/* Emits a SyntaxWarning and returns 0 on success.
1213
   If a SyntaxWarning raised as error, replaces it with a SyntaxError
1214
   and returns -1.
1215
*/
1216
int
1217
_PyCompile_Warn(compiler *c, location loc, const char *format, ...)
1218
0
{
1219
0
    if (c->c_disable_warning) {
1220
0
        return 0;
1221
0
    }
1222
0
    va_list vargs;
1223
0
    va_start(vargs, format);
1224
0
    PyObject *msg = PyUnicode_FromFormatV(format, vargs);
1225
0
    va_end(vargs);
1226
0
    if (msg == NULL) {
1227
0
        return ERROR;
1228
0
    }
1229
0
    int ret = _PyErr_EmitSyntaxWarning(msg, c->c_filename, loc.lineno, loc.col_offset + 1,
1230
0
                                       loc.end_lineno, loc.end_col_offset + 1,
1231
0
                                       c->c_module);
1232
0
    Py_DECREF(msg);
1233
0
    return ret;
1234
0
}
1235
1236
PyObject *
1237
_PyCompile_Mangle(compiler *c, PyObject *name)
1238
104
{
1239
104
    return _Py_Mangle(c->u->u_private, name);
1240
104
}
1241
1242
PyObject *
1243
_PyCompile_MaybeMangle(compiler *c, PyObject *name)
1244
166k
{
1245
166k
    return _Py_MaybeMangle(c->u->u_private, c->u->u_ste, name);
1246
166k
}
1247
1248
instr_sequence *
1249
_PyCompile_InstrSequence(compiler *c)
1250
589k
{
1251
589k
    return c->u->u_instr_sequence;
1252
589k
}
1253
1254
int
1255
_PyCompile_StartAnnotationSetup(struct _PyCompiler *c)
1256
1
{
1257
1
    instr_sequence *new_seq = (instr_sequence *)_PyInstructionSequence_New();
1258
1
    if (new_seq == NULL) {
1259
0
        return ERROR;
1260
0
    }
1261
1
    assert(c->u->u_stashed_instr_sequence == NULL);
1262
1
    c->u->u_stashed_instr_sequence = c->u->u_instr_sequence;
1263
1
    c->u->u_instr_sequence = new_seq;
1264
1
    return SUCCESS;
1265
1
}
1266
1267
int
1268
_PyCompile_EndAnnotationSetup(struct _PyCompiler *c)
1269
1
{
1270
1
    assert(c->u->u_stashed_instr_sequence != NULL);
1271
1
    instr_sequence *parent_seq = c->u->u_stashed_instr_sequence;
1272
1
    instr_sequence *anno_seq = c->u->u_instr_sequence;
1273
1
    c->u->u_stashed_instr_sequence = NULL;
1274
1
    c->u->u_instr_sequence = parent_seq;
1275
1
    if (_PyInstructionSequence_SetAnnotationsCode(parent_seq, anno_seq) == ERROR) {
1276
0
        Py_DECREF(anno_seq);
1277
0
        return ERROR;
1278
0
    }
1279
1
    return SUCCESS;
1280
1
}
1281
1282
1283
int
1284
_PyCompile_FutureFeatures(compiler *c)
1285
3.61k
{
1286
3.61k
    return c->c_future.ff_features;
1287
3.61k
}
1288
1289
struct symtable *
1290
_PyCompile_Symtable(compiler *c)
1291
16.6k
{
1292
16.6k
    return c->c_st;
1293
16.6k
}
1294
1295
PySTEntryObject *
1296
_PyCompile_SymtableEntry(compiler *c)
1297
196k
{
1298
196k
    return c->u->u_ste;
1299
196k
}
1300
1301
int
1302
_PyCompile_OptimizationLevel(compiler *c)
1303
198
{
1304
198
    return c->c_optimize;
1305
198
}
1306
1307
int
1308
_PyCompile_IsInteractiveTopLevel(compiler *c)
1309
6.27k
{
1310
6.27k
    assert(c->c_stack != NULL);
1311
6.27k
    assert(PyList_CheckExact(c->c_stack));
1312
6.27k
    bool is_nested_scope = PyList_GET_SIZE(c->c_stack) > 0;
1313
6.27k
    return c->c_interactive && !is_nested_scope;
1314
6.27k
}
1315
1316
int
1317
_PyCompile_ScopeType(compiler *c)
1318
298
{
1319
298
    return c->u->u_scope_type;
1320
298
}
1321
1322
int
1323
_PyCompile_IsInInlinedComp(compiler *c)
1324
2.91k
{
1325
2.91k
    return c->u->u_in_inlined_comp;
1326
2.91k
}
1327
1328
PyObject *
1329
_PyCompile_Qualname(compiler *c)
1330
1.25k
{
1331
1.25k
    assert(c->u->u_metadata.u_qualname);
1332
1.25k
    return c->u->u_metadata.u_qualname;
1333
1.25k
}
1334
1335
_PyCompile_CodeUnitMetadata *
1336
_PyCompile_Metadata(compiler *c)
1337
118k
{
1338
118k
    return &c->u->u_metadata;
1339
118k
}
1340
1341
// Merge *obj* with constant cache, without recursion.
1342
int
1343
_PyCompile_ConstCacheMergeOne(PyObject *const_cache, PyObject **obj)
1344
52.6k
{
1345
52.6k
    PyObject *key = const_cache_insert(const_cache, *obj, false);
1346
52.6k
    if (key == NULL) {
1347
0
        return ERROR;
1348
0
    }
1349
52.6k
    if (PyTuple_CheckExact(key)) {
1350
51.9k
        PyObject *item = PyTuple_GET_ITEM(key, 1);
1351
51.9k
        Py_SETREF(*obj, Py_NewRef(item));
1352
51.9k
        Py_DECREF(key);
1353
51.9k
    }
1354
742
    else {
1355
742
        Py_SETREF(*obj, key);
1356
742
    }
1357
52.6k
    return SUCCESS;
1358
52.6k
}
1359
1360
static PyObject *
1361
consts_dict_keys_inorder(PyObject *dict)
1362
8.29k
{
1363
8.29k
    PyObject *consts, *k, *v;
1364
8.29k
    Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict);
1365
1366
8.29k
    consts = PyList_New(size);   /* PyCode_Optimize() requires a list */
1367
8.29k
    if (consts == NULL)
1368
0
        return NULL;
1369
67.5k
    while (PyDict_Next(dict, &pos, &k, &v)) {
1370
59.2k
        assert(PyLong_CheckExact(v));
1371
59.2k
        i = PyLong_AsLong(v);
1372
        /* The keys of the dictionary can be tuples wrapping a constant.
1373
         * (see _PyCompile_DictAddObj and _PyCode_ConstantKey). In that case
1374
         * the object we want is always second. */
1375
59.2k
        if (PyTuple_CheckExact(k)) {
1376
4.85k
            k = PyTuple_GET_ITEM(k, 1);
1377
4.85k
        }
1378
59.2k
        assert(i < size);
1379
59.2k
        assert(i >= 0);
1380
59.2k
        PyList_SET_ITEM(consts, i, Py_NewRef(k));
1381
59.2k
    }
1382
8.29k
    return consts;
1383
8.29k
}
1384
1385
static int
1386
compute_code_flags(compiler *c)
1387
8.29k
{
1388
8.29k
    PySTEntryObject *ste = c->u->u_ste;
1389
8.29k
    int flags = 0;
1390
8.29k
    if (_PyST_IsFunctionLike(ste)) {
1391
6.59k
        flags |= CO_NEWLOCALS | CO_OPTIMIZED;
1392
6.59k
        if (ste->ste_nested)
1393
658
            flags |= CO_NESTED;
1394
6.59k
        if (ste->ste_generator && !ste->ste_coroutine)
1395
409
            flags |= CO_GENERATOR;
1396
6.59k
        if (ste->ste_generator && ste->ste_coroutine)
1397
1
            flags |= CO_ASYNC_GENERATOR;
1398
6.59k
        if (ste->ste_varargs)
1399
212
            flags |= CO_VARARGS;
1400
6.59k
        if (ste->ste_varkeywords)
1401
172
            flags |= CO_VARKEYWORDS;
1402
6.59k
        if (ste->ste_has_docstring)
1403
2.08k
            flags |= CO_HAS_DOCSTRING;
1404
6.59k
        if (ste->ste_method)
1405
3.89k
            flags |= CO_METHOD;
1406
6.59k
    }
1407
1408
8.29k
    if (ste->ste_coroutine && !ste->ste_generator) {
1409
15
        flags |= CO_COROUTINE;
1410
15
    }
1411
1412
    /* (Only) inherit compilerflags in PyCF_MASK */
1413
8.29k
    flags |= (c->c_flags.cf_flags & PyCF_MASK);
1414
1415
8.29k
    return flags;
1416
8.29k
}
1417
1418
static PyCodeObject *
1419
optimize_and_assemble_code_unit(struct compiler_unit *u, PyObject *const_cache,
1420
                                int code_flags, PyObject *filename)
1421
8.29k
{
1422
8.29k
    cfg_builder *g = NULL;
1423
8.29k
    instr_sequence optimized_instrs;
1424
8.29k
    memset(&optimized_instrs, 0, sizeof(instr_sequence));
1425
1426
8.29k
    PyCodeObject *co = NULL;
1427
8.29k
    PyObject *consts = consts_dict_keys_inorder(u->u_metadata.u_consts);
1428
8.29k
    if (consts == NULL) {
1429
0
        goto error;
1430
0
    }
1431
8.29k
    g = _PyCfg_FromInstructionSequence(u->u_instr_sequence);
1432
8.29k
    if (g == NULL) {
1433
0
        goto error;
1434
0
    }
1435
8.29k
    int nlocals = (int)PyDict_GET_SIZE(u->u_metadata.u_varnames);
1436
8.29k
    int nparams = (int)PyList_GET_SIZE(u->u_ste->ste_varnames);
1437
8.29k
    assert(u->u_metadata.u_firstlineno);
1438
1439
8.29k
    if (_PyCfg_OptimizeCodeUnit(g, consts, const_cache, nlocals,
1440
8.29k
                                nparams, u->u_metadata.u_firstlineno) < 0) {
1441
0
        goto error;
1442
0
    }
1443
1444
8.29k
    int stackdepth;
1445
8.29k
    int nlocalsplus;
1446
8.29k
    if (_PyCfg_OptimizedCfgToInstructionSequence(g, &u->u_metadata,
1447
8.29k
                                                 &stackdepth, &nlocalsplus,
1448
8.29k
                                                 &optimized_instrs) < 0) {
1449
0
        goto error;
1450
0
    }
1451
1452
    /** Assembly **/
1453
8.29k
    co = _PyAssemble_MakeCodeObject(&u->u_metadata, const_cache, consts,
1454
8.29k
                                    stackdepth, &optimized_instrs, nlocalsplus,
1455
8.29k
                                    code_flags, filename);
1456
1457
8.29k
error:
1458
8.29k
    Py_XDECREF(consts);
1459
8.29k
    PyInstructionSequence_Fini(&optimized_instrs);
1460
8.29k
    _PyCfgBuilder_Free(g);
1461
8.29k
    return co;
1462
8.29k
}
1463
1464
1465
PyCodeObject *
1466
_PyCompile_OptimizeAndAssemble(compiler *c, int addNone)
1467
8.29k
{
1468
8.29k
    struct compiler_unit *u = c->u;
1469
8.29k
    PyObject *const_cache = c->c_const_cache;
1470
8.29k
    PyObject *filename = c->c_filename;
1471
1472
8.29k
    int code_flags = compute_code_flags(c);
1473
8.29k
    if (code_flags < 0) {
1474
0
        return NULL;
1475
0
    }
1476
1477
8.29k
    if (_PyCodegen_AddReturnAtEnd(c, addNone) < 0) {
1478
0
        return NULL;
1479
0
    }
1480
1481
8.29k
    return optimize_and_assemble_code_unit(u, const_cache, code_flags, filename);
1482
8.29k
}
1483
1484
PyCodeObject *
1485
_PyAST_Compile(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags,
1486
               int optimize, PyArena *arena, PyObject *module)
1487
444
{
1488
444
    assert(!PyErr_Occurred());
1489
444
    compiler *c = new_compiler(mod, filename, pflags, optimize, arena, module);
1490
444
    if (c == NULL) {
1491
0
        return NULL;
1492
0
    }
1493
1494
444
    PyCodeObject *co = compiler_mod(c, mod);
1495
444
    compiler_free(c);
1496
444
    assert(co || PyErr_Occurred());
1497
444
    return co;
1498
444
}
1499
1500
int
1501
_PyCompile_AstPreprocess(mod_ty mod, PyObject *filename, PyCompilerFlags *cf,
1502
                         int optimize, PyArena *arena, int no_const_folding,
1503
                         PyObject *module)
1504
5.95k
{
1505
5.95k
    _PyFutureFeatures future;
1506
5.95k
    if (!_PyFuture_FromAST(mod, filename, &future)) {
1507
15
        return -1;
1508
15
    }
1509
5.94k
    int flags = future.ff_features | cf->cf_flags;
1510
5.94k
    if (optimize == -1) {
1511
5.94k
        optimize = _Py_GetConfig()->optimization_level;
1512
5.94k
    }
1513
5.94k
    if (!_PyAST_Preprocess(mod, arena, filename, optimize, flags,
1514
5.94k
                           no_const_folding, 0, module))
1515
0
    {
1516
0
        return -1;
1517
0
    }
1518
5.94k
    return 0;
1519
5.94k
}
1520
1521
// C implementation of inspect.cleandoc()
1522
//
1523
// Difference from inspect.cleandoc():
1524
// - Do not remove leading and trailing blank lines to keep lineno.
1525
PyObject *
1526
_PyCompile_CleanDoc(PyObject *doc)
1527
2.67k
{
1528
2.67k
    doc = PyObject_CallMethod(doc, "expandtabs", NULL);
1529
2.67k
    if (doc == NULL) {
1530
0
        return NULL;
1531
0
    }
1532
1533
2.67k
    Py_ssize_t doc_size;
1534
2.67k
    const char *doc_utf8 = PyUnicode_AsUTF8AndSize(doc, &doc_size);
1535
2.67k
    if (doc_utf8 == NULL) {
1536
0
        Py_DECREF(doc);
1537
0
        return NULL;
1538
0
    }
1539
2.67k
    const char *p = doc_utf8;
1540
2.67k
    const char *pend = p + doc_size;
1541
1542
    // First pass: find minimum indentation of any non-blank lines
1543
    // after first line.
1544
117k
    while (p < pend && *p++ != '\n') {
1545
114k
    }
1546
1547
2.67k
    Py_ssize_t margin = PY_SSIZE_T_MAX;
1548
17.6k
    while (p < pend) {
1549
14.9k
        const char *s = p;
1550
89.2k
        while (*p == ' ') p++;
1551
14.9k
        if (p < pend && *p != '\n') {
1552
10.0k
            margin = Py_MIN(margin, p - s);
1553
10.0k
        }
1554
501k
        while (p < pend && *p++ != '\n') {
1555
486k
        }
1556
14.9k
    }
1557
2.67k
    if (margin == PY_SSIZE_T_MAX) {
1558
901
        margin = 0;
1559
901
    }
1560
1561
    // Second pass: write cleandoc into buff.
1562
1563
    // copy first line without leading spaces.
1564
2.67k
    p = doc_utf8;
1565
2.81k
    while (*p == ' ') {
1566
139
        p++;
1567
139
    }
1568
2.67k
    if (p == doc_utf8 && margin == 0 ) {
1569
        // doc is already clean.
1570
896
        return doc;
1571
896
    }
1572
1573
1.77k
    char *buff = PyMem_Malloc(doc_size);
1574
1.77k
    if (buff == NULL){
1575
0
        Py_DECREF(doc);
1576
0
        PyErr_NoMemory();
1577
0
        return NULL;
1578
0
    }
1579
1580
1.77k
    char *w = buff;
1581
1582
76.0k
    while (p < pend) {
1583
76.0k
        int ch = *w++ = *p++;
1584
76.0k
        if (ch == '\n') {
1585
1.77k
            break;
1586
1.77k
        }
1587
76.0k
    }
1588
1589
    // copy subsequent lines without margin.
1590
15.0k
    while (p < pend) {
1591
72.7k
        for (Py_ssize_t i = 0; i < margin; i++, p++) {
1592
62.3k
            if (*p != ' ') {
1593
2.90k
                assert(*p == '\n' || *p == '\0');
1594
2.90k
                break;
1595
2.90k
            }
1596
62.3k
        }
1597
449k
        while (p < pend) {
1598
447k
            int ch = *w++ = *p++;
1599
447k
            if (ch == '\n') {
1600
11.5k
                break;
1601
11.5k
            }
1602
447k
        }
1603
13.2k
    }
1604
1605
1.77k
    Py_DECREF(doc);
1606
1.77k
    PyObject *res = PyUnicode_FromStringAndSize(buff, w - buff);
1607
1.77k
    PyMem_Free(buff);
1608
1.77k
    return res;
1609
1.77k
}
1610
1611
/* Access to compiler optimizations for unit tests.
1612
 *
1613
 * _PyCompile_CodeGen takes an AST, applies code-gen and
1614
 * returns the unoptimized CFG as an instruction list.
1615
 *
1616
 */
1617
PyObject *
1618
_PyCompile_CodeGen(PyObject *ast, PyObject *filename, PyCompilerFlags *pflags,
1619
                   int optimize, int compile_mode)
1620
0
{
1621
0
    PyObject *res = NULL;
1622
0
    PyObject *metadata = NULL;
1623
1624
0
    if (!PyAST_Check(ast)) {
1625
0
        PyErr_SetString(PyExc_TypeError, "expected an AST");
1626
0
        return NULL;
1627
0
    }
1628
1629
0
    PyArena *arena = _PyArena_New();
1630
0
    if (arena == NULL) {
1631
0
        return NULL;
1632
0
    }
1633
1634
0
    mod_ty mod = PyAST_obj2mod(ast, arena, compile_mode);
1635
0
    if (mod == NULL || !_PyAST_Validate(mod)) {
1636
0
        _PyArena_Free(arena);
1637
0
        return NULL;
1638
0
    }
1639
1640
0
    compiler *c = new_compiler(mod, filename, pflags, optimize, arena, NULL);
1641
0
    if (c == NULL) {
1642
0
        _PyArena_Free(arena);
1643
0
        return NULL;
1644
0
    }
1645
0
    c->c_save_nested_seqs = true;
1646
1647
0
    metadata = PyDict_New();
1648
0
    if (metadata == NULL) {
1649
0
        return NULL;
1650
0
    }
1651
1652
0
    if (compiler_codegen(c, mod) < 0) {
1653
0
        goto finally;
1654
0
    }
1655
1656
0
    _PyCompile_CodeUnitMetadata *umd = &c->u->u_metadata;
1657
1658
0
#define SET_METADATA_INT(key, value) do { \
1659
0
        PyObject *v = PyLong_FromLong((long)value); \
1660
0
        if (v == NULL) goto finally; \
1661
0
        int res = PyDict_SetItemString(metadata, key, v); \
1662
0
        Py_XDECREF(v); \
1663
0
        if (res < 0) goto finally; \
1664
0
    } while (0);
1665
1666
0
    SET_METADATA_INT("argcount", umd->u_argcount);
1667
0
    SET_METADATA_INT("posonlyargcount", umd->u_posonlyargcount);
1668
0
    SET_METADATA_INT("kwonlyargcount", umd->u_kwonlyargcount);
1669
0
#undef SET_METADATA_INT
1670
1671
0
    int addNone = mod->kind != Expression_kind;
1672
0
    if (_PyCodegen_AddReturnAtEnd(c, addNone) < 0) {
1673
0
        goto finally;
1674
0
    }
1675
1676
0
    if (_PyInstructionSequence_ApplyLabelMap(_PyCompile_InstrSequence(c)) < 0) {
1677
0
        return NULL;
1678
0
    }
1679
    /* Allocate a copy of the instruction sequence on the heap */
1680
0
    res = PyTuple_Pack(2, _PyCompile_InstrSequence(c), metadata);
1681
1682
0
finally:
1683
0
    Py_XDECREF(metadata);
1684
0
    _PyCompile_ExitScope(c);
1685
0
    compiler_free(c);
1686
0
    _PyArena_Free(arena);
1687
0
    return res;
1688
0
}
1689
1690
int _PyCfg_JumpLabelsToTargets(cfg_builder *g);
1691
1692
PyCodeObject *
1693
_PyCompile_Assemble(_PyCompile_CodeUnitMetadata *umd, PyObject *filename,
1694
                    PyObject *seq)
1695
0
{
1696
0
    if (!_PyInstructionSequence_Check(seq)) {
1697
0
        PyErr_SetString(PyExc_TypeError, "expected an instruction sequence");
1698
0
        return NULL;
1699
0
    }
1700
0
    cfg_builder *g = NULL;
1701
0
    PyCodeObject *co = NULL;
1702
0
    instr_sequence optimized_instrs;
1703
0
    memset(&optimized_instrs, 0, sizeof(instr_sequence));
1704
1705
0
    PyObject *const_cache = PyDict_New();
1706
0
    if (const_cache == NULL) {
1707
0
        return NULL;
1708
0
    }
1709
1710
0
    g = _PyCfg_FromInstructionSequence((instr_sequence*)seq);
1711
0
    if (g == NULL) {
1712
0
        goto error;
1713
0
    }
1714
1715
0
    if (_PyCfg_JumpLabelsToTargets(g) < 0) {
1716
0
        goto error;
1717
0
    }
1718
1719
0
    int code_flags = 0;
1720
0
    int stackdepth, nlocalsplus;
1721
0
    if (_PyCfg_OptimizedCfgToInstructionSequence(g, umd,
1722
0
                                                 &stackdepth, &nlocalsplus,
1723
0
                                                 &optimized_instrs) < 0) {
1724
0
        goto error;
1725
0
    }
1726
1727
0
    PyObject *consts = consts_dict_keys_inorder(umd->u_consts);
1728
0
    if (consts == NULL) {
1729
0
        goto error;
1730
0
    }
1731
0
    co = _PyAssemble_MakeCodeObject(umd, const_cache,
1732
0
                                    consts, stackdepth, &optimized_instrs,
1733
0
                                    nlocalsplus, code_flags, filename);
1734
0
    Py_DECREF(consts);
1735
1736
0
error:
1737
0
    Py_DECREF(const_cache);
1738
0
    _PyCfgBuilder_Free(g);
1739
0
    PyInstructionSequence_Fini(&optimized_instrs);
1740
0
    return co;
1741
0
}
1742
1743
/* Retained for API compatibility.
1744
 * Optimization is now done in _PyCfg_OptimizeCodeUnit */
1745
1746
PyObject *
1747
PyCode_Optimize(PyObject *code, PyObject* Py_UNUSED(consts),
1748
                PyObject *Py_UNUSED(names), PyObject *Py_UNUSED(lnotab_obj))
1749
0
{
1750
0
    return Py_NewRef(code);
1751
0
}