Coverage Report

Created: 2025-12-07 07:03

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
236k
#define SUCCESS 0
36
1
#define ERROR -1
37
38
#define RETURN_IF_ERROR(X)  \
39
84.8k
    do {                    \
40
84.8k
        if ((X) == -1) {    \
41
0
            return ERROR;   \
42
0
        }                   \
43
84.8k
    } 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
454
{
115
454
    PyCompilerFlags local_flags = _PyCompilerFlags_INIT;
116
117
454
    c->c_const_cache = PyDict_New();
118
454
    if (!c->c_const_cache) {
119
0
        return ERROR;
120
0
    }
121
122
454
    c->c_stack = PyList_New(0);
123
454
    if (!c->c_stack) {
124
0
        return ERROR;
125
0
    }
126
127
454
    c->c_filename = Py_NewRef(filename);
128
454
    if (!_PyFuture_FromAST(mod, filename, &c->c_future)) {
129
0
        return ERROR;
130
0
    }
131
454
    c->c_module = Py_XNewRef(module);
132
454
    if (!flags) {
133
84
        flags = &local_flags;
134
84
    }
135
454
    int merged = c->c_future.ff_features | flags->cf_flags;
136
454
    c->c_future.ff_features = merged;
137
454
    flags->cf_flags = merged;
138
454
    c->c_flags = *flags;
139
454
    c->c_optimize = (optimize == -1) ? _Py_GetConfig()->optimization_level : optimize;
140
454
    c->c_save_nested_seqs = false;
141
142
454
    if (!_PyAST_Preprocess(mod, arena, filename, c->c_optimize, merged,
143
454
                           0, 1, module))
144
0
    {
145
0
        return ERROR;
146
0
    }
147
454
    c->c_st = _PySymtable_Build(mod, filename, &c->c_future);
148
454
    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
454
    return SUCCESS;
155
454
}
156
157
static void
158
compiler_free(compiler *c)
159
454
{
160
454
    if (c->c_st) {
161
454
        _PySymtable_Free(c->c_st);
162
454
    }
163
454
    Py_XDECREF(c->c_filename);
164
454
    Py_XDECREF(c->c_module);
165
454
    Py_XDECREF(c->c_const_cache);
166
454
    Py_XDECREF(c->c_stack);
167
454
    PyMem_Free(c);
168
454
}
169
170
static compiler*
171
new_compiler(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags,
172
             int optimize, PyArena *arena, PyObject *module)
173
454
{
174
454
    compiler *c = PyMem_Calloc(1, sizeof(compiler));
175
454
    if (c == NULL) {
176
0
        return NULL;
177
0
    }
178
454
    if (compiler_setup(c, mod, filename, pflags, optimize, arena, module) < 0) {
179
0
        compiler_free(c);
180
0
        return NULL;
181
0
    }
182
454
    return c;
183
454
}
184
185
static void
186
compiler_unit_free(struct compiler_unit *u)
187
8.54k
{
188
8.54k
    Py_CLEAR(u->u_instr_sequence);
189
8.54k
    Py_CLEAR(u->u_stashed_instr_sequence);
190
8.54k
    Py_CLEAR(u->u_ste);
191
8.54k
    Py_CLEAR(u->u_metadata.u_name);
192
8.54k
    Py_CLEAR(u->u_metadata.u_qualname);
193
8.54k
    Py_CLEAR(u->u_metadata.u_consts);
194
8.54k
    Py_CLEAR(u->u_metadata.u_names);
195
8.54k
    Py_CLEAR(u->u_metadata.u_varnames);
196
8.54k
    Py_CLEAR(u->u_metadata.u_freevars);
197
8.54k
    Py_CLEAR(u->u_metadata.u_cellvars);
198
8.54k
    Py_CLEAR(u->u_metadata.u_fasthidden);
199
8.54k
    Py_CLEAR(u->u_private);
200
8.54k
    Py_CLEAR(u->u_static_attributes);
201
8.54k
    Py_CLEAR(u->u_deferred_annotations);
202
8.54k
    Py_CLEAR(u->u_conditional_annotation_indices);
203
8.54k
    PyMem_Free(u);
204
8.54k
}
205
206
22.8k
#define CAPSULE_NAME "compile.c compiler unit"
207
208
int
209
_PyCompile_MaybeAddStaticAttributeToClass(compiler *c, expr_ty e)
210
19.2k
{
211
19.2k
    assert(e->kind == Attribute_kind);
212
19.2k
    expr_ty attr_value = e->v.Attribute.value;
213
19.2k
    if (attr_value->kind != Name_kind ||
214
17.9k
        e->v.Attribute.ctx != Store ||
215
2.56k
        !_PyUnicode_EqualToASCIIString(attr_value->v.Name.id, "self"))
216
17.4k
    {
217
17.4k
        return SUCCESS;
218
17.4k
    }
219
1.84k
    Py_ssize_t stack_size = PyList_GET_SIZE(c->c_stack);
220
1.84k
    for (Py_ssize_t i = stack_size - 1; i >= 0; i--) {
221
1.84k
        PyObject *capsule = PyList_GET_ITEM(c->c_stack, i);
222
1.84k
        struct compiler_unit *u = (struct compiler_unit *)PyCapsule_GetPointer(
223
1.84k
                                                              capsule, CAPSULE_NAME);
224
1.84k
        assert(u);
225
1.84k
        if (u->u_scope_type == COMPILE_SCOPE_CLASS) {
226
1.83k
            assert(u->u_static_attributes);
227
1.83k
            RETURN_IF_ERROR(PySet_Add(u->u_static_attributes, e->v.Attribute.attr));
228
1.83k
            break;
229
1.83k
        }
230
1.84k
    }
231
1.84k
    return SUCCESS;
232
1.84k
}
233
234
static int
235
compiler_set_qualname(compiler *c)
236
8.09k
{
237
8.09k
    Py_ssize_t stack_size;
238
8.09k
    struct compiler_unit *u = c->u;
239
8.09k
    PyObject *name, *base;
240
241
8.09k
    base = NULL;
242
8.09k
    stack_size = PyList_GET_SIZE(c->c_stack);
243
8.09k
    assert(stack_size >= 1);
244
8.09k
    if (stack_size > 1) {
245
4.77k
        int scope, force_global = 0;
246
4.77k
        struct compiler_unit *parent;
247
4.77k
        PyObject *mangled, *capsule;
248
249
4.77k
        capsule = PyList_GET_ITEM(c->c_stack, stack_size - 1);
250
4.77k
        parent = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME);
251
4.77k
        assert(parent);
252
4.77k
        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.76k
        if (u->u_scope_type == COMPILE_SCOPE_FUNCTION
267
481
            || u->u_scope_type == COMPILE_SCOPE_ASYNC_FUNCTION
268
4.30k
            || u->u_scope_type == COMPILE_SCOPE_CLASS) {
269
4.30k
            assert(u->u_metadata.u_name);
270
4.30k
            mangled = _Py_Mangle(parent->u_private, u->u_metadata.u_name);
271
4.30k
            if (!mangled) {
272
0
                return ERROR;
273
0
            }
274
275
4.30k
            scope = _PyST_GetScope(parent->u_ste, mangled);
276
4.30k
            Py_DECREF(mangled);
277
4.30k
            RETURN_IF_ERROR(scope);
278
4.30k
            assert(scope != GLOBAL_IMPLICIT);
279
4.30k
            if (scope == GLOBAL_EXPLICIT)
280
0
                force_global = 1;
281
4.30k
        }
282
283
4.76k
        if (!force_global) {
284
4.76k
            if (parent->u_scope_type == COMPILE_SCOPE_FUNCTION
285
4.11k
                || parent->u_scope_type == COMPILE_SCOPE_ASYNC_FUNCTION
286
4.11k
                || parent->u_scope_type == COMPILE_SCOPE_LAMBDA)
287
657
            {
288
657
                _Py_DECLARE_STR(dot_locals, ".<locals>");
289
657
                base = PyUnicode_Concat(parent->u_metadata.u_qualname,
290
657
                                        &_Py_STR(dot_locals));
291
657
                if (base == NULL) {
292
0
                    return ERROR;
293
0
                }
294
657
            }
295
4.11k
            else {
296
4.11k
                base = Py_NewRef(parent->u_metadata.u_qualname);
297
4.11k
            }
298
4.76k
        }
299
4.76k
    }
300
301
8.08k
    if (base != NULL) {
302
4.76k
        name = PyUnicode_Concat(base, _Py_LATIN1_CHR('.'));
303
4.76k
        Py_DECREF(base);
304
4.76k
        if (name == NULL) {
305
0
            return ERROR;
306
0
        }
307
4.76k
        PyUnicode_Append(&name, u->u_metadata.u_name);
308
4.76k
        if (name == NULL) {
309
0
            return ERROR;
310
0
        }
311
4.76k
    }
312
3.31k
    else {
313
3.31k
        name = Py_NewRef(u->u_metadata.u_name);
314
3.31k
    }
315
8.08k
    u->u_metadata.u_qualname = name;
316
317
8.08k
    return SUCCESS;
318
8.08k
}
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
149k
{
326
149k
    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
149k
    if (o == Py_None || o == Py_Ellipsis) {
330
17.3k
        return o;
331
17.3k
    }
332
333
131k
    PyObject *key = _PyCode_ConstantKey(o);
334
131k
    if (key == NULL) {
335
0
        return NULL;
336
0
    }
337
338
131k
    PyObject *t;
339
131k
    int res = PyDict_SetDefaultRef(const_cache, key, key, &t);
340
131k
    if (res != 0) {
341
        // o was not inserted into const_cache. t is either the existing value
342
        // or NULL (on error).
343
50.3k
        Py_DECREF(key);
344
50.3k
        return t;
345
50.3k
    }
346
81.3k
    Py_DECREF(t);
347
348
81.3k
    if (!recursive) {
349
36.4k
        return key;
350
36.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
44.8k
    if (PyTuple_CheckExact(o)) {
356
1.49k
        Py_ssize_t len = PyTuple_GET_SIZE(o);
357
5.13k
        for (Py_ssize_t i = 0; i < len; i++) {
358
3.64k
            PyObject *item = PyTuple_GET_ITEM(o, i);
359
3.64k
            PyObject *u = const_cache_insert(const_cache, item, recursive);
360
3.64k
            if (u == NULL) {
361
0
                Py_DECREF(key);
362
0
                return NULL;
363
0
            }
364
365
            // See _PyCode_ConstantKey()
366
3.64k
            PyObject *v;  // borrowed
367
3.64k
            if (PyTuple_CheckExact(u)) {
368
0
                v = PyTuple_GET_ITEM(u, 1);
369
0
            }
370
3.64k
            else {
371
3.64k
                v = u;
372
3.64k
            }
373
3.64k
            if (v != item) {
374
257
                PyTuple_SET_ITEM(o, i, Py_NewRef(v));
375
257
                Py_DECREF(item);
376
257
            }
377
378
3.64k
            Py_DECREF(u);
379
3.64k
        }
380
1.49k
    }
381
43.3k
    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
44.8k
    return key;
433
44.8k
}
434
435
static PyObject*
436
merge_consts_recursive(PyObject *const_cache, PyObject *o)
437
91.1k
{
438
91.1k
    return const_cache_insert(const_cache, o, true);
439
91.1k
}
440
441
Py_ssize_t
442
_PyCompile_DictAddObj(PyObject *dict, PyObject *o)
443
264k
{
444
264k
    PyObject *v;
445
264k
    Py_ssize_t arg;
446
447
264k
    if (PyDict_GetItemRef(dict, o, &v) < 0) {
448
0
        return ERROR;
449
0
    }
450
264k
    if (!v) {
451
131k
        arg = PyDict_GET_SIZE(dict);
452
131k
        v = PyLong_FromSsize_t(arg);
453
131k
        if (!v) {
454
0
            return ERROR;
455
0
        }
456
131k
        if (PyDict_SetItem(dict, o, v) < 0) {
457
0
            Py_DECREF(v);
458
0
            return ERROR;
459
0
        }
460
131k
    }
461
133k
    else
462
133k
        arg = PyLong_AsLong(v);
463
264k
    Py_DECREF(v);
464
264k
    return arg;
465
264k
}
466
467
Py_ssize_t
468
_PyCompile_AddConst(compiler *c, PyObject *o)
469
91.1k
{
470
91.1k
    PyObject *key = merge_consts_recursive(c->c_const_cache, o);
471
91.1k
    if (key == NULL) {
472
0
        return ERROR;
473
0
    }
474
475
91.1k
    Py_ssize_t arg = _PyCompile_DictAddObj(c->u->u_metadata.u_consts, key);
476
91.1k
    Py_DECREF(key);
477
91.1k
    return arg;
478
91.1k
}
479
480
static PyObject *
481
list2dict(PyObject *list)
482
8.54k
{
483
8.54k
    Py_ssize_t i, n;
484
8.54k
    PyObject *v, *k;
485
8.54k
    PyObject *dict = PyDict_New();
486
8.54k
    if (!dict) return NULL;
487
488
8.54k
    n = PyList_Size(list);
489
22.3k
    for (i = 0; i < n; i++) {
490
13.8k
        v = PyLong_FromSsize_t(i);
491
13.8k
        if (!v) {
492
0
            Py_DECREF(dict);
493
0
            return NULL;
494
0
        }
495
13.8k
        k = PyList_GET_ITEM(list, i);
496
13.8k
        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.8k
        Py_DECREF(v);
502
13.8k
    }
503
8.54k
    return dict;
504
8.54k
}
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
17.0k
{
517
17.0k
    Py_ssize_t i = offset, num_keys, key_i;
518
17.0k
    PyObject *k, *v, *dest = PyDict_New();
519
17.0k
    PyObject *sorted_keys;
520
521
17.0k
    assert(offset >= 0);
522
17.0k
    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
17.0k
    sorted_keys = PyDict_Keys(src);
531
17.0k
    if (sorted_keys == NULL) {
532
0
        Py_DECREF(dest);
533
0
        return NULL;
534
0
    }
535
17.0k
    if (PyList_Sort(sorted_keys) != 0) {
536
0
        Py_DECREF(sorted_keys);
537
0
        Py_DECREF(dest);
538
0
        return NULL;
539
0
    }
540
17.0k
    num_keys = PyList_GET_SIZE(sorted_keys);
541
542
126k
    for (key_i = 0; key_i < num_keys; key_i++) {
543
109k
        k = PyList_GET_ITEM(sorted_keys, key_i);
544
109k
        v = PyDict_GetItemWithError(src, k);
545
109k
        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
109k
        long vi = PyLong_AsLong(v);
554
109k
        if (vi == -1 && PyErr_Occurred()) {
555
0
            Py_DECREF(sorted_keys);
556
0
            Py_DECREF(dest);
557
0
            return NULL;
558
0
        }
559
109k
        if (SYMBOL_TO_SCOPE(vi) == scope_type || vi & flag) {
560
1.63k
            PyObject *item = PyLong_FromSsize_t(i);
561
1.63k
            if (item == NULL) {
562
0
                Py_DECREF(sorted_keys);
563
0
                Py_DECREF(dest);
564
0
                return NULL;
565
0
            }
566
1.63k
            i++;
567
1.63k
            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.63k
            Py_DECREF(item);
574
1.63k
        }
575
109k
    }
576
17.0k
    Py_DECREF(sorted_keys);
577
17.0k
    return dest;
578
17.0k
}
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.54k
{
585
8.54k
    struct compiler_unit *u;
586
8.54k
    u = (struct compiler_unit *)PyMem_Calloc(1, sizeof(struct compiler_unit));
587
8.54k
    if (!u) {
588
0
        PyErr_NoMemory();
589
0
        return ERROR;
590
0
    }
591
8.54k
    u->u_scope_type = scope_type;
592
8.54k
    if (umd != NULL) {
593
6.81k
        u->u_metadata = *umd;
594
6.81k
    }
595
1.72k
    else {
596
1.72k
        u->u_metadata.u_argcount = 0;
597
1.72k
        u->u_metadata.u_posonlyargcount = 0;
598
1.72k
        u->u_metadata.u_kwonlyargcount = 0;
599
1.72k
    }
600
8.54k
    u->u_ste = _PySymtable_Lookup(c->c_st, key);
601
8.54k
    if (!u->u_ste) {
602
0
        compiler_unit_free(u);
603
0
        return ERROR;
604
0
    }
605
8.54k
    u->u_metadata.u_name = Py_NewRef(name);
606
8.54k
    u->u_metadata.u_varnames = list2dict(u->u_ste->ste_varnames);
607
8.54k
    if (!u->u_metadata.u_varnames) {
608
0
        compiler_unit_free(u);
609
0
        return ERROR;
610
0
    }
611
8.54k
    u->u_metadata.u_cellvars = dictbytype(u->u_ste->ste_symbols, CELL, DEF_COMP_CELL, 0);
612
8.54k
    if (!u->u_metadata.u_cellvars) {
613
0
        compiler_unit_free(u);
614
0
        return ERROR;
615
0
    }
616
8.54k
    if (u->u_ste->ste_needs_class_closure) {
617
        /* Cook up an implicit __class__ cell. */
618
110
        Py_ssize_t res;
619
110
        assert(u->u_scope_type == COMPILE_SCOPE_CLASS);
620
110
        res = _PyCompile_DictAddObj(u->u_metadata.u_cellvars, &_Py_ID(__class__));
621
110
        if (res < 0) {
622
0
            compiler_unit_free(u);
623
0
            return ERROR;
624
0
        }
625
110
    }
626
8.54k
    if (u->u_ste->ste_needs_classdict) {
627
        /* Cook up an implicit __classdict__ cell. */
628
794
        Py_ssize_t res;
629
794
        assert(u->u_scope_type == COMPILE_SCOPE_CLASS);
630
794
        res = _PyCompile_DictAddObj(u->u_metadata.u_cellvars, &_Py_ID(__classdict__));
631
794
        if (res < 0) {
632
0
            compiler_unit_free(u);
633
0
            return ERROR;
634
0
        }
635
794
    }
636
8.54k
    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.54k
    u->u_metadata.u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS,
648
8.54k
                               PyDict_GET_SIZE(u->u_metadata.u_cellvars));
649
8.54k
    if (!u->u_metadata.u_freevars) {
650
0
        compiler_unit_free(u);
651
0
        return ERROR;
652
0
    }
653
654
8.54k
    u->u_metadata.u_fasthidden = PyDict_New();
655
8.54k
    if (!u->u_metadata.u_fasthidden) {
656
0
        compiler_unit_free(u);
657
0
        return ERROR;
658
0
    }
659
660
8.54k
    u->u_nfblocks = 0;
661
8.54k
    u->u_in_inlined_comp = 0;
662
8.54k
    u->u_metadata.u_firstlineno = lineno;
663
8.54k
    u->u_metadata.u_consts = PyDict_New();
664
8.54k
    if (!u->u_metadata.u_consts) {
665
0
        compiler_unit_free(u);
666
0
        return ERROR;
667
0
    }
668
8.54k
    u->u_metadata.u_names = PyDict_New();
669
8.54k
    if (!u->u_metadata.u_names) {
670
0
        compiler_unit_free(u);
671
0
        return ERROR;
672
0
    }
673
674
8.54k
    u->u_deferred_annotations = NULL;
675
8.54k
    u->u_conditional_annotation_indices = NULL;
676
8.54k
    u->u_next_conditional_annotation_index = 0;
677
8.54k
    if (scope_type == COMPILE_SCOPE_CLASS) {
678
1.27k
        u->u_static_attributes = PySet_New(0);
679
1.27k
        if (!u->u_static_attributes) {
680
0
            compiler_unit_free(u);
681
0
            return ERROR;
682
0
        }
683
1.27k
    }
684
7.27k
    else {
685
7.27k
        u->u_static_attributes = NULL;
686
7.27k
    }
687
688
8.54k
    u->u_instr_sequence = (instr_sequence*)_PyInstructionSequence_New();
689
8.54k
    if (!u->u_instr_sequence) {
690
0
        compiler_unit_free(u);
691
0
        return ERROR;
692
0
    }
693
8.54k
    u->u_stashed_instr_sequence = NULL;
694
695
    /* Push the old compiler_unit on the stack. */
696
8.54k
    if (c->u) {
697
8.09k
        PyObject *capsule = PyCapsule_New(c->u, CAPSULE_NAME, NULL);
698
8.09k
        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
8.09k
        Py_DECREF(capsule);
704
8.09k
        if (private == NULL) {
705
6.81k
            private = c->u->u_private;
706
6.81k
        }
707
8.09k
    }
708
709
8.54k
    u->u_private = Py_XNewRef(private);
710
711
8.54k
    c->u = u;
712
8.54k
    if (scope_type != COMPILE_SCOPE_MODULE) {
713
8.09k
        RETURN_IF_ERROR(compiler_set_qualname(c));
714
8.09k
    }
715
8.54k
    return SUCCESS;
716
8.54k
}
717
718
void
719
_PyCompile_ExitScope(compiler *c)
720
8.54k
{
721
    // Don't call PySequence_DelItem() with an exception raised
722
8.54k
    PyObject *exc = PyErr_GetRaisedException();
723
724
8.54k
    instr_sequence *nested_seq = NULL;
725
8.54k
    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.54k
    compiler_unit_free(c->u);
730
    /* Restore c->u to the parent unit. */
731
8.54k
    Py_ssize_t n = PyList_GET_SIZE(c->c_stack) - 1;
732
8.54k
    if (n >= 0) {
733
8.09k
        PyObject *capsule = PyList_GET_ITEM(c->c_stack, n);
734
8.09k
        c->u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME);
735
8.09k
        assert(c->u);
736
        /* we are deleting from a list so this really shouldn't fail */
737
8.09k
        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
8.09k
        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
8.09k
    }
748
454
    else {
749
454
        c->u = NULL;
750
454
    }
751
8.54k
    Py_XDECREF(nested_seq);
752
753
8.54k
    PyErr_SetRaisedException(exc);
754
8.54k
}
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
7.01k
{
765
7.01k
    fblockinfo *f;
766
7.01k
    if (c->u->u_nfblocks >= CO_MAXBLOCKS) {
767
0
        return _PyCompile_Error(c, loc, "too many statically nested blocks");
768
0
    }
769
7.01k
    f = &c->u->u_fblock[c->u->u_nfblocks++];
770
7.01k
    f->fb_type = t;
771
7.01k
    f->fb_block = block_label;
772
7.01k
    f->fb_loc = loc;
773
7.01k
    f->fb_exit = exit;
774
7.01k
    f->fb_datum = datum;
775
7.01k
    if (t == COMPILE_FBLOCK_FINALLY_END) {
776
75
        c->c_disable_warning++;
777
75
    }
778
7.01k
    return SUCCESS;
779
7.01k
}
780
781
void
782
_PyCompile_PopFBlock(compiler *c, fblocktype t, jump_target_label block_label)
783
7.01k
{
784
7.01k
    struct compiler_unit *u = c->u;
785
7.01k
    assert(u->u_nfblocks > 0);
786
7.01k
    u->u_nfblocks--;
787
7.01k
    assert(u->u_fblock[u->u_nfblocks].fb_type == t);
788
7.01k
    assert(SAME_JUMP_TARGET_LABEL(u->u_fblock[u->u_nfblocks].fb_block, block_label));
789
7.01k
    if (t == COMPILE_FBLOCK_FINALLY_END) {
790
75
        c->c_disable_warning--;
791
75
    }
792
7.01k
}
793
794
fblockinfo *
795
_PyCompile_TopFBlock(compiler *c)
796
9.04k
{
797
9.04k
    if (c->u->u_nfblocks == 0) {
798
6.83k
        return NULL;
799
6.83k
    }
800
2.20k
    return &c->u->u_fblock[c->u->u_nfblocks - 1];
801
9.04k
}
802
803
void
804
_PyCompile_DeferredAnnotations(compiler *c,
805
                               PyObject **deferred_annotations,
806
                               PyObject **conditional_annotation_indices)
807
1.63k
{
808
1.63k
    *deferred_annotations = Py_XNewRef(c->u->u_deferred_annotations);
809
1.63k
    *conditional_annotation_indices = Py_XNewRef(c->u->u_conditional_annotation_indices);
810
1.63k
}
811
812
static location
813
start_location(asdl_stmt_seq *stmts)
814
368
{
815
368
    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
365
        stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
822
365
        return SRC_LOCATION_FROM_AST(st);
823
365
    }
824
3
    return (const _Py_SourceLocation){1, 1, 0, 0};
825
368
}
826
827
static int
828
compiler_codegen(compiler *c, mod_ty mod)
829
454
{
830
454
    RETURN_IF_ERROR(_PyCodegen_EnterAnonymousScope(c, mod));
831
454
    assert(c->u->u_scope_type == COMPILE_SCOPE_MODULE);
832
454
    switch (mod->kind) {
833
368
    case Module_kind: {
834
368
        asdl_stmt_seq *stmts = mod->v.Module.body;
835
368
        RETURN_IF_ERROR(_PyCodegen_Module(c, start_location(stmts), stmts, false));
836
368
        break;
837
368
    }
838
368
    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
454
    return SUCCESS;
855
454
}
856
857
static PyCodeObject *
858
compiler_mod(compiler *c, mod_ty mod)
859
454
{
860
454
    PyCodeObject *co = NULL;
861
454
    int addNone = mod->kind != Expression_kind;
862
454
    if (compiler_codegen(c, mod) < 0) {
863
0
        goto finally;
864
0
    }
865
454
    co = _PyCompile_OptimizeAndAssemble(c, addNone);
866
454
finally:
867
454
    _PyCompile_ExitScope(c);
868
454
    return co;
869
454
}
870
871
int
872
_PyCompile_GetRefType(compiler *c, PyObject *name)
873
1.30k
{
874
1.30k
    if (c->u->u_scope_type == COMPILE_SCOPE_CLASS &&
875
301
        (_PyUnicode_EqualToASCIIString(name, "__class__") ||
876
79
         _PyUnicode_EqualToASCIIString(name, "__classdict__") ||
877
291
         _PyUnicode_EqualToASCIIString(name, "__conditional_annotations__"))) {
878
291
        return CELL;
879
291
    }
880
1.00k
    PySTEntryObject *ste = c->u->u_ste;
881
1.00k
    int scope = _PyST_GetScope(ste, name);
882
1.00k
    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
1.00k
    return scope;
895
1.00k
}
896
897
static int
898
dict_lookup_arg(PyObject *dict, PyObject *name)
899
1.99k
{
900
1.99k
    PyObject *v = PyDict_GetItemWithError(dict, name);
901
1.99k
    if (v == NULL) {
902
0
        return ERROR;
903
0
    }
904
1.99k
    return PyLong_AsLong(v);
905
1.99k
}
906
907
int
908
_PyCompile_LookupCellvar(compiler *c, PyObject *name)
909
904
{
910
904
    assert(c->u->u_metadata.u_cellvars);
911
904
    return dict_lookup_arg(c->u->u_metadata.u_cellvars, name);
912
904
}
913
914
int
915
_PyCompile_LookupArg(compiler *c, PyCodeObject *co, PyObject *name)
916
1.08k
{
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.08k
    int reftype = _PyCompile_GetRefType(c, name);
924
1.08k
    if (reftype == -1) {
925
0
        return ERROR;
926
0
    }
927
1.08k
    int arg;
928
1.08k
    if (reftype == CELL) {
929
1.02k
        arg = dict_lookup_arg(c->u->u_metadata.u_cellvars, name);
930
1.02k
    }
931
61
    else {
932
61
        arg = dict_lookup_arg(c->u->u_metadata.u_freevars, name);
933
61
    }
934
1.08k
    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.08k
    return arg;
951
1.08k
}
952
953
PyObject *
954
_PyCompile_StaticAttributesAsTuple(compiler *c)
955
1.27k
{
956
1.27k
    assert(c->u->u_static_attributes);
957
1.27k
    PyObject *static_attributes_unsorted = PySequence_List(c->u->u_static_attributes);
958
1.27k
    if (static_attributes_unsorted == NULL) {
959
0
        return NULL;
960
0
    }
961
1.27k
    if (PyList_Sort(static_attributes_unsorted) != 0) {
962
0
        Py_DECREF(static_attributes_unsorted);
963
0
        return NULL;
964
0
    }
965
1.27k
    PyObject *static_attributes = PySequence_Tuple(static_attributes_unsorted);
966
1.27k
    Py_DECREF(static_attributes_unsorted);
967
1.27k
    return static_attributes;
968
1.27k
}
969
970
int
971
_PyCompile_ResolveNameop(compiler *c, PyObject *mangled, int scope,
972
                          _PyCompile_optype *optype, Py_ssize_t *arg)
973
137k
{
974
137k
    PyObject *dict = c->u->u_metadata.u_names;
975
137k
    *optype = COMPILE_OP_NAME;
976
977
137k
    assert(scope >= 0);
978
137k
    switch (scope) {
979
1.65k
    case FREE:
980
1.65k
        dict = c->u->u_metadata.u_freevars;
981
1.65k
        *optype = COMPILE_OP_DEREF;
982
1.65k
        break;
983
1.15k
    case CELL:
984
1.15k
        dict = c->u->u_metadata.u_cellvars;
985
1.15k
        *optype = COMPILE_OP_DEREF;
986
1.15k
        break;
987
100k
    case LOCAL:
988
100k
        if (_PyST_IsFunctionLike(c->u->u_ste)) {
989
85.2k
            *optype = COMPILE_OP_FAST;
990
85.2k
        }
991
15.2k
        else {
992
15.2k
            PyObject *item;
993
15.2k
            RETURN_IF_ERROR(PyDict_GetItemRef(c->u->u_metadata.u_fasthidden, mangled,
994
15.2k
                                              &item));
995
15.2k
            if (item == Py_True) {
996
63
                *optype = COMPILE_OP_FAST;
997
63
            }
998
15.2k
            Py_XDECREF(item);
999
15.2k
        }
1000
100k
        break;
1001
100k
    case GLOBAL_IMPLICIT:
1002
26.2k
        if (_PyST_IsFunctionLike(c->u->u_ste)) {
1003
23.1k
            *optype = COMPILE_OP_GLOBAL;
1004
23.1k
        }
1005
26.2k
        break;
1006
181
    case GLOBAL_EXPLICIT:
1007
181
        *optype = COMPILE_OP_GLOBAL;
1008
181
        break;
1009
7.89k
    default:
1010
        /* scope can be 0 */
1011
7.89k
        break;
1012
137k
    }
1013
137k
    if (*optype != COMPILE_OP_FAST) {
1014
52.3k
        *arg = _PyCompile_DictAddObj(dict, mangled);
1015
52.3k
        RETURN_IF_ERROR(*arg);
1016
52.3k
    }
1017
137k
    return SUCCESS;
1018
137k
}
1019
1020
int
1021
_PyCompile_TweakInlinedComprehensionScopes(compiler *c, location loc,
1022
                                            PySTEntryObject *entry,
1023
                                            _PyCompile_InlinedComprehensionState *state)
1024
264
{
1025
264
    int in_class_block = (c->u->u_ste->ste_type == ClassBlock) && !c->u->u_in_inlined_comp;
1026
264
    c->u->u_in_inlined_comp++;
1027
1028
264
    PyObject *k, *v;
1029
264
    Py_ssize_t pos = 0;
1030
1.14k
    while (PyDict_Next(entry->ste_symbols, &pos, &k, &v)) {
1031
876
        long symbol = PyLong_AsLong(v);
1032
876
        assert(symbol >= 0 || PyErr_Occurred());
1033
876
        RETURN_IF_ERROR(symbol);
1034
876
        long scope = SYMBOL_TO_SCOPE(symbol);
1035
1036
876
        long outsymbol = _PyST_GetSymbol(c->u->u_ste, k);
1037
876
        RETURN_IF_ERROR(outsymbol);
1038
876
        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
876
        if ((scope != outsc && scope != FREE && !(scope == CELL && outsc == FREE))
1049
598
                || in_class_block) {
1050
278
            if (state->temp_symbols == NULL) {
1051
264
                state->temp_symbols = PyDict_New();
1052
264
                if (state->temp_symbols == NULL) {
1053
0
                    return ERROR;
1054
0
                }
1055
264
            }
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
278
            if (PyDict_SetItem(c->u->u_ste->ste_symbols, k, v) < 0) {
1060
0
                return ERROR;
1061
0
            }
1062
278
            PyObject *outv = PyLong_FromLong(outsymbol);
1063
278
            if (outv == NULL) {
1064
0
                return ERROR;
1065
0
            }
1066
278
            int res = PyDict_SetItem(state->temp_symbols, k, outv);
1067
278
            Py_DECREF(outv);
1068
278
            RETURN_IF_ERROR(res);
1069
278
        }
1070
        // locals handling for names bound in comprehension (DEF_LOCAL |
1071
        // DEF_NONLOCAL occurs in assignment expression to nonlocal)
1072
876
        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
25
                PyObject *orig;
1076
25
                if (PyDict_GetItemRef(c->u->u_metadata.u_fasthidden, k, &orig) < 0) {
1077
0
                    return ERROR;
1078
0
                }
1079
25
                assert(orig == NULL || orig == Py_True || orig == Py_False);
1080
25
                if (orig != Py_True) {
1081
25
                    if (PyDict_SetItem(c->u->u_metadata.u_fasthidden, k, Py_True) < 0) {
1082
0
                        return ERROR;
1083
0
                    }
1084
25
                    if (state->fast_hidden == NULL) {
1085
19
                        state->fast_hidden = PySet_New(NULL);
1086
19
                        if (state->fast_hidden == NULL) {
1087
0
                            return ERROR;
1088
0
                        }
1089
19
                    }
1090
25
                    if (PySet_Add(state->fast_hidden, k) < 0) {
1091
0
                        return ERROR;
1092
0
                    }
1093
25
                }
1094
25
            }
1095
348
        }
1096
876
    }
1097
264
    return SUCCESS;
1098
264
}
1099
1100
int
1101
_PyCompile_RevertInlinedComprehensionScopes(compiler *c, location loc,
1102
                                             _PyCompile_InlinedComprehensionState *state)
1103
264
{
1104
264
    c->u->u_in_inlined_comp--;
1105
264
    if (state->temp_symbols) {
1106
264
        PyObject *k, *v;
1107
264
        Py_ssize_t pos = 0;
1108
542
        while (PyDict_Next(state->temp_symbols, &pos, &k, &v)) {
1109
278
            if (PyDict_SetItem(c->u->u_ste->ste_symbols, k, v)) {
1110
0
                return ERROR;
1111
0
            }
1112
278
        }
1113
264
        Py_CLEAR(state->temp_symbols);
1114
264
    }
1115
264
    if (state->fast_hidden) {
1116
44
        while (PySet_Size(state->fast_hidden) > 0) {
1117
25
            PyObject *k = PySet_Pop(state->fast_hidden);
1118
25
            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
25
            if (PyDict_SetItem(c->u->u_metadata.u_fasthidden, k, Py_False)) {
1124
0
                Py_DECREF(k);
1125
0
                return ERROR;
1126
0
            }
1127
25
            Py_DECREF(k);
1128
25
        }
1129
19
        Py_CLEAR(state->fast_hidden);
1130
19
    }
1131
264
    return SUCCESS;
1132
264
}
1133
1134
void
1135
_PyCompile_EnterConditionalBlock(struct _PyCompiler *c)
1136
14.3k
{
1137
14.3k
    c->u->u_in_conditional_block++;
1138
14.3k
}
1139
1140
void
1141
_PyCompile_LeaveConditionalBlock(struct _PyCompiler *c)
1142
14.3k
{
1143
14.3k
    assert(c->u->u_in_conditional_block > 0);
1144
14.3k
    c->u->u_in_conditional_block--;
1145
14.3k
}
1146
1147
int
1148
_PyCompile_AddDeferredAnnotation(compiler *c, stmt_ty s,
1149
                                 PyObject **conditional_annotation_index)
1150
72
{
1151
72
    if (c->u->u_deferred_annotations == NULL) {
1152
14
        c->u->u_deferred_annotations = PyList_New(0);
1153
14
        if (c->u->u_deferred_annotations == NULL) {
1154
0
            return ERROR;
1155
0
        }
1156
14
    }
1157
72
    if (c->u->u_conditional_annotation_indices == NULL) {
1158
14
        c->u->u_conditional_annotation_indices = PyList_New(0);
1159
14
        if (c->u->u_conditional_annotation_indices == NULL) {
1160
0
            return ERROR;
1161
0
        }
1162
14
    }
1163
72
    PyObject *ptr = PyLong_FromVoidPtr((void *)s);
1164
72
    if (ptr == NULL) {
1165
0
        return ERROR;
1166
0
    }
1167
72
    if (PyList_Append(c->u->u_deferred_annotations, ptr) < 0) {
1168
0
        Py_DECREF(ptr);
1169
0
        return ERROR;
1170
0
    }
1171
72
    Py_DECREF(ptr);
1172
72
    PyObject *index;
1173
72
    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
71
    else {
1182
71
        index = PyLong_FromLong(-1);
1183
71
        if (index == NULL) {
1184
0
            return ERROR;
1185
0
        }
1186
71
    }
1187
72
    int rc = PyList_Append(c->u->u_conditional_annotation_indices, index);
1188
72
    Py_DECREF(index);
1189
72
    RETURN_IF_ERROR(rc);
1190
72
    return SUCCESS;
1191
72
}
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
72
{
1239
72
    return _Py_Mangle(c->u->u_private, name);
1240
72
}
1241
1242
PyObject *
1243
_PyCompile_MaybeMangle(compiler *c, PyObject *name)
1244
172k
{
1245
172k
    return _Py_MaybeMangle(c->u->u_private, c->u->u_ste, name);
1246
172k
}
1247
1248
instr_sequence *
1249
_PyCompile_InstrSequence(compiler *c)
1250
611k
{
1251
611k
    return c->u->u_instr_sequence;
1252
611k
}
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.63k
{
1286
3.63k
    return c->c_future.ff_features;
1287
3.63k
}
1288
1289
struct symtable *
1290
_PyCompile_Symtable(compiler *c)
1291
17.0k
{
1292
17.0k
    return c->c_st;
1293
17.0k
}
1294
1295
PySTEntryObject *
1296
_PyCompile_SymtableEntry(compiler *c)
1297
195k
{
1298
195k
    return c->u->u_ste;
1299
195k
}
1300
1301
int
1302
_PyCompile_OptimizationLevel(compiler *c)
1303
209
{
1304
209
    return c->c_optimize;
1305
209
}
1306
1307
int
1308
_PyCompile_IsInteractiveTopLevel(compiler *c)
1309
6.44k
{
1310
6.44k
    assert(c->c_stack != NULL);
1311
6.44k
    assert(PyList_CheckExact(c->c_stack));
1312
6.44k
    bool is_nested_scope = PyList_GET_SIZE(c->c_stack) > 0;
1313
6.44k
    return c->c_interactive && !is_nested_scope;
1314
6.44k
}
1315
1316
int
1317
_PyCompile_ScopeType(compiler *c)
1318
228
{
1319
228
    return c->u->u_scope_type;
1320
228
}
1321
1322
int
1323
_PyCompile_IsInInlinedComp(compiler *c)
1324
3.04k
{
1325
3.04k
    return c->u->u_in_inlined_comp;
1326
3.04k
}
1327
1328
PyObject *
1329
_PyCompile_Qualname(compiler *c)
1330
1.27k
{
1331
1.27k
    assert(c->u->u_metadata.u_qualname);
1332
1.27k
    return c->u->u_metadata.u_qualname;
1333
1.27k
}
1334
1335
_PyCompile_CodeUnitMetadata *
1336
_PyCompile_Metadata(compiler *c)
1337
121k
{
1338
121k
    return &c->u->u_metadata;
1339
121k
}
1340
1341
// Merge *obj* with constant cache, without recursion.
1342
int
1343
_PyCompile_ConstCacheMergeOne(PyObject *const_cache, PyObject **obj)
1344
54.3k
{
1345
54.3k
    PyObject *key = const_cache_insert(const_cache, *obj, false);
1346
54.3k
    if (key == NULL) {
1347
0
        return ERROR;
1348
0
    }
1349
54.3k
    if (PyTuple_CheckExact(key)) {
1350
53.5k
        PyObject *item = PyTuple_GET_ITEM(key, 1);
1351
53.5k
        Py_SETREF(*obj, Py_NewRef(item));
1352
53.5k
        Py_DECREF(key);
1353
53.5k
    }
1354
785
    else {
1355
785
        Py_SETREF(*obj, key);
1356
785
    }
1357
54.3k
    return SUCCESS;
1358
54.3k
}
1359
1360
static PyObject *
1361
consts_dict_keys_inorder(PyObject *dict)
1362
8.54k
{
1363
8.54k
    PyObject *consts, *k, *v;
1364
8.54k
    Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict);
1365
1366
8.54k
    consts = PyList_New(size);   /* PyCode_Optimize() requires a list */
1367
8.54k
    if (consts == NULL)
1368
0
        return NULL;
1369
70.3k
    while (PyDict_Next(dict, &pos, &k, &v)) {
1370
61.7k
        assert(PyLong_CheckExact(v));
1371
61.7k
        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
61.7k
        if (PyTuple_CheckExact(k)) {
1376
4.92k
            k = PyTuple_GET_ITEM(k, 1);
1377
4.92k
        }
1378
61.7k
        assert(i < size);
1379
61.7k
        assert(i >= 0);
1380
61.7k
        PyList_SET_ITEM(consts, i, Py_NewRef(k));
1381
61.7k
    }
1382
8.54k
    return consts;
1383
8.54k
}
1384
1385
static int
1386
compute_code_flags(compiler *c)
1387
8.54k
{
1388
8.54k
    PySTEntryObject *ste = c->u->u_ste;
1389
8.54k
    int flags = 0;
1390
8.54k
    if (_PyST_IsFunctionLike(ste)) {
1391
6.81k
        flags |= CO_NEWLOCALS | CO_OPTIMIZED;
1392
6.81k
        if (ste->ste_nested)
1393
676
            flags |= CO_NESTED;
1394
6.81k
        if (ste->ste_generator && !ste->ste_coroutine)
1395
435
            flags |= CO_GENERATOR;
1396
6.81k
        if (ste->ste_generator && ste->ste_coroutine)
1397
2
            flags |= CO_ASYNC_GENERATOR;
1398
6.81k
        if (ste->ste_varargs)
1399
212
            flags |= CO_VARARGS;
1400
6.81k
        if (ste->ste_varkeywords)
1401
167
            flags |= CO_VARKEYWORDS;
1402
6.81k
        if (ste->ste_has_docstring)
1403
2.16k
            flags |= CO_HAS_DOCSTRING;
1404
6.81k
        if (ste->ste_method)
1405
4.02k
            flags |= CO_METHOD;
1406
6.81k
    }
1407
1408
8.54k
    if (ste->ste_coroutine && !ste->ste_generator) {
1409
16
        flags |= CO_COROUTINE;
1410
16
    }
1411
1412
    /* (Only) inherit compilerflags in PyCF_MASK */
1413
8.54k
    flags |= (c->c_flags.cf_flags & PyCF_MASK);
1414
1415
8.54k
    return flags;
1416
8.54k
}
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.54k
{
1422
8.54k
    cfg_builder *g = NULL;
1423
8.54k
    instr_sequence optimized_instrs;
1424
8.54k
    memset(&optimized_instrs, 0, sizeof(instr_sequence));
1425
1426
8.54k
    PyCodeObject *co = NULL;
1427
8.54k
    PyObject *consts = consts_dict_keys_inorder(u->u_metadata.u_consts);
1428
8.54k
    if (consts == NULL) {
1429
0
        goto error;
1430
0
    }
1431
8.54k
    g = _PyCfg_FromInstructionSequence(u->u_instr_sequence);
1432
8.54k
    if (g == NULL) {
1433
0
        goto error;
1434
0
    }
1435
8.54k
    int nlocals = (int)PyDict_GET_SIZE(u->u_metadata.u_varnames);
1436
8.54k
    int nparams = (int)PyList_GET_SIZE(u->u_ste->ste_varnames);
1437
8.54k
    assert(u->u_metadata.u_firstlineno);
1438
1439
8.54k
    if (_PyCfg_OptimizeCodeUnit(g, consts, const_cache, nlocals,
1440
8.54k
                                nparams, u->u_metadata.u_firstlineno) < 0) {
1441
0
        goto error;
1442
0
    }
1443
1444
8.54k
    int stackdepth;
1445
8.54k
    int nlocalsplus;
1446
8.54k
    if (_PyCfg_OptimizedCfgToInstructionSequence(g, &u->u_metadata, code_flags,
1447
8.54k
                                                 &stackdepth, &nlocalsplus,
1448
8.54k
                                                 &optimized_instrs) < 0) {
1449
0
        goto error;
1450
0
    }
1451
1452
    /** Assembly **/
1453
8.54k
    co = _PyAssemble_MakeCodeObject(&u->u_metadata, const_cache, consts,
1454
8.54k
                                    stackdepth, &optimized_instrs, nlocalsplus,
1455
8.54k
                                    code_flags, filename);
1456
1457
8.54k
error:
1458
8.54k
    Py_XDECREF(consts);
1459
8.54k
    PyInstructionSequence_Fini(&optimized_instrs);
1460
8.54k
    _PyCfgBuilder_Free(g);
1461
8.54k
    return co;
1462
8.54k
}
1463
1464
1465
PyCodeObject *
1466
_PyCompile_OptimizeAndAssemble(compiler *c, int addNone)
1467
8.54k
{
1468
8.54k
    struct compiler_unit *u = c->u;
1469
8.54k
    PyObject *const_cache = c->c_const_cache;
1470
8.54k
    PyObject *filename = c->c_filename;
1471
1472
8.54k
    int code_flags = compute_code_flags(c);
1473
8.54k
    if (code_flags < 0) {
1474
0
        return NULL;
1475
0
    }
1476
1477
8.54k
    if (_PyCodegen_AddReturnAtEnd(c, addNone) < 0) {
1478
0
        return NULL;
1479
0
    }
1480
1481
8.54k
    return optimize_and_assemble_code_unit(u, const_cache, code_flags, filename);
1482
8.54k
}
1483
1484
PyCodeObject *
1485
_PyAST_Compile(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags,
1486
               int optimize, PyArena *arena, PyObject *module)
1487
454
{
1488
454
    assert(!PyErr_Occurred());
1489
454
    compiler *c = new_compiler(mod, filename, pflags, optimize, arena, module);
1490
454
    if (c == NULL) {
1491
0
        return NULL;
1492
0
    }
1493
1494
454
    PyCodeObject *co = compiler_mod(c, mod);
1495
454
    compiler_free(c);
1496
454
    assert(co || PyErr_Occurred());
1497
454
    return co;
1498
454
}
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
6.07k
{
1505
6.07k
    _PyFutureFeatures future;
1506
6.07k
    if (!_PyFuture_FromAST(mod, filename, &future)) {
1507
11
        return -1;
1508
11
    }
1509
6.06k
    int flags = future.ff_features | cf->cf_flags;
1510
6.06k
    if (optimize == -1) {
1511
6.06k
        optimize = _Py_GetConfig()->optimization_level;
1512
6.06k
    }
1513
6.06k
    if (!_PyAST_Preprocess(mod, arena, filename, optimize, flags,
1514
6.06k
                           no_const_folding, 0, module))
1515
0
    {
1516
0
        return -1;
1517
0
    }
1518
6.06k
    return 0;
1519
6.06k
}
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.77k
{
1528
2.77k
    doc = PyObject_CallMethod(doc, "expandtabs", NULL);
1529
2.77k
    if (doc == NULL) {
1530
0
        return NULL;
1531
0
    }
1532
1533
2.77k
    Py_ssize_t doc_size;
1534
2.77k
    const char *doc_utf8 = PyUnicode_AsUTF8AndSize(doc, &doc_size);
1535
2.77k
    if (doc_utf8 == NULL) {
1536
0
        Py_DECREF(doc);
1537
0
        return NULL;
1538
0
    }
1539
2.77k
    const char *p = doc_utf8;
1540
2.77k
    const char *pend = p + doc_size;
1541
1542
    // First pass: find minimum indentation of any non-blank lines
1543
    // after first line.
1544
121k
    while (p < pend && *p++ != '\n') {
1545
119k
    }
1546
1547
2.77k
    Py_ssize_t margin = PY_SSIZE_T_MAX;
1548
18.5k
    while (p < pend) {
1549
15.8k
        const char *s = p;
1550
95.5k
        while (*p == ' ') p++;
1551
15.8k
        if (p < pend && *p != '\n') {
1552
10.5k
            margin = Py_MIN(margin, p - s);
1553
10.5k
        }
1554
522k
        while (p < pend && *p++ != '\n') {
1555
506k
        }
1556
15.8k
    }
1557
2.77k
    if (margin == PY_SSIZE_T_MAX) {
1558
924
        margin = 0;
1559
924
    }
1560
1561
    // Second pass: write cleandoc into buff.
1562
1563
    // copy first line without leading spaces.
1564
2.77k
    p = doc_utf8;
1565
2.91k
    while (*p == ' ') {
1566
140
        p++;
1567
140
    }
1568
2.77k
    if (p == doc_utf8 && margin == 0 ) {
1569
        // doc is already clean.
1570
924
        return doc;
1571
924
    }
1572
1573
1.85k
    char *buff = PyMem_Malloc(doc_size);
1574
1.85k
    if (buff == NULL){
1575
0
        Py_DECREF(doc);
1576
0
        PyErr_NoMemory();
1577
0
        return NULL;
1578
0
    }
1579
1580
1.85k
    char *w = buff;
1581
1582
79.4k
    while (p < pend) {
1583
79.4k
        int ch = *w++ = *p++;
1584
79.4k
        if (ch == '\n') {
1585
1.84k
            break;
1586
1.84k
        }
1587
79.4k
    }
1588
1589
    // copy subsequent lines without margin.
1590
15.9k
    while (p < pend) {
1591
77.0k
        for (Py_ssize_t i = 0; i < margin; i++, p++) {
1592
66.1k
            if (*p != ' ') {
1593
3.15k
                assert(*p == '\n' || *p == '\0');
1594
3.15k
                break;
1595
3.15k
            }
1596
66.1k
        }
1597
470k
        while (p < pend) {
1598
469k
            int ch = *w++ = *p++;
1599
469k
            if (ch == '\n') {
1600
12.3k
                break;
1601
12.3k
            }
1602
469k
        }
1603
14.1k
    }
1604
1605
1.85k
    Py_DECREF(doc);
1606
1.85k
    PyObject *res = PyUnicode_FromStringAndSize(buff, w - buff);
1607
1.85k
    PyMem_Free(buff);
1608
1.85k
    return res;
1609
1.85k
}
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, code_flags,
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
}