Coverage Report

Created: 2026-06-09 06:31

next uncovered line (L), next uncovered region (R), next uncovered branch (B)
/src/cpython3/Python/codegen.c
Line
Count
Source
1
/*
2
 * This file implements the compiler's code generation stage, which
3
 * produces a sequence of pseudo-instructions from an AST.
4
 *
5
 * The primary entry point is _PyCodegen_Module() for modules, and
6
 * _PyCodegen_Expression() for expressions.
7
 *
8
 * CAUTION: The VISIT_* macros abort the current function when they
9
 * encounter a problem. So don't invoke them when there is memory
10
 * which needs to be released. Code blocks are OK, as the compiler
11
 * structure takes care of releasing those.  Use the arena to manage
12
 * objects.
13
 */
14
15
#include "Python.h"
16
#include "opcode.h"
17
#include "pycore_ast.h"           // _PyAST_GetDocString()
18
#define NEED_OPCODE_TABLES
19
#include "pycore_opcode_utils.h"
20
#undef NEED_OPCODE_TABLES
21
#include "pycore_c_array.h"       // _Py_c_array_t
22
#include "pycore_code.h"          // COMPARISON_LESS_THAN
23
#include "pycore_compile.h"
24
#include "pycore_instruction_sequence.h" // _PyInstructionSequence_NewLabel()
25
#include "pycore_intrinsics.h"
26
#include "pycore_long.h"          // _PyLong_GetZero()
27
#include "pycore_object.h"        // _Py_ANNOTATE_FORMAT_VALUE_WITH_FAKE_GLOBALS
28
#include "pycore_pystate.h"       // _Py_GetConfig()
29
#include "pycore_symtable.h"      // PySTEntryObject
30
#include "pycore_unicodeobject.h" // _PyUnicode_EqualToASCIIString
31
#include "pycore_ceval.h"         // SPECIAL___ENTER__
32
#include "pycore_template.h"      // _PyTemplate_Type
33
34
#define NEED_OPCODE_METADATA
35
#include "pycore_opcode_metadata.h" // _PyOpcode_opcode_metadata, _PyOpcode_num_popped/pushed
36
#undef NEED_OPCODE_METADATA
37
38
#include <stdbool.h>
39
40
522
#define COMP_GENEXP   0
41
3
#define COMP_LISTCOMP 1
42
1.11k
#define COMP_SETCOMP  2
43
342
#define COMP_DICTCOMP 3
44
45
#undef SUCCESS
46
#undef ERROR
47
6.42M
#define SUCCESS 0
48
1.03k
#define ERROR -1
49
50
#define RETURN_IF_ERROR(X)  \
51
3.47M
    do {                    \
52
3.47M
        if ((X) == -1) {    \
53
741
            return ERROR;   \
54
741
        }                   \
55
3.47M
    } while (0)
56
57
#define RETURN_IF_ERROR_IN_SCOPE(C, CALL)   \
58
69.0k
    do {                                    \
59
69.0k
        if ((CALL) < 0) {                   \
60
24
            _PyCompile_ExitScope((C));      \
61
24
            return ERROR;                   \
62
24
        }                                   \
63
69.0k
    } while (0)
64
65
struct _PyCompiler;
66
typedef struct _PyCompiler compiler;
67
68
118k
#define INSTR_SEQUENCE(C) _PyCompile_InstrSequence(C)
69
30.4k
#define FUTURE_FEATURES(C) _PyCompile_FutureFeatures(C)
70
712
#define SYMTABLE(C) _PyCompile_Symtable(C)
71
290k
#define SYMTABLE_ENTRY(C) _PyCompile_SymtableEntry(C)
72
788
#define OPTIMIZATION_LEVEL(C) _PyCompile_OptimizationLevel(C)
73
28.7k
#define IS_INTERACTIVE_TOP_LEVEL(C) _PyCompile_IsInteractiveTopLevel(C)
74
26.6k
#define SCOPE_TYPE(C) _PyCompile_ScopeType(C)
75
#define QUALNAME(C) _PyCompile_Qualname(C)
76
41.3k
#define METADATA(C) _PyCompile_Metadata(C)
77
78
typedef _PyInstruction instruction;
79
typedef _PyInstructionSequence instr_sequence;
80
typedef _Py_SourceLocation location;
81
typedef _PyJumpTargetLabel jump_target_label;
82
83
typedef _PyCompile_FBlockInfo fblockinfo;
84
85
#define LOCATION(LNO, END_LNO, COL, END_COL) \
86
26.9k
    ((const _Py_SourceLocation){(LNO), (END_LNO), (COL), (END_COL)})
87
88
837k
#define LOC(x) SRC_LOCATION_FROM_AST(x)
89
90
#define NEW_JUMP_TARGET_LABEL(C, NAME) \
91
117k
    jump_target_label NAME = _PyInstructionSequence_NewLabel(INSTR_SEQUENCE(C)); \
92
117k
    if (!IS_JUMP_TARGET_LABEL(NAME)) { \
93
0
        return ERROR; \
94
0
    }
95
96
#define USE_LABEL(C, LBL) \
97
117k
    RETURN_IF_ERROR(_PyInstructionSequence_UseLabel(INSTR_SEQUENCE(C), (LBL).id))
98
99
static const int compare_masks[] = {
100
    [Py_LT] = COMPARISON_LESS_THAN,
101
    [Py_LE] = COMPARISON_LESS_THAN | COMPARISON_EQUALS,
102
    [Py_EQ] = COMPARISON_EQUALS,
103
    [Py_NE] = COMPARISON_NOT_EQUALS,
104
    [Py_GT] = COMPARISON_GREATER_THAN,
105
    [Py_GE] = COMPARISON_GREATER_THAN | COMPARISON_EQUALS,
106
};
107
108
109
int
110
6.35k
_Py_CArray_Init(_Py_c_array_t* array, int item_size, int initial_num_entries) {
111
6.35k
    memset(array, 0, sizeof(_Py_c_array_t));
112
6.35k
    array->item_size = item_size;
113
6.35k
    array->initial_num_entries = initial_num_entries;
114
6.35k
    return 0;
115
6.35k
}
116
117
void
118
_Py_CArray_Fini(_Py_c_array_t* array)
119
6.35k
{
120
6.35k
    if (array->array) {
121
1.04k
        PyMem_Free(array->array);
122
1.04k
        array->allocated_entries = 0;
123
1.04k
    }
124
6.35k
}
125
126
int
127
_Py_CArray_EnsureCapacity(_Py_c_array_t *c_array, int idx)
128
4.66M
{
129
4.66M
    void *arr = c_array->array;
130
4.66M
    int alloc = c_array->allocated_entries;
131
4.66M
    if (arr == NULL) {
132
253k
        int new_alloc = c_array->initial_num_entries;
133
253k
        if (idx >= new_alloc) {
134
3
            new_alloc = idx + c_array->initial_num_entries;
135
3
        }
136
253k
        arr = PyMem_Calloc(new_alloc, c_array->item_size);
137
253k
        if (arr == NULL) {
138
0
            PyErr_NoMemory();
139
0
            return ERROR;
140
0
        }
141
253k
        alloc = new_alloc;
142
253k
    }
143
4.41M
    else if (idx >= alloc) {
144
29.9k
        size_t oldsize = alloc * c_array->item_size;
145
29.9k
        int new_alloc = alloc << 1;
146
29.9k
        if (idx >= new_alloc) {
147
0
            new_alloc = idx + c_array->initial_num_entries;
148
0
        }
149
29.9k
        size_t newsize = new_alloc * c_array->item_size;
150
151
29.9k
        if (oldsize > (SIZE_MAX >> 1)) {
152
0
            PyErr_NoMemory();
153
0
            return ERROR;
154
0
        }
155
156
29.9k
        assert(newsize > 0);
157
29.9k
        void *tmp = PyMem_Realloc(arr, newsize);
158
29.9k
        if (tmp == NULL) {
159
0
            PyErr_NoMemory();
160
0
            return ERROR;
161
0
        }
162
29.9k
        alloc = new_alloc;
163
29.9k
        arr = tmp;
164
29.9k
        memset((char *)arr + oldsize, 0, newsize - oldsize);
165
29.9k
    }
166
167
4.66M
    c_array->array = arr;
168
4.66M
    c_array->allocated_entries = alloc;
169
4.66M
    return SUCCESS;
170
4.66M
}
171
172
173
typedef struct {
174
    // A list of strings corresponding to name captures. It is used to track:
175
    // - Repeated name assignments in the same pattern.
176
    // - Different name assignments in alternatives.
177
    // - The order of name assignments in alternatives.
178
    PyObject *stores;
179
    // If 0, any name captures against our subject will raise.
180
    int allow_irrefutable;
181
    // An array of blocks to jump to on failure. Jumping to fail_pop[i] will pop
182
    // i items off of the stack. The end result looks like this (with each block
183
    // falling through to the next):
184
    // fail_pop[4]: POP_TOP
185
    // fail_pop[3]: POP_TOP
186
    // fail_pop[2]: POP_TOP
187
    // fail_pop[1]: POP_TOP
188
    // fail_pop[0]: NOP
189
    jump_target_label *fail_pop;
190
    // The current length of fail_pop.
191
    Py_ssize_t fail_pop_size;
192
    // The number of items on top of the stack that need to *stay* on top of the
193
    // stack. Variable captures go beneath these. All of them will be popped on
194
    // failure.
195
    Py_ssize_t on_top;
196
} pattern_context;
197
198
static int codegen_nameop(compiler *, location, identifier, expr_context_ty);
199
200
static int codegen_visit_stmt(compiler *, stmt_ty);
201
static int codegen_visit_keyword(compiler *, keyword_ty);
202
static int codegen_visit_expr(compiler *, expr_ty);
203
static int codegen_augassign(compiler *, stmt_ty);
204
static int codegen_annassign(compiler *, stmt_ty);
205
static int codegen_subscript(compiler *, expr_ty);
206
static int codegen_slice_two_parts(compiler *, expr_ty);
207
static int codegen_slice(compiler *, expr_ty);
208
209
static int codegen_body(compiler *, location, asdl_stmt_seq *, bool);
210
static int codegen_with(compiler *, stmt_ty);
211
static int codegen_async_with(compiler *, stmt_ty);
212
static int codegen_with_inner(compiler *, stmt_ty, int);
213
static int codegen_async_with_inner(compiler *, stmt_ty, int);
214
static int codegen_async_for(compiler *, stmt_ty);
215
static int codegen_call_simple_kw_helper(compiler *c,
216
                                         location loc,
217
                                         asdl_keyword_seq *keywords,
218
                                         Py_ssize_t nkwelts);
219
static int codegen_call_helper_impl(compiler *c, location loc,
220
                                    int n, /* Args already pushed */
221
                                    asdl_expr_seq *args,
222
                                    PyObject *injected_arg,
223
                                    asdl_keyword_seq *keywords);
224
static int codegen_call_helper(compiler *c, location loc,
225
                               int n, asdl_expr_seq *args,
226
                               asdl_keyword_seq *keywords);
227
static int codegen_try_except(compiler *, stmt_ty);
228
static int codegen_try_star_except(compiler *, stmt_ty);
229
230
typedef enum {
231
    ITERABLE_IN_LOCAL = 0,
232
    ITERABLE_ON_STACK = 1,
233
    ITERATOR_ON_STACK = 2,
234
} IterStackPosition;
235
236
static int codegen_sync_comprehension_generator(
237
                                      compiler *c, location loc,
238
                                      asdl_comprehension_seq *generators, int gen_index,
239
                                      int depth,
240
                                      expr_ty elt, expr_ty val, int type,
241
                                      IterStackPosition iter_pos);
242
243
static int codegen_async_comprehension_generator(
244
                                      compiler *c, location loc,
245
                                      asdl_comprehension_seq *generators, int gen_index,
246
                                      int depth,
247
                                      expr_ty elt, expr_ty val, int type,
248
                                      IterStackPosition iter_pos);
249
250
static int codegen_pattern(compiler *, pattern_ty, pattern_context *);
251
static int codegen_match(compiler *, stmt_ty);
252
static int codegen_pattern_subpattern(compiler *,
253
                                      pattern_ty, pattern_context *);
254
static int codegen_make_closure(compiler *c, location loc,
255
                                PyCodeObject *co, Py_ssize_t flags);
256
257
258
/* Add an opcode with an integer argument */
259
static int
260
codegen_addop_i(instr_sequence *seq, int opcode, Py_ssize_t oparg, location loc)
261
1.15M
{
262
    /* oparg value is unsigned, but a signed C int is usually used to store
263
       it in the C code (like Python/ceval.c).
264
265
       Limit to 32-bit signed C int (rather than INT_MAX) for portability.
266
267
       The argument of a concrete bytecode instruction is limited to 8-bit.
268
       EXTENDED_ARG is used for 16, 24, and 32-bit arguments. */
269
270
1.15M
    int oparg_ = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int);
271
1.15M
    assert(!IS_ASSEMBLER_OPCODE(opcode));
272
1.15M
    return _PyInstructionSequence_Addop(seq, opcode, oparg_, loc);
273
1.15M
}
274
275
#define ADDOP_I(C, LOC, OP, O) \
276
1.14M
    RETURN_IF_ERROR(codegen_addop_i(INSTR_SEQUENCE(C), (OP), (O), (LOC)))
277
278
#define ADDOP_I_IN_SCOPE(C, LOC, OP, O) \
279
4.72k
    RETURN_IF_ERROR_IN_SCOPE(C, codegen_addop_i(INSTR_SEQUENCE(C), (OP), (O), (LOC)))
280
281
static int
282
codegen_addop_noarg(instr_sequence *seq, int opcode, location loc)
283
357k
{
284
357k
    assert(!OPCODE_HAS_ARG(opcode));
285
357k
    assert(!IS_ASSEMBLER_OPCODE(opcode));
286
357k
    return _PyInstructionSequence_Addop(seq, opcode, 0, loc);
287
357k
}
288
289
#define ADDOP(C, LOC, OP) \
290
347k
    RETURN_IF_ERROR(codegen_addop_noarg(INSTR_SEQUENCE(C), (OP), (LOC)))
291
292
#define ADDOP_IN_SCOPE(C, LOC, OP) \
293
10.0k
    RETURN_IF_ERROR_IN_SCOPE((C), codegen_addop_noarg(INSTR_SEQUENCE(C), (OP), (LOC)))
294
295
static int
296
codegen_addop_load_const(compiler *c, location loc, PyObject *o)
297
395k
{
298
395k
    Py_ssize_t arg = _PyCompile_AddConst(c, o);
299
395k
    if (arg < 0) {
300
0
        return ERROR;
301
0
    }
302
395k
    ADDOP_I(c, loc, LOAD_CONST, arg);
303
395k
    return SUCCESS;
304
395k
}
305
306
#define ADDOP_LOAD_CONST(C, LOC, O) \
307
371k
    RETURN_IF_ERROR(codegen_addop_load_const((C), (LOC), (O)))
308
309
#define ADDOP_LOAD_CONST_IN_SCOPE(C, LOC, O) \
310
0
    RETURN_IF_ERROR_IN_SCOPE((C), codegen_addop_load_const((C), (LOC), (O)))
311
312
/* Same as ADDOP_LOAD_CONST, but steals a reference. */
313
#define ADDOP_LOAD_CONST_NEW(C, LOC, O)                                 \
314
24.4k
    do {                                                                \
315
24.4k
        PyObject *__new_const = (O);                                    \
316
24.4k
        if (__new_const == NULL) {                                      \
317
0
            return ERROR;                                               \
318
0
        }                                                               \
319
24.4k
        if (codegen_addop_load_const((C), (LOC), __new_const) < 0) {    \
320
0
            Py_DECREF(__new_const);                                     \
321
0
            return ERROR;                                               \
322
0
        }                                                               \
323
24.4k
        Py_DECREF(__new_const);                                         \
324
24.4k
    } while (0)
325
326
static int
327
codegen_addop_o(compiler *c, location loc,
328
                int opcode, PyObject *dict, PyObject *o)
329
41.3k
{
330
41.3k
    Py_ssize_t arg = _PyCompile_DictAddObj(dict, o);
331
41.3k
    RETURN_IF_ERROR(arg);
332
41.3k
    ADDOP_I(c, loc, opcode, arg);
333
41.3k
    return SUCCESS;
334
41.3k
}
335
336
#define ADDOP_N(C, LOC, OP, O, TYPE)                                    \
337
37.4k
    do {                                                                \
338
37.4k
        assert(!OPCODE_HAS_CONST(OP)); /* use ADDOP_LOAD_CONST_NEW */   \
339
37.4k
        int ret = codegen_addop_o((C), (LOC), (OP),                     \
340
37.4k
                                  METADATA(C)->u_ ## TYPE, (O));        \
341
37.4k
        Py_DECREF((O));                                                 \
342
37.4k
        RETURN_IF_ERROR(ret);                                           \
343
37.4k
    } while (0)
344
345
#define ADDOP_N_IN_SCOPE(C, LOC, OP, O, TYPE)                           \
346
3.96k
    do {                                                                \
347
3.96k
        assert(!OPCODE_HAS_CONST(OP)); /* use ADDOP_LOAD_CONST_NEW */   \
348
3.96k
        int ret = codegen_addop_o((C), (LOC), (OP),                     \
349
3.96k
                                  METADATA(C)->u_ ## TYPE, (O));        \
350
3.96k
        Py_DECREF((O));                                                 \
351
3.96k
        RETURN_IF_ERROR_IN_SCOPE((C), ret);                             \
352
3.96k
    } while (0)
353
354
10.9k
#define LOAD_METHOD -1
355
10.9k
#define LOAD_SUPER_METHOD -2
356
10.9k
#define LOAD_ZERO_SUPER_ATTR -3
357
10.9k
#define LOAD_ZERO_SUPER_METHOD -4
358
359
static int
360
codegen_addop_name_custom(compiler *c, location loc, int opcode,
361
                          PyObject *dict, PyObject *o, int shift, int low)
362
14.3k
{
363
14.3k
    PyObject *mangled = _PyCompile_MaybeMangle(c, o);
364
14.3k
    if (!mangled) {
365
0
        return ERROR;
366
0
    }
367
14.3k
    Py_ssize_t arg = _PyCompile_DictAddObj(dict, mangled);
368
14.3k
    Py_DECREF(mangled);
369
14.3k
    if (arg < 0) {
370
0
        return ERROR;
371
0
    }
372
14.3k
    ADDOP_I(c, loc, opcode, (arg << shift) | low);
373
14.3k
    return SUCCESS;
374
14.3k
}
375
376
static int
377
codegen_addop_name(compiler *c, location loc,
378
                   int opcode, PyObject *dict, PyObject *o)
379
10.9k
{
380
10.9k
    int shift = 0, low = 0;
381
10.9k
    if (opcode == LOAD_ATTR) {
382
2.78k
        shift = 1;
383
2.78k
    }
384
10.9k
    if (opcode == LOAD_METHOD) {
385
825
        opcode = LOAD_ATTR;
386
825
        shift = 1;
387
825
        low = 1;
388
825
    }
389
10.9k
    if (opcode == LOAD_SUPER_ATTR) {
390
189
        shift = 2;
391
189
        low = 2;
392
189
    }
393
10.9k
    if (opcode == LOAD_SUPER_METHOD) {
394
7
        opcode = LOAD_SUPER_ATTR;
395
7
        shift = 2;
396
7
        low = 3;
397
7
    }
398
10.9k
    if (opcode == LOAD_ZERO_SUPER_ATTR) {
399
0
        opcode = LOAD_SUPER_ATTR;
400
0
        shift = 2;
401
0
    }
402
10.9k
    if (opcode == LOAD_ZERO_SUPER_METHOD) {
403
0
        opcode = LOAD_SUPER_ATTR;
404
0
        shift = 2;
405
0
        low = 1;
406
0
    }
407
10.9k
    return codegen_addop_name_custom(c, loc, opcode, dict, o, shift, low);
408
10.9k
}
409
410
#define ADDOP_NAME(C, LOC, OP, O, TYPE) \
411
10.9k
    RETURN_IF_ERROR(codegen_addop_name((C), (LOC), (OP), METADATA(C)->u_ ## TYPE, (O)))
412
413
#define ADDOP_NAME_CUSTOM(C, LOC, OP, O, TYPE, SHIFT, LOW) \
414
3.34k
    RETURN_IF_ERROR(codegen_addop_name_custom((C), (LOC), (OP), METADATA(C)->u_ ## TYPE, (O), SHIFT, LOW))
415
416
    static int
417
codegen_addop_j(instr_sequence *seq, location loc,
418
                int opcode, jump_target_label target)
419
111k
{
420
111k
    assert(IS_JUMP_TARGET_LABEL(target));
421
111k
    assert(HAS_TARGET(opcode));
422
111k
    assert(!IS_ASSEMBLER_OPCODE(opcode));
423
111k
    return _PyInstructionSequence_Addop(seq, opcode, target.id, loc);
424
111k
}
425
426
#define ADDOP_JUMP(C, LOC, OP, O) \
427
111k
    RETURN_IF_ERROR(codegen_addop_j(INSTR_SEQUENCE(C), (LOC), (OP), (O)))
428
429
#define ADDOP_COMPARE(C, LOC, CMP) \
430
23.0k
    RETURN_IF_ERROR(codegen_addcompare((C), (LOC), (cmpop_ty)(CMP)))
431
432
#define ADDOP_BINARY(C, LOC, BINOP) \
433
236k
    RETURN_IF_ERROR(addop_binary((C), (LOC), (BINOP), false))
434
435
#define ADDOP_INPLACE(C, LOC, BINOP) \
436
1.46k
    RETURN_IF_ERROR(addop_binary((C), (LOC), (BINOP), true))
437
438
#define ADD_YIELD_FROM(C, LOC, await) \
439
15.6k
    RETURN_IF_ERROR(codegen_add_yield_from((C), (LOC), (await)))
440
441
#define POP_EXCEPT_AND_RERAISE(C, LOC) \
442
5.56k
    RETURN_IF_ERROR(codegen_pop_except_and_reraise((C), (LOC)))
443
444
#define ADDOP_YIELD(C, LOC) \
445
7
    RETURN_IF_ERROR(codegen_addop_yield((C), (LOC)))
446
447
/* VISIT and VISIT_SEQ takes an ASDL type as their second argument.  They use
448
   the ASDL name to synthesize the name of the C type and the visit function.
449
*/
450
451
#define VISIT(C, TYPE, V) \
452
758k
    RETURN_IF_ERROR(codegen_visit_ ## TYPE((C), (V)))
453
454
#define VISIT_IN_SCOPE(C, TYPE, V) \
455
6.50k
    RETURN_IF_ERROR_IN_SCOPE((C), codegen_visit_ ## TYPE((C), (V)))
456
457
#define VISIT_SEQ(C, TYPE, SEQ)                                             \
458
7.59k
    do {                                                                    \
459
7.59k
        asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */    \
460
23.1k
        for (int _i = 0; _i < asdl_seq_LEN(seq); _i++) {                    \
461
15.6k
            TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i);           \
462
15.6k
            RETURN_IF_ERROR(codegen_visit_ ## TYPE((C), elt));              \
463
15.6k
        }                                                                   \
464
7.59k
    } while (0)
465
466
#define VISIT_SEQ_IN_SCOPE(C, TYPE, SEQ)                                    \
467
    do {                                                                    \
468
        asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */    \
469
        for (int _i = 0; _i < asdl_seq_LEN(seq); _i++) {                    \
470
            TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i);           \
471
            if (codegen_visit_ ## TYPE((C), elt) < 0) {                     \
472
                _PyCompile_ExitScope(C);                                    \
473
                return ERROR;                                               \
474
            }                                                               \
475
        }                                                                   \
476
    } while (0)
477
478
static int
479
codegen_call_exit_with_nones(compiler *c, location loc)
480
6.35k
{
481
6.35k
    ADDOP_LOAD_CONST(c, loc, Py_None);
482
6.35k
    ADDOP_LOAD_CONST(c, loc, Py_None);
483
6.35k
    ADDOP_LOAD_CONST(c, loc, Py_None);
484
6.35k
    ADDOP_I(c, loc, CALL, 3);
485
6.35k
    return SUCCESS;
486
6.35k
}
487
488
static int
489
codegen_add_yield_from(compiler *c, location loc, int await)
490
15.6k
{
491
15.6k
    NEW_JUMP_TARGET_LABEL(c, send);
492
15.6k
    NEW_JUMP_TARGET_LABEL(c, fail);
493
15.6k
    NEW_JUMP_TARGET_LABEL(c, exit);
494
495
15.6k
    USE_LABEL(c, send);
496
15.6k
    ADDOP_JUMP(c, loc, SEND, exit);
497
    // Set up a virtual try/except to handle when StopIteration is raised during
498
    // a close or throw call. The only way YIELD_VALUE raises if they do!
499
15.6k
    ADDOP_JUMP(c, loc, SETUP_FINALLY, fail);
500
15.6k
    ADDOP_I(c, loc, YIELD_VALUE, 1);
501
15.6k
    ADDOP(c, NO_LOCATION, POP_BLOCK);
502
15.6k
    ADDOP_I(c, loc, RESUME, await ? RESUME_AFTER_AWAIT : RESUME_AFTER_YIELD_FROM);
503
15.6k
    ADDOP_JUMP(c, loc, JUMP_NO_INTERRUPT, send);
504
505
15.6k
    USE_LABEL(c, fail);
506
15.6k
    ADDOP(c, loc, CLEANUP_THROW);
507
508
15.6k
    USE_LABEL(c, exit);
509
15.6k
    ADDOP(c, loc, END_SEND);
510
15.6k
    return SUCCESS;
511
15.6k
}
512
513
static int
514
codegen_pop_except_and_reraise(compiler *c, location loc)
515
5.56k
{
516
    /* Stack contents
517
     * [exc_info, lasti, exc]            COPY        3
518
     * [exc_info, lasti, exc, exc_info]  POP_EXCEPT
519
     * [exc_info, lasti, exc]            RERAISE      1
520
     * (exception_unwind clears the stack)
521
     */
522
523
5.56k
    ADDOP_I(c, loc, COPY, 3);
524
5.56k
    ADDOP(c, loc, POP_EXCEPT);
525
5.56k
    ADDOP_I(c, loc, RERAISE, 1);
526
5.56k
    return SUCCESS;
527
5.56k
}
528
529
/* Unwind a frame block.  If preserve_tos is true, the TOS before
530
 * popping the blocks will be restored afterwards, unless another
531
 * return, break or continue is found. In which case, the TOS will
532
 * be popped.
533
 */
534
static int
535
codegen_unwind_fblock(compiler *c, location *ploc,
536
                      fblockinfo *info, int preserve_tos)
537
1.99k
{
538
1.99k
    switch (info->fb_type) {
539
0
        case COMPILE_FBLOCK_WHILE_LOOP:
540
0
        case COMPILE_FBLOCK_EXCEPTION_HANDLER:
541
0
        case COMPILE_FBLOCK_EXCEPTION_GROUP_HANDLER:
542
0
        case COMPILE_FBLOCK_ASYNC_COMPREHENSION_GENERATOR:
543
156
        case COMPILE_FBLOCK_STOP_ITERATION:
544
156
            return SUCCESS;
545
546
0
        case COMPILE_FBLOCK_FOR_LOOP:
547
            /* Pop the iterator */
548
0
            if (preserve_tos) {
549
0
                ADDOP_I(c, *ploc, SWAP, 3);
550
0
            }
551
0
            ADDOP(c, *ploc, POP_TOP);
552
0
            ADDOP(c, *ploc, POP_TOP);
553
0
            return SUCCESS;
554
555
0
        case COMPILE_FBLOCK_ASYNC_FOR_LOOP:
556
            /* Pop the iterator */
557
0
            if (preserve_tos) {
558
0
                ADDOP_I(c, *ploc, SWAP, 2);
559
0
            }
560
0
            ADDOP(c, *ploc, POP_TOP);
561
0
            return SUCCESS;
562
563
0
        case COMPILE_FBLOCK_TRY_EXCEPT:
564
0
            ADDOP(c, *ploc, POP_BLOCK);
565
0
            return SUCCESS;
566
567
0
        case COMPILE_FBLOCK_FINALLY_TRY:
568
            /* This POP_BLOCK gets the line number of the unwinding statement */
569
0
            ADDOP(c, *ploc, POP_BLOCK);
570
0
            if (preserve_tos) {
571
0
                RETURN_IF_ERROR(
572
0
                    _PyCompile_PushFBlock(c, *ploc, COMPILE_FBLOCK_POP_VALUE,
573
0
                                          NO_LABEL, NO_LABEL, NULL));
574
0
            }
575
            /* Emit the finally block */
576
0
            VISIT_SEQ(c, stmt, info->fb_datum);
577
0
            if (preserve_tos) {
578
0
                _PyCompile_PopFBlock(c, COMPILE_FBLOCK_POP_VALUE, NO_LABEL);
579
0
            }
580
            /* The finally block should appear to execute after the
581
             * statement causing the unwinding, so make the unwinding
582
             * instruction artificial */
583
0
            *ploc = NO_LOCATION;
584
0
            return SUCCESS;
585
586
0
        case COMPILE_FBLOCK_FINALLY_END:
587
0
            if (preserve_tos) {
588
0
                ADDOP_I(c, *ploc, SWAP, 2);
589
0
            }
590
0
            ADDOP(c, *ploc, POP_TOP); /* exc_value */
591
0
            if (preserve_tos) {
592
0
                ADDOP_I(c, *ploc, SWAP, 2);
593
0
            }
594
0
            ADDOP(c, *ploc, POP_BLOCK);
595
0
            ADDOP(c, *ploc, POP_EXCEPT);
596
0
            return SUCCESS;
597
598
2
        case COMPILE_FBLOCK_WITH:
599
1.83k
        case COMPILE_FBLOCK_ASYNC_WITH:
600
1.83k
            *ploc = info->fb_loc;
601
1.83k
            ADDOP(c, *ploc, POP_BLOCK);
602
1.83k
            if (preserve_tos) {
603
22
                ADDOP_I(c, *ploc, SWAP, 3);
604
22
                ADDOP_I(c, *ploc, SWAP, 2);
605
22
            }
606
1.83k
            RETURN_IF_ERROR(codegen_call_exit_with_nones(c, *ploc));
607
1.83k
            if (info->fb_type == COMPILE_FBLOCK_ASYNC_WITH) {
608
1.83k
                ADDOP_I(c, *ploc, GET_AWAITABLE, 2);
609
1.83k
                ADDOP(c, *ploc, PUSH_NULL);
610
1.83k
                ADDOP_LOAD_CONST(c, *ploc, Py_None);
611
1.83k
                ADD_YIELD_FROM(c, *ploc, 1);
612
1.83k
            }
613
1.83k
            ADDOP(c, *ploc, POP_TOP);
614
            /* The exit block should appear to execute after the
615
             * statement causing the unwinding, so make the unwinding
616
             * instruction artificial */
617
1.83k
            *ploc = NO_LOCATION;
618
1.83k
            return SUCCESS;
619
620
4
        case COMPILE_FBLOCK_HANDLER_CLEANUP: {
621
4
            if (info->fb_datum) {
622
0
                ADDOP(c, *ploc, POP_BLOCK);
623
0
            }
624
4
            if (preserve_tos) {
625
0
                ADDOP_I(c, *ploc, SWAP, 2);
626
0
            }
627
4
            ADDOP(c, *ploc, POP_BLOCK);
628
4
            ADDOP(c, *ploc, POP_EXCEPT);
629
4
            if (info->fb_datum) {
630
0
                ADDOP_LOAD_CONST(c, *ploc, Py_None);
631
0
                RETURN_IF_ERROR(codegen_nameop(c, *ploc, info->fb_datum, Store));
632
0
                RETURN_IF_ERROR(codegen_nameop(c, *ploc, info->fb_datum, Del));
633
0
            }
634
4
            return SUCCESS;
635
4
        }
636
0
        case COMPILE_FBLOCK_POP_VALUE: {
637
0
            if (preserve_tos) {
638
0
                ADDOP_I(c, *ploc, SWAP, 2);
639
0
            }
640
0
            ADDOP(c, *ploc, POP_TOP);
641
0
            return SUCCESS;
642
0
        }
643
1.99k
    }
644
1.99k
    Py_UNREACHABLE();
645
1.99k
}
646
647
/** Unwind block stack. If loop is not NULL, then stop when the first loop is encountered. */
648
static int
649
codegen_unwind_fblock_stack(compiler *c, location *ploc,
650
                            int preserve_tos, fblockinfo **loop)
651
2.22k
{
652
2.22k
    fblockinfo *top = _PyCompile_TopFBlock(c);
653
2.22k
    if (top == NULL) {
654
166
        return SUCCESS;
655
166
    }
656
2.05k
    if (top->fb_type == COMPILE_FBLOCK_EXCEPTION_GROUP_HANDLER) {
657
4
        return _PyCompile_Error(
658
4
            c, *ploc, "'break', 'continue' and 'return' cannot appear in an except* block");
659
4
    }
660
2.05k
    if (loop != NULL && (top->fb_type == COMPILE_FBLOCK_WHILE_LOOP ||
661
4
                         top->fb_type == COMPILE_FBLOCK_FOR_LOOP ||
662
51
                         top->fb_type == COMPILE_FBLOCK_ASYNC_FOR_LOOP)) {
663
51
        *loop = top;
664
51
        return SUCCESS;
665
51
    }
666
1.99k
    fblockinfo copy = *top;
667
1.99k
    _PyCompile_PopFBlock(c, top->fb_type, top->fb_block);
668
1.99k
    RETURN_IF_ERROR(codegen_unwind_fblock(c, ploc, &copy, preserve_tos));
669
1.99k
    RETURN_IF_ERROR(codegen_unwind_fblock_stack(c, ploc, preserve_tos, loop));
670
1.99k
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, copy.fb_loc, copy.fb_type, copy.fb_block,
671
1.99k
                          copy.fb_exit, copy.fb_datum));
672
1.99k
    return SUCCESS;
673
1.99k
}
674
675
static int
676
codegen_enter_scope(compiler *c, identifier name, int scope_type,
677
                    void *key, int lineno, PyObject *private,
678
                    _PyCompile_CodeUnitMetadata *umd)
679
21.1k
{
680
21.1k
    RETURN_IF_ERROR(
681
21.1k
        _PyCompile_EnterScope(c, name, scope_type, key, lineno, private, umd));
682
21.1k
    location loc = LOCATION(lineno, lineno, 0, 0);
683
21.1k
    if (scope_type == COMPILE_SCOPE_MODULE) {
684
4.63k
        loc.lineno = 0;
685
4.63k
    }
686
    /* Add the generator prefix instructions. */
687
688
21.1k
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
689
21.1k
    if (ste->ste_coroutine || ste->ste_generator) {
690
        /* Note that RETURN_GENERATOR + POP_TOP have a net stack effect
691
         * of 0. This is because RETURN_GENERATOR pushes the generator
692
         before returning. */
693
876
        location loc = LOCATION(lineno, lineno, -1, -1);
694
876
        ADDOP(c, loc, RETURN_GENERATOR);
695
876
        ADDOP(c, loc, POP_TOP);
696
876
    }
697
698
21.1k
    ADDOP_I(c, loc, RESUME, RESUME_AT_FUNC_START);
699
21.1k
    if (scope_type == COMPILE_SCOPE_MODULE) {
700
4.63k
        ADDOP(c, loc, ANNOTATIONS_PLACEHOLDER);
701
4.63k
    }
702
21.1k
    return SUCCESS;
703
21.1k
}
704
705
static int
706
codegen_setup_annotations_scope(compiler *c, location loc,
707
                                void *key, PyObject *name)
708
4.61k
{
709
4.61k
    _PyCompile_CodeUnitMetadata umd = {
710
4.61k
        .u_posonlyargcount = 1,
711
4.61k
    };
712
4.61k
    RETURN_IF_ERROR(
713
4.61k
        codegen_enter_scope(c, name, COMPILE_SCOPE_ANNOTATIONS,
714
4.61k
                            key, loc.lineno, NULL, &umd));
715
716
    // if .format > VALUE_WITH_FAKE_GLOBALS: raise NotImplementedError
717
4.61k
    PyObject *value_with_fake_globals = PyLong_FromLong(_Py_ANNOTATE_FORMAT_VALUE_WITH_FAKE_GLOBALS);
718
4.61k
    if (value_with_fake_globals == NULL) {
719
0
        return ERROR;
720
0
    }
721
722
4.61k
    assert(!SYMTABLE_ENTRY(c)->ste_has_docstring);
723
4.61k
    _Py_DECLARE_STR(format, ".format");
724
4.61k
    ADDOP_I(c, loc, LOAD_FAST, 0);
725
4.61k
    ADDOP_LOAD_CONST_NEW(c, loc, value_with_fake_globals);
726
4.61k
    ADDOP_I(c, loc, COMPARE_OP, (Py_GT << 5) | compare_masks[Py_GT]);
727
4.61k
    NEW_JUMP_TARGET_LABEL(c, body);
728
4.61k
    ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, body);
729
4.61k
    ADDOP_I(c, loc, LOAD_COMMON_CONSTANT, CONSTANT_NOTIMPLEMENTEDERROR);
730
4.61k
    ADDOP_I(c, loc, RAISE_VARARGS, 1);
731
4.61k
    USE_LABEL(c, body);
732
4.61k
    return SUCCESS;
733
4.61k
}
734
735
static int
736
codegen_leave_annotations_scope(compiler *c, location loc)
737
4.53k
{
738
4.53k
    ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
739
4.53k
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
740
4.53k
    if (co == NULL) {
741
0
        return ERROR;
742
0
    }
743
744
    // We want the parameter to __annotate__ to be named "format" in the
745
    // signature  shown by inspect.signature(), but we need to use a
746
    // different name (.format) in the symtable; if the name
747
    // "format" appears in the annotations, it doesn't get clobbered
748
    // by this name.  This code is essentially:
749
    // co->co_localsplusnames = ("format", *co->co_localsplusnames[1:])
750
4.53k
    const Py_ssize_t size = PyObject_Size(co->co_localsplusnames);
751
4.53k
    if (size == -1) {
752
0
        Py_DECREF(co);
753
0
        return ERROR;
754
0
    }
755
4.53k
    PyObject *new_names = PyTuple_New(size);
756
4.53k
    if (new_names == NULL) {
757
0
        Py_DECREF(co);
758
0
        return ERROR;
759
0
    }
760
4.53k
    PyTuple_SET_ITEM(new_names, 0, Py_NewRef(&_Py_ID(format)));
761
8.27k
    for (int i = 1; i < size; i++) {
762
3.74k
        PyObject *item = PyTuple_GetItem(co->co_localsplusnames, i);
763
3.74k
        if (item == NULL) {
764
0
            Py_DECREF(co);
765
0
            Py_DECREF(new_names);
766
0
            return ERROR;
767
0
        }
768
3.74k
        Py_INCREF(item);
769
3.74k
        PyTuple_SET_ITEM(new_names, i, item);
770
3.74k
    }
771
4.53k
    Py_SETREF(co->co_localsplusnames, new_names);
772
773
4.53k
    _PyCompile_ExitScope(c);
774
4.53k
    int ret = codegen_make_closure(c, loc, co, 0);
775
4.53k
    Py_DECREF(co);
776
4.53k
    RETURN_IF_ERROR(ret);
777
4.53k
    return SUCCESS;
778
4.53k
}
779
780
static int
781
codegen_deferred_annotations_body(compiler *c, location loc,
782
    PyObject *deferred_anno, PyObject *conditional_annotation_indices, int scope_type)
783
3.19k
{
784
3.19k
    Py_ssize_t annotations_len = PyList_GET_SIZE(deferred_anno);
785
786
3.19k
    assert(PyList_CheckExact(conditional_annotation_indices));
787
3.19k
    assert(annotations_len == PyList_Size(conditional_annotation_indices));
788
789
3.19k
    ADDOP_I(c, loc, BUILD_MAP, 0); // stack now contains <annos>
790
791
10.8k
    for (Py_ssize_t i = 0; i < annotations_len; i++) {
792
7.62k
        PyObject *ptr = PyList_GET_ITEM(deferred_anno, i);
793
0
        stmt_ty st = (stmt_ty)PyLong_AsVoidPtr(ptr);
794
7.62k
        if (st == NULL) {
795
0
            return ERROR;
796
0
        }
797
7.62k
        PyObject *mangled = _PyCompile_Mangle(c, st->v.AnnAssign.target->v.Name.id);
798
7.62k
        if (!mangled) {
799
0
            return ERROR;
800
0
        }
801
        // NOTE: ref of mangled can be leaked on ADDOP* and VISIT macros due to early returns
802
        // fixing would require an overhaul of these macros
803
804
7.62k
        PyObject *cond_index = PyList_GET_ITEM(conditional_annotation_indices, i);
805
7.62k
        assert(PyLong_CheckExact(cond_index));
806
7.62k
        long idx = PyLong_AS_LONG(cond_index);
807
7.62k
        NEW_JUMP_TARGET_LABEL(c, not_set);
808
809
7.62k
        if (idx != -1) {
810
1.76k
            ADDOP_LOAD_CONST(c, LOC(st), cond_index);
811
1.76k
            if (scope_type == COMPILE_SCOPE_CLASS) {
812
897
                ADDOP_NAME(
813
897
                    c, LOC(st), LOAD_DEREF, &_Py_ID(__conditional_annotations__), freevars);
814
897
            }
815
871
            else {
816
871
                ADDOP_NAME(
817
871
                    c, LOC(st), LOAD_GLOBAL, &_Py_ID(__conditional_annotations__), names);
818
871
            }
819
820
1.76k
            ADDOP_I(c, LOC(st), CONTAINS_OP, 0);
821
1.76k
            ADDOP_JUMP(c, LOC(st), POP_JUMP_IF_FALSE, not_set);
822
1.76k
        }
823
824
7.62k
        VISIT(c, expr, st->v.AnnAssign.annotation);
825
7.62k
        ADDOP_I(c, LOC(st), COPY, 2);
826
7.62k
        ADDOP_LOAD_CONST_NEW(c, LOC(st), mangled);
827
        // stack now contains <annos> <name> <annos> <value>
828
7.62k
        ADDOP(c, loc, STORE_SUBSCR);
829
        // stack now contains <annos>
830
831
7.62k
        USE_LABEL(c, not_set);
832
7.62k
    }
833
3.19k
    return SUCCESS;
834
3.19k
}
835
836
static int
837
codegen_process_deferred_annotations(compiler *c, location loc)
838
7.75k
{
839
7.75k
    PyObject *deferred_anno = NULL;
840
7.75k
    PyObject *conditional_annotation_indices = NULL;
841
7.75k
    _PyCompile_DeferredAnnotations(c, &deferred_anno, &conditional_annotation_indices);
842
7.75k
    if (deferred_anno == NULL) {
843
4.55k
        assert(conditional_annotation_indices == NULL);
844
4.55k
        return SUCCESS;
845
4.55k
    }
846
847
3.19k
    int scope_type = SCOPE_TYPE(c);
848
3.19k
    bool need_separate_block = scope_type == COMPILE_SCOPE_MODULE;
849
3.19k
    if (need_separate_block) {
850
237
        if (_PyCompile_StartAnnotationSetup(c) == ERROR) {
851
0
            goto error;
852
0
        }
853
237
    }
854
855
    // It's possible that ste_annotations_block is set but
856
    // u_deferred_annotations is not, because the former is still
857
    // set if there are only non-simple annotations (i.e., annotations
858
    // for attributes, subscripts, or parenthesized names). However, the
859
    // reverse should not be possible.
860
3.19k
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
861
3.19k
    assert(ste->ste_annotation_block != NULL);
862
3.19k
    void *key = (void *)((uintptr_t)ste->ste_id + 1);
863
3.19k
    if (codegen_setup_annotations_scope(c, loc, key,
864
3.19k
                                        ste->ste_annotation_block->ste_name) < 0) {
865
0
        goto error;
866
0
    }
867
3.19k
    if (codegen_deferred_annotations_body(c, loc, deferred_anno,
868
3.19k
                                          conditional_annotation_indices, scope_type) < 0) {
869
2
        _PyCompile_ExitScope(c);
870
2
        goto error;
871
2
    }
872
873
3.19k
    Py_DECREF(deferred_anno);
874
3.19k
    Py_DECREF(conditional_annotation_indices);
875
876
3.19k
    RETURN_IF_ERROR(codegen_leave_annotations_scope(c, loc));
877
3.19k
    RETURN_IF_ERROR(codegen_nameop(
878
3.19k
        c, loc,
879
3.19k
        ste->ste_type == ClassBlock ? &_Py_ID(__annotate_func__) : &_Py_ID(__annotate__),
880
3.19k
        Store));
881
882
3.19k
    if (need_separate_block) {
883
235
        RETURN_IF_ERROR(_PyCompile_EndAnnotationSetup(c));
884
235
    }
885
886
3.19k
    return SUCCESS;
887
2
error:
888
2
    Py_XDECREF(deferred_anno);
889
2
    Py_XDECREF(conditional_annotation_indices);
890
2
    return ERROR;
891
3.19k
}
892
893
/* Compile an expression */
894
int
895
_PyCodegen_Expression(compiler *c, expr_ty e)
896
935
{
897
935
    VISIT(c, expr, e);
898
927
    return SUCCESS;
899
935
}
900
901
/* Compile a sequence of statements, checking for a docstring
902
   and for annotations. */
903
904
int
905
_PyCodegen_Module(compiler *c, location loc, asdl_stmt_seq *stmts, bool is_interactive)
906
3.70k
{
907
3.70k
    if (SYMTABLE_ENTRY(c)->ste_has_conditional_annotations) {
908
704
        ADDOP_I(c, loc, BUILD_SET, 0);
909
704
        ADDOP_N(c, loc, STORE_NAME, &_Py_ID(__conditional_annotations__), names);
910
704
    }
911
3.70k
    return codegen_body(c, loc, stmts, is_interactive);
912
3.70k
}
913
914
int
915
codegen_body(compiler *c, location loc, asdl_stmt_seq *stmts, bool is_interactive)
916
8.62k
{
917
    /* If from __future__ import annotations is active,
918
     * every annotated class and module should have __annotations__.
919
     * Else __annotate__ is created when necessary. */
920
8.62k
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
921
8.62k
    if ((FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS) && ste->ste_annotations_used) {
922
602
        ADDOP(c, loc, SETUP_ANNOTATIONS);
923
602
    }
924
8.62k
    if (!asdl_seq_LEN(stmts)) {
925
75
        return SUCCESS;
926
75
    }
927
8.54k
    Py_ssize_t first_instr = 0;
928
8.54k
    if (!is_interactive) { /* A string literal on REPL prompt is not a docstring */
929
7.64k
        if (ste->ste_has_docstring) {
930
291
            PyObject *docstring = _PyAST_GetDocString(stmts);
931
291
            assert(docstring);
932
291
            first_instr = 1;
933
            /* set docstring */
934
291
            assert(OPTIMIZATION_LEVEL(c) < 2);
935
291
            PyObject *cleandoc = _PyCompile_CleanDoc(docstring);
936
291
            if (cleandoc == NULL) {
937
0
                return ERROR;
938
0
            }
939
291
            stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
940
291
            assert(st->kind == Expr_kind);
941
291
            location loc = LOC(st->v.Expr.value);
942
291
            ADDOP_LOAD_CONST(c, loc, cleandoc);
943
291
            Py_DECREF(cleandoc);
944
291
            RETURN_IF_ERROR(codegen_nameop(c, NO_LOCATION, &_Py_ID(__doc__), Store));
945
291
        }
946
7.64k
    }
947
49.3k
    for (Py_ssize_t i = first_instr; i < asdl_seq_LEN(stmts); i++) {
948
40.9k
        VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i));
949
40.9k
    }
950
    // If there are annotations and the future import is not on, we
951
    // collect the annotations in a separate pass and generate an
952
    // __annotate__ function. See PEP 649.
953
8.40k
    if (!(FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS)) {
954
7.75k
        RETURN_IF_ERROR(codegen_process_deferred_annotations(c, loc));
955
7.75k
    }
956
8.40k
    return SUCCESS;
957
8.40k
}
958
959
int
960
_PyCodegen_EnterAnonymousScope(compiler* c, mod_ty mod)
961
4.63k
{
962
4.63k
    _Py_DECLARE_STR(anon_module, "<module>");
963
4.63k
    RETURN_IF_ERROR(
964
4.63k
        codegen_enter_scope(c, &_Py_STR(anon_module), COMPILE_SCOPE_MODULE,
965
4.63k
                            mod, 1, NULL, NULL));
966
4.63k
    return SUCCESS;
967
4.63k
}
968
969
static int
970
codegen_make_closure(compiler *c, location loc,
971
                     PyCodeObject *co, Py_ssize_t flags)
972
16.5k
{
973
16.5k
    if (co->co_nfreevars) {
974
3.45k
        int i = PyUnstable_Code_GetFirstFree(co);
975
7.71k
        for (; i < co->co_nlocalsplus; ++i) {
976
            /* Bypass com_addop_varname because it will generate
977
               LOAD_DEREF but LOAD_CLOSURE is needed.
978
            */
979
4.25k
            PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
980
0
            int arg = _PyCompile_LookupArg(c, co, name);
981
4.25k
            RETURN_IF_ERROR(arg);
982
4.25k
            ADDOP_I(c, loc, LOAD_CLOSURE, arg);
983
4.25k
        }
984
3.45k
        flags |= MAKE_FUNCTION_CLOSURE;
985
3.45k
        ADDOP_I(c, loc, BUILD_TUPLE, co->co_nfreevars);
986
3.45k
    }
987
16.5k
    ADDOP_LOAD_CONST(c, loc, (PyObject*)co);
988
989
16.5k
    ADDOP(c, loc, MAKE_FUNCTION);
990
991
16.5k
    if (flags & MAKE_FUNCTION_CLOSURE) {
992
3.45k
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_CLOSURE);
993
3.45k
    }
994
16.5k
    if (flags & MAKE_FUNCTION_ANNOTATIONS) {
995
0
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_ANNOTATIONS);
996
0
    }
997
16.5k
    if (flags & MAKE_FUNCTION_ANNOTATE) {
998
1.32k
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_ANNOTATE);
999
1.32k
    }
1000
16.5k
    if (flags & MAKE_FUNCTION_KWDEFAULTS) {
1001
117
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_KWDEFAULTS);
1002
117
    }
1003
16.5k
    if (flags & MAKE_FUNCTION_DEFAULTS) {
1004
178
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_DEFAULTS);
1005
178
    }
1006
16.5k
    return SUCCESS;
1007
16.5k
}
1008
1009
static int
1010
codegen_decorators(compiler *c, asdl_expr_seq* decos)
1011
9.01k
{
1012
9.01k
    if (!decos) {
1013
8.93k
        return SUCCESS;
1014
8.93k
    }
1015
1016
289
    for (Py_ssize_t i = 0; i < asdl_seq_LEN(decos); i++) {
1017
211
        VISIT(c, expr, (expr_ty)asdl_seq_GET(decos, i));
1018
211
    }
1019
78
    return SUCCESS;
1020
78
}
1021
1022
static int
1023
codegen_apply_decorators(compiler *c, asdl_expr_seq* decos)
1024
8.98k
{
1025
8.98k
    if (!decos) {
1026
8.91k
        return SUCCESS;
1027
8.91k
    }
1028
1029
289
    for (Py_ssize_t i = asdl_seq_LEN(decos) - 1; i > -1; i--) {
1030
211
        location loc = LOC((expr_ty)asdl_seq_GET(decos, i));
1031
211
        ADDOP_I(c, loc, CALL, 0);
1032
211
    }
1033
78
    return SUCCESS;
1034
78
}
1035
1036
static int
1037
codegen_kwonlydefaults(compiler *c, location loc,
1038
                       asdl_arg_seq *kwonlyargs, asdl_expr_seq *kw_defaults)
1039
4.56k
{
1040
    /* Push a dict of keyword-only default values.
1041
1042
       Return -1 on error, 0 if no dict pushed, 1 if a dict is pushed.
1043
       */
1044
4.56k
    int default_count = 0;
1045
4.77k
    for (int i = 0; i < asdl_seq_LEN(kwonlyargs); i++) {
1046
205
        arg_ty arg = asdl_seq_GET(kwonlyargs, i);
1047
205
        expr_ty default_ = asdl_seq_GET(kw_defaults, i);
1048
205
        if (default_) {
1049
124
            default_count++;
1050
124
            PyObject *mangled = _PyCompile_MaybeMangle(c, arg->arg);
1051
124
            if (!mangled) {
1052
0
                return ERROR;
1053
0
            }
1054
124
            ADDOP_LOAD_CONST_NEW(c, loc, mangled);
1055
124
            VISIT(c, expr, default_);
1056
124
        }
1057
205
    }
1058
4.56k
    if (default_count) {
1059
117
        ADDOP_I(c, loc, BUILD_MAP, default_count);
1060
117
        return 1;
1061
117
    }
1062
4.45k
    else {
1063
4.45k
        return 0;
1064
4.45k
    }
1065
4.56k
}
1066
1067
static int
1068
codegen_visit_annexpr(compiler *c, expr_ty annotation)
1069
1.43k
{
1070
1.43k
    location loc = LOC(annotation);
1071
1.43k
    ADDOP_LOAD_CONST_NEW(c, loc, _PyAST_ExprAsUnicode(annotation));
1072
1.43k
    return SUCCESS;
1073
1.43k
}
1074
1075
static int
1076
codegen_argannotation(compiler *c, identifier id,
1077
    expr_ty annotation, Py_ssize_t *annotations_len, location loc)
1078
2.21k
{
1079
2.21k
    if (!annotation) {
1080
876
        return SUCCESS;
1081
876
    }
1082
1.34k
    PyObject *mangled = _PyCompile_MaybeMangle(c, id);
1083
1.34k
    if (!mangled) {
1084
0
        return ERROR;
1085
0
    }
1086
1.34k
    ADDOP_LOAD_CONST(c, loc, mangled);
1087
1.34k
    Py_DECREF(mangled);
1088
1089
1.34k
    if (FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS) {
1090
301
        VISIT(c, annexpr, annotation);
1091
301
    }
1092
1.04k
    else {
1093
1.04k
        if (annotation->kind == Starred_kind) {
1094
            // *args: *Ts (where Ts is a TypeVarTuple).
1095
            // Do [annotation_value] = [*Ts].
1096
            // (Note that in theory we could end up here even for an argument
1097
            // other than *args, but in practice the grammar doesn't allow it.)
1098
52
            VISIT(c, expr, annotation->v.Starred.value);
1099
52
            ADDOP_I(c, loc, UNPACK_SEQUENCE, (Py_ssize_t) 1);
1100
52
        }
1101
989
        else {
1102
989
            VISIT(c, expr, annotation);
1103
989
        }
1104
1.04k
    }
1105
1.34k
    *annotations_len += 1;
1106
1.34k
    return SUCCESS;
1107
1.34k
}
1108
1109
static int
1110
codegen_argannotations(compiler *c, asdl_arg_seq* args,
1111
                       Py_ssize_t *annotations_len, location loc)
1112
4.00k
{
1113
4.00k
    int i;
1114
4.49k
    for (i = 0; i < asdl_seq_LEN(args); i++) {
1115
489
        arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
1116
489
        RETURN_IF_ERROR(
1117
489
            codegen_argannotation(
1118
489
                        c,
1119
489
                        arg->arg,
1120
489
                        arg->annotation,
1121
489
                        annotations_len,
1122
489
                        loc));
1123
489
    }
1124
4.00k
    return SUCCESS;
1125
4.00k
}
1126
1127
static int
1128
codegen_annotations_in_scope(compiler *c, location loc,
1129
                             arguments_ty args, expr_ty returns,
1130
                             Py_ssize_t *annotations_len)
1131
1.33k
{
1132
1.33k
    RETURN_IF_ERROR(
1133
1.33k
        codegen_argannotations(c, args->posonlyargs, annotations_len, loc));
1134
1135
1.33k
    RETURN_IF_ERROR(
1136
1.33k
        codegen_argannotations(c, args->args, annotations_len, loc));
1137
1138
1.33k
    if (args->vararg && args->vararg->annotation) {
1139
105
        RETURN_IF_ERROR(
1140
105
            codegen_argannotation(c, args->vararg->arg,
1141
105
                                     args->vararg->annotation, annotations_len, loc));
1142
105
    }
1143
1144
1.33k
    RETURN_IF_ERROR(
1145
1.33k
        codegen_argannotations(c, args->kwonlyargs, annotations_len, loc));
1146
1147
1.33k
    if (args->kwarg && args->kwarg->annotation) {
1148
289
        RETURN_IF_ERROR(
1149
289
            codegen_argannotation(c, args->kwarg->arg,
1150
289
                                     args->kwarg->annotation, annotations_len, loc));
1151
289
    }
1152
1153
1.33k
    RETURN_IF_ERROR(
1154
1.33k
        codegen_argannotation(c, &_Py_ID(return), returns, annotations_len, loc));
1155
1156
1.33k
    return 0;
1157
1.33k
}
1158
1159
static int
1160
codegen_function_annotations(compiler *c, location loc,
1161
                             arguments_ty args, expr_ty returns)
1162
4.08k
{
1163
    /* Push arg annotation names and values.
1164
       The expressions are evaluated separately from the rest of the source code.
1165
1166
       Return -1 on error, or a combination of flags to add to the function.
1167
       */
1168
4.08k
    Py_ssize_t annotations_len = 0;
1169
1170
4.08k
    PySTEntryObject *ste;
1171
4.08k
    RETURN_IF_ERROR(_PySymtable_LookupOptional(SYMTABLE(c), args, &ste));
1172
4.08k
    assert(ste != NULL);
1173
1174
4.08k
    if (ste->ste_annotations_used) {
1175
1.33k
        int err = codegen_setup_annotations_scope(c, loc, (void *)args, ste->ste_name);
1176
1.33k
        Py_DECREF(ste);
1177
1.33k
        RETURN_IF_ERROR(err);
1178
1.33k
        RETURN_IF_ERROR_IN_SCOPE(
1179
1.33k
            c, codegen_annotations_in_scope(c, loc, args, returns, &annotations_len)
1180
1.33k
        );
1181
1.33k
        ADDOP_I(c, loc, BUILD_MAP, annotations_len);
1182
1.33k
        RETURN_IF_ERROR(codegen_leave_annotations_scope(c, loc));
1183
1.33k
        return MAKE_FUNCTION_ANNOTATE;
1184
1.33k
    }
1185
2.75k
    else {
1186
2.75k
        Py_DECREF(ste);
1187
2.75k
    }
1188
1189
2.75k
    return 0;
1190
4.08k
}
1191
1192
static int
1193
codegen_defaults(compiler *c, arguments_ty args,
1194
                        location loc)
1195
94
{
1196
94
    VISIT_SEQ(c, expr, args->defaults);
1197
94
    ADDOP_I(c, loc, BUILD_TUPLE, asdl_seq_LEN(args->defaults));
1198
94
    return SUCCESS;
1199
94
}
1200
1201
static Py_ssize_t
1202
codegen_default_arguments(compiler *c, location loc,
1203
                          arguments_ty args)
1204
4.56k
{
1205
4.56k
    Py_ssize_t funcflags = 0;
1206
4.56k
    if (args->defaults && asdl_seq_LEN(args->defaults) > 0) {
1207
94
        RETURN_IF_ERROR(codegen_defaults(c, args, loc));
1208
94
        funcflags |= MAKE_FUNCTION_DEFAULTS;
1209
94
    }
1210
4.56k
    if (args->kwonlyargs) {
1211
4.56k
        int res = codegen_kwonlydefaults(c, loc,
1212
4.56k
                                         args->kwonlyargs,
1213
4.56k
                                         args->kw_defaults);
1214
4.56k
        RETURN_IF_ERROR(res);
1215
4.56k
        if (res > 0) {
1216
117
            funcflags |= MAKE_FUNCTION_KWDEFAULTS;
1217
117
        }
1218
4.56k
    }
1219
4.56k
    return funcflags;
1220
4.56k
}
1221
1222
static int
1223
codegen_wrap_in_stopiteration_handler(compiler *c)
1224
828
{
1225
828
    NEW_JUMP_TARGET_LABEL(c, handler);
1226
1227
    /* Insert SETUP_CLEANUP just after the initial RETURN_GENERATOR; POP_TOP */
1228
828
    instr_sequence *seq = INSTR_SEQUENCE(c);
1229
828
    int resume = 0;
1230
843
    while (_PyInstructionSequence_GetInstruction(seq, resume).i_opcode != RETURN_GENERATOR) {
1231
15
        resume++;
1232
15
        assert(resume < seq->s_used);
1233
15
    }
1234
828
    resume++;
1235
828
    assert(_PyInstructionSequence_GetInstruction(seq, resume).i_opcode == POP_TOP);
1236
828
    resume++;
1237
828
    assert(resume < seq->s_used);
1238
828
    RETURN_IF_ERROR(
1239
828
        _PyInstructionSequence_InsertInstruction(
1240
828
            seq, resume,
1241
828
            SETUP_CLEANUP, handler.id, NO_LOCATION));
1242
1243
828
    ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
1244
828
    ADDOP(c, NO_LOCATION, RETURN_VALUE);
1245
828
    USE_LABEL(c, handler);
1246
828
    ADDOP_I(c, NO_LOCATION, CALL_INTRINSIC_1, INTRINSIC_STOPITERATION_ERROR);
1247
828
    ADDOP_I(c, NO_LOCATION, RERAISE, 1);
1248
828
    return SUCCESS;
1249
828
}
1250
1251
static int
1252
codegen_type_param_bound_or_default(compiler *c, expr_ty e,
1253
                                    identifier name, void *key,
1254
                                    bool allow_starred)
1255
53
{
1256
53
    PyObject *defaults = PyTuple_Pack(1, _PyLong_GetOne());
1257
53
    ADDOP_LOAD_CONST_NEW(c, LOC(e), defaults);
1258
53
    RETURN_IF_ERROR(codegen_setup_annotations_scope(c, LOC(e), key, name));
1259
53
    if (allow_starred && e->kind == Starred_kind) {
1260
0
        VISIT_IN_SCOPE(c, expr, e->v.Starred.value);
1261
0
        ADDOP_I_IN_SCOPE(c, LOC(e), UNPACK_SEQUENCE, (Py_ssize_t)1);
1262
0
    }
1263
53
    else {
1264
53
        VISIT_IN_SCOPE(c, expr, e);
1265
53
    }
1266
53
    ADDOP_IN_SCOPE(c, LOC(e), RETURN_VALUE);
1267
53
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
1268
53
    _PyCompile_ExitScope(c);
1269
53
    if (co == NULL) {
1270
0
        return ERROR;
1271
0
    }
1272
53
    int ret = codegen_make_closure(c, LOC(e), co, MAKE_FUNCTION_DEFAULTS);
1273
53
    Py_DECREF(co);
1274
53
    RETURN_IF_ERROR(ret);
1275
53
    return SUCCESS;
1276
53
}
1277
1278
static int
1279
codegen_type_params(compiler *c, asdl_type_param_seq *type_params)
1280
2.43k
{
1281
2.43k
    if (!type_params) {
1282
0
        return SUCCESS;
1283
0
    }
1284
2.43k
    Py_ssize_t n = asdl_seq_LEN(type_params);
1285
2.43k
    bool seen_default = false;
1286
1287
7.06k
    for (Py_ssize_t i = 0; i < n; i++) {
1288
4.63k
        type_param_ty typeparam = asdl_seq_GET(type_params, i);
1289
4.63k
        location loc = LOC(typeparam);
1290
4.63k
        switch(typeparam->kind) {
1291
4.63k
        case TypeVar_kind:
1292
4.63k
            ADDOP_LOAD_CONST(c, loc, typeparam->v.TypeVar.name);
1293
4.63k
            if (typeparam->v.TypeVar.bound) {
1294
49
                expr_ty bound = typeparam->v.TypeVar.bound;
1295
49
                RETURN_IF_ERROR(
1296
49
                    codegen_type_param_bound_or_default(c, bound, typeparam->v.TypeVar.name,
1297
49
                                                        (void *)typeparam, false));
1298
1299
49
                int intrinsic = bound->kind == Tuple_kind
1300
49
                    ? INTRINSIC_TYPEVAR_WITH_CONSTRAINTS
1301
49
                    : INTRINSIC_TYPEVAR_WITH_BOUND;
1302
49
                ADDOP_I(c, loc, CALL_INTRINSIC_2, intrinsic);
1303
49
            }
1304
4.58k
            else {
1305
4.58k
                ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_TYPEVAR);
1306
4.58k
            }
1307
4.63k
            if (typeparam->v.TypeVar.default_value) {
1308
4
                seen_default = true;
1309
4
                expr_ty default_ = typeparam->v.TypeVar.default_value;
1310
4
                RETURN_IF_ERROR(
1311
4
                    codegen_type_param_bound_or_default(c, default_, typeparam->v.TypeVar.name,
1312
4
                                                        (void *)((uintptr_t)typeparam + 1), false));
1313
4
                ADDOP_I(c, loc, CALL_INTRINSIC_2, INTRINSIC_SET_TYPEPARAM_DEFAULT);
1314
4
            }
1315
4.63k
            else if (seen_default) {
1316
4
                return _PyCompile_Error(c, loc, "non-default type parameter '%U' "
1317
4
                                        "follows default type parameter",
1318
4
                                        typeparam->v.TypeVar.name);
1319
4
            }
1320
4.63k
            ADDOP_I(c, loc, COPY, 1);
1321
4.63k
            RETURN_IF_ERROR(codegen_nameop(c, loc, typeparam->v.TypeVar.name, Store));
1322
4.63k
            break;
1323
4.63k
        case TypeVarTuple_kind:
1324
1
            ADDOP_LOAD_CONST(c, loc, typeparam->v.TypeVarTuple.name);
1325
1
            ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_TYPEVARTUPLE);
1326
1
            if (typeparam->v.TypeVarTuple.default_value) {
1327
0
                expr_ty default_ = typeparam->v.TypeVarTuple.default_value;
1328
0
                RETURN_IF_ERROR(
1329
0
                    codegen_type_param_bound_or_default(c, default_, typeparam->v.TypeVarTuple.name,
1330
0
                                                        (void *)typeparam, true));
1331
0
                ADDOP_I(c, loc, CALL_INTRINSIC_2, INTRINSIC_SET_TYPEPARAM_DEFAULT);
1332
0
                seen_default = true;
1333
0
            }
1334
1
            else if (seen_default) {
1335
0
                return _PyCompile_Error(c, loc, "non-default type parameter '%U' "
1336
0
                                        "follows default type parameter",
1337
0
                                        typeparam->v.TypeVarTuple.name);
1338
0
            }
1339
1
            ADDOP_I(c, loc, COPY, 1);
1340
1
            RETURN_IF_ERROR(codegen_nameop(c, loc, typeparam->v.TypeVarTuple.name, Store));
1341
1
            break;
1342
1
        case ParamSpec_kind:
1343
0
            ADDOP_LOAD_CONST(c, loc, typeparam->v.ParamSpec.name);
1344
0
            ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_PARAMSPEC);
1345
0
            if (typeparam->v.ParamSpec.default_value) {
1346
0
                expr_ty default_ = typeparam->v.ParamSpec.default_value;
1347
0
                RETURN_IF_ERROR(
1348
0
                    codegen_type_param_bound_or_default(c, default_, typeparam->v.ParamSpec.name,
1349
0
                                                        (void *)typeparam, false));
1350
0
                ADDOP_I(c, loc, CALL_INTRINSIC_2, INTRINSIC_SET_TYPEPARAM_DEFAULT);
1351
0
                seen_default = true;
1352
0
            }
1353
0
            else if (seen_default) {
1354
0
                return _PyCompile_Error(c, loc, "non-default type parameter '%U' "
1355
0
                                        "follows default type parameter",
1356
0
                                        typeparam->v.ParamSpec.name);
1357
0
            }
1358
0
            ADDOP_I(c, loc, COPY, 1);
1359
0
            RETURN_IF_ERROR(codegen_nameop(c, loc, typeparam->v.ParamSpec.name, Store));
1360
0
            break;
1361
4.63k
        }
1362
4.63k
    }
1363
2.42k
    ADDOP_I(c, LOC(asdl_seq_GET(type_params, 0)), BUILD_TUPLE, n);
1364
2.42k
    return SUCCESS;
1365
2.42k
}
1366
1367
static int
1368
codegen_function_body(compiler *c, stmt_ty s, int is_async, Py_ssize_t funcflags,
1369
                      int firstlineno)
1370
4.08k
{
1371
4.08k
    arguments_ty args;
1372
4.08k
    identifier name;
1373
4.08k
    asdl_stmt_seq *body;
1374
4.08k
    int scope_type;
1375
1376
4.08k
    if (is_async) {
1377
833
        assert(s->kind == AsyncFunctionDef_kind);
1378
1379
833
        args = s->v.AsyncFunctionDef.args;
1380
833
        name = s->v.AsyncFunctionDef.name;
1381
833
        body = s->v.AsyncFunctionDef.body;
1382
1383
833
        scope_type = COMPILE_SCOPE_ASYNC_FUNCTION;
1384
3.25k
    } else {
1385
3.25k
        assert(s->kind == FunctionDef_kind);
1386
1387
3.25k
        args = s->v.FunctionDef.args;
1388
3.25k
        name = s->v.FunctionDef.name;
1389
3.25k
        body = s->v.FunctionDef.body;
1390
1391
3.25k
        scope_type = COMPILE_SCOPE_FUNCTION;
1392
3.25k
    }
1393
1394
4.08k
    _PyCompile_CodeUnitMetadata umd = {
1395
4.08k
        .u_argcount = asdl_seq_LEN(args->args),
1396
4.08k
        .u_posonlyargcount = asdl_seq_LEN(args->posonlyargs),
1397
4.08k
        .u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs),
1398
4.08k
    };
1399
4.08k
    RETURN_IF_ERROR(
1400
4.08k
        codegen_enter_scope(c, name, scope_type, (void *)s, firstlineno, NULL, &umd));
1401
1402
4.08k
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
1403
4.08k
    Py_ssize_t first_instr = 0;
1404
4.08k
    if (ste->ste_has_docstring) {
1405
491
        PyObject *docstring = _PyAST_GetDocString(body);
1406
491
        assert(docstring);
1407
491
        first_instr = 1;
1408
491
        docstring = _PyCompile_CleanDoc(docstring);
1409
491
        if (docstring == NULL) {
1410
0
            _PyCompile_ExitScope(c);
1411
0
            return ERROR;
1412
0
        }
1413
491
        Py_ssize_t idx = _PyCompile_AddConst(c, docstring);
1414
491
        Py_DECREF(docstring);
1415
491
        RETURN_IF_ERROR_IN_SCOPE(c, idx < 0 ? ERROR : SUCCESS);
1416
491
    }
1417
1418
4.08k
    NEW_JUMP_TARGET_LABEL(c, start);
1419
4.08k
    USE_LABEL(c, start);
1420
4.08k
    bool add_stopiteration_handler = ste->ste_coroutine || ste->ste_generator;
1421
4.08k
    if (add_stopiteration_handler) {
1422
        /* codegen_wrap_in_stopiteration_handler will push a block, so we need to account for that */
1423
833
        RETURN_IF_ERROR(
1424
833
            _PyCompile_PushFBlock(c, NO_LOCATION, COMPILE_FBLOCK_STOP_ITERATION,
1425
833
                                  start, NO_LABEL, NULL));
1426
833
    }
1427
1428
10.0k
    for (Py_ssize_t i = first_instr; i < asdl_seq_LEN(body); i++) {
1429
5.93k
        VISIT_IN_SCOPE(c, stmt, (stmt_ty)asdl_seq_GET(body, i));
1430
5.93k
    }
1431
4.07k
    if (add_stopiteration_handler) {
1432
823
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_wrap_in_stopiteration_handler(c));
1433
823
        _PyCompile_PopFBlock(c, COMPILE_FBLOCK_STOP_ITERATION, start);
1434
823
    }
1435
4.07k
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
1436
4.07k
    _PyCompile_ExitScope(c);
1437
4.07k
    if (co == NULL) {
1438
0
        return ERROR;
1439
0
    }
1440
4.07k
    int ret = codegen_make_closure(c, LOC(s), co, funcflags);
1441
4.07k
    Py_DECREF(co);
1442
4.07k
    return ret;
1443
4.07k
}
1444
1445
static int
1446
codegen_function(compiler *c, stmt_ty s, int is_async)
1447
4.09k
{
1448
4.09k
    arguments_ty args;
1449
4.09k
    expr_ty returns;
1450
4.09k
    identifier name;
1451
4.09k
    asdl_expr_seq *decos;
1452
4.09k
    asdl_type_param_seq *type_params;
1453
4.09k
    Py_ssize_t funcflags;
1454
4.09k
    int firstlineno;
1455
1456
4.09k
    if (is_async) {
1457
833
        assert(s->kind == AsyncFunctionDef_kind);
1458
1459
833
        args = s->v.AsyncFunctionDef.args;
1460
833
        returns = s->v.AsyncFunctionDef.returns;
1461
833
        decos = s->v.AsyncFunctionDef.decorator_list;
1462
833
        name = s->v.AsyncFunctionDef.name;
1463
833
        type_params = s->v.AsyncFunctionDef.type_params;
1464
3.25k
    } else {
1465
3.25k
        assert(s->kind == FunctionDef_kind);
1466
1467
3.25k
        args = s->v.FunctionDef.args;
1468
3.25k
        returns = s->v.FunctionDef.returns;
1469
3.25k
        decos = s->v.FunctionDef.decorator_list;
1470
3.25k
        name = s->v.FunctionDef.name;
1471
3.25k
        type_params = s->v.FunctionDef.type_params;
1472
3.25k
    }
1473
1474
4.09k
    RETURN_IF_ERROR(codegen_decorators(c, decos));
1475
1476
4.09k
    firstlineno = s->lineno;
1477
4.09k
    if (asdl_seq_LEN(decos)) {
1478
40
        firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
1479
40
    }
1480
1481
4.09k
    location loc = LOC(s);
1482
1483
4.09k
    int is_generic = asdl_seq_LEN(type_params) > 0;
1484
1485
4.09k
    funcflags = codegen_default_arguments(c, loc, args);
1486
4.09k
    RETURN_IF_ERROR(funcflags);
1487
1488
4.09k
    int num_typeparam_args = 0;
1489
1490
4.09k
    if (is_generic) {
1491
2.29k
        if (funcflags & MAKE_FUNCTION_DEFAULTS) {
1492
0
            num_typeparam_args += 1;
1493
0
        }
1494
2.29k
        if (funcflags & MAKE_FUNCTION_KWDEFAULTS) {
1495
0
            num_typeparam_args += 1;
1496
0
        }
1497
2.29k
        if (num_typeparam_args == 2) {
1498
0
            ADDOP_I(c, loc, SWAP, 2);
1499
0
        }
1500
2.29k
        PyObject *type_params_name = PyUnicode_FromFormat("<generic parameters of %U>", name);
1501
2.29k
        if (!type_params_name) {
1502
0
            return ERROR;
1503
0
        }
1504
2.29k
        _PyCompile_CodeUnitMetadata umd = {
1505
2.29k
            .u_argcount = num_typeparam_args,
1506
2.29k
        };
1507
2.29k
        int ret = codegen_enter_scope(c, type_params_name, COMPILE_SCOPE_ANNOTATIONS,
1508
2.29k
                                      (void *)type_params, firstlineno, NULL, &umd);
1509
2.29k
        Py_DECREF(type_params_name);
1510
2.29k
        RETURN_IF_ERROR(ret);
1511
2.29k
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_type_params(c, type_params));
1512
2.29k
        for (int i = 0; i < num_typeparam_args; i++) {
1513
0
            ADDOP_I_IN_SCOPE(c, loc, LOAD_FAST, i);
1514
0
        }
1515
2.29k
    }
1516
1517
4.08k
    int annotations_flag = codegen_function_annotations(c, loc, args, returns);
1518
4.08k
    if (annotations_flag < 0) {
1519
0
        if (is_generic) {
1520
0
            _PyCompile_ExitScope(c);
1521
0
        }
1522
0
        return ERROR;
1523
0
    }
1524
4.08k
    funcflags |= annotations_flag;
1525
1526
4.08k
    int ret = codegen_function_body(c, s, is_async, funcflags, firstlineno);
1527
4.08k
    if (is_generic) {
1528
2.29k
        RETURN_IF_ERROR_IN_SCOPE(c, ret);
1529
2.29k
    }
1530
1.79k
    else {
1531
1.79k
        RETURN_IF_ERROR(ret);
1532
1.79k
    }
1533
1534
4.07k
    if (is_generic) {
1535
2.29k
        ADDOP_I_IN_SCOPE(c, loc, SWAP, 2);
1536
2.29k
        ADDOP_I_IN_SCOPE(c, loc, CALL_INTRINSIC_2, INTRINSIC_SET_FUNCTION_TYPE_PARAMS);
1537
1538
2.29k
        PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 0);
1539
2.29k
        _PyCompile_ExitScope(c);
1540
2.29k
        if (co == NULL) {
1541
0
            return ERROR;
1542
0
        }
1543
2.29k
        int ret = codegen_make_closure(c, loc, co, 0);
1544
2.29k
        Py_DECREF(co);
1545
2.29k
        RETURN_IF_ERROR(ret);
1546
2.29k
        if (num_typeparam_args > 0) {
1547
0
            ADDOP_I(c, loc, SWAP, num_typeparam_args + 1);
1548
0
            ADDOP_I(c, loc, CALL, num_typeparam_args - 1);
1549
0
        }
1550
2.29k
        else {
1551
2.29k
            ADDOP(c, loc, PUSH_NULL);
1552
2.29k
            ADDOP_I(c, loc, CALL, 0);
1553
2.29k
        }
1554
2.29k
    }
1555
1556
4.07k
    RETURN_IF_ERROR(codegen_apply_decorators(c, decos));
1557
4.07k
    return codegen_nameop(c, loc, name, Store);
1558
4.07k
}
1559
1560
static int
1561
codegen_set_type_params_in_class(compiler *c, location loc)
1562
135
{
1563
135
    _Py_DECLARE_STR(type_params, ".type_params");
1564
135
    RETURN_IF_ERROR(codegen_nameop(c, loc, &_Py_STR(type_params), Load));
1565
135
    RETURN_IF_ERROR(codegen_nameop(c, loc, &_Py_ID(__type_params__), Store));
1566
135
    return SUCCESS;
1567
135
}
1568
1569
1570
static int
1571
codegen_class_body(compiler *c, stmt_ty s, int firstlineno)
1572
4.92k
{
1573
    /* ultimately generate code for:
1574
         <name> = __build_class__(<func>, <name>, *<bases>, **<keywords>)
1575
       where:
1576
         <func> is a zero arg function/closure created from the class body.
1577
            It mutates its locals to build the class namespace.
1578
         <name> is the class name
1579
         <bases> is the positional arguments and *varargs argument
1580
         <keywords> is the keyword arguments and **kwds argument
1581
       This borrows from codegen_call.
1582
    */
1583
1584
    /* 1. compile the class body into a code object */
1585
4.92k
    RETURN_IF_ERROR(
1586
4.92k
        codegen_enter_scope(c, s->v.ClassDef.name, COMPILE_SCOPE_CLASS,
1587
4.92k
                            (void *)s, firstlineno, s->v.ClassDef.name, NULL));
1588
1589
4.92k
    location loc = LOCATION(firstlineno, firstlineno, 0, 0);
1590
    /* load (global) __name__ ... */
1591
4.92k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__name__), Load));
1592
    /* ... and store it as __module__ */
1593
4.92k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__module__), Store));
1594
4.92k
    ADDOP_LOAD_CONST(c, loc, QUALNAME(c));
1595
4.92k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__qualname__), Store));
1596
4.92k
    ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromLong(METADATA(c)->u_firstlineno));
1597
4.92k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__firstlineno__), Store));
1598
4.92k
    asdl_type_param_seq *type_params = s->v.ClassDef.type_params;
1599
4.92k
    if (asdl_seq_LEN(type_params) > 0) {
1600
135
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_set_type_params_in_class(c, loc));
1601
135
    }
1602
4.92k
    if (SYMTABLE_ENTRY(c)->ste_needs_classdict) {
1603
3.06k
        ADDOP(c, loc, LOAD_LOCALS);
1604
1605
        // We can't use codegen_nameop here because we need to generate a
1606
        // STORE_DEREF in a class namespace, and codegen_nameop() won't do
1607
        // that by default.
1608
3.06k
        ADDOP_N_IN_SCOPE(c, loc, STORE_DEREF, &_Py_ID(__classdict__), cellvars);
1609
3.06k
    }
1610
4.92k
    if (SYMTABLE_ENTRY(c)->ste_has_conditional_annotations) {
1611
903
        ADDOP_I(c, loc, BUILD_SET, 0);
1612
903
        ADDOP_N_IN_SCOPE(c, loc, STORE_DEREF, &_Py_ID(__conditional_annotations__), cellvars);
1613
903
    }
1614
    /* compile the body proper */
1615
4.92k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_body(c, loc, s->v.ClassDef.body, false));
1616
4.91k
    PyObject *static_attributes = _PyCompile_StaticAttributesAsTuple(c);
1617
4.91k
    if (static_attributes == NULL) {
1618
0
        _PyCompile_ExitScope(c);
1619
0
        return ERROR;
1620
0
    }
1621
4.91k
    ADDOP_LOAD_CONST(c, NO_LOCATION, static_attributes);
1622
4.91k
    Py_CLEAR(static_attributes);
1623
4.91k
    RETURN_IF_ERROR_IN_SCOPE(
1624
4.91k
        c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__static_attributes__), Store));
1625
    /* The following code is artificial */
1626
    /* Set __classdictcell__ if necessary */
1627
4.91k
    if (SYMTABLE_ENTRY(c)->ste_needs_classdict) {
1628
        /* Store __classdictcell__ into class namespace */
1629
3.05k
        int i = _PyCompile_LookupCellvar(c, &_Py_ID(__classdict__));
1630
3.05k
        RETURN_IF_ERROR_IN_SCOPE(c, i);
1631
3.05k
        ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
1632
3.05k
        RETURN_IF_ERROR_IN_SCOPE(
1633
3.05k
            c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__classdictcell__), Store));
1634
3.05k
    }
1635
    /* Return __classcell__ if it is referenced, otherwise return None */
1636
4.91k
    if (SYMTABLE_ENTRY(c)->ste_needs_class_closure) {
1637
        /* Store __classcell__ into class namespace & return it */
1638
0
        int i = _PyCompile_LookupCellvar(c, &_Py_ID(__class__));
1639
0
        RETURN_IF_ERROR_IN_SCOPE(c, i);
1640
0
        ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
1641
0
        ADDOP_I(c, NO_LOCATION, COPY, 1);
1642
0
        RETURN_IF_ERROR_IN_SCOPE(
1643
0
            c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__classcell__), Store));
1644
0
    }
1645
4.91k
    else {
1646
        /* No methods referenced __class__, so just return None */
1647
4.91k
        ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
1648
4.91k
    }
1649
4.91k
    ADDOP_IN_SCOPE(c, NO_LOCATION, RETURN_VALUE);
1650
    /* create the code object */
1651
4.91k
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
1652
1653
    /* leave the new scope */
1654
4.91k
    _PyCompile_ExitScope(c);
1655
4.91k
    if (co == NULL) {
1656
0
        return ERROR;
1657
0
    }
1658
1659
    /* 2. load the 'build_class' function */
1660
1661
    // these instructions should be attributed to the class line,
1662
    // not a decorator line
1663
4.91k
    loc = LOC(s);
1664
4.91k
    ADDOP(c, loc, LOAD_BUILD_CLASS);
1665
4.91k
    ADDOP(c, loc, PUSH_NULL);
1666
1667
    /* 3. load a function (or closure) made from the code object */
1668
4.91k
    int ret = codegen_make_closure(c, loc, co, 0);
1669
4.91k
    Py_DECREF(co);
1670
4.91k
    RETURN_IF_ERROR(ret);
1671
1672
    /* 4. load class name */
1673
4.91k
    ADDOP_LOAD_CONST(c, loc, s->v.ClassDef.name);
1674
1675
4.91k
    return SUCCESS;
1676
4.91k
}
1677
1678
static int
1679
codegen_class(compiler *c, stmt_ty s)
1680
4.92k
{
1681
4.92k
    asdl_expr_seq *decos = s->v.ClassDef.decorator_list;
1682
1683
4.92k
    RETURN_IF_ERROR(codegen_decorators(c, decos));
1684
1685
4.92k
    int firstlineno = s->lineno;
1686
4.92k
    if (asdl_seq_LEN(decos)) {
1687
38
        firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
1688
38
    }
1689
4.92k
    location loc = LOC(s);
1690
1691
4.92k
    asdl_type_param_seq *type_params = s->v.ClassDef.type_params;
1692
4.92k
    int is_generic = asdl_seq_LEN(type_params) > 0;
1693
4.92k
    if (is_generic) {
1694
135
        PyObject *type_params_name = PyUnicode_FromFormat("<generic parameters of %U>",
1695
135
                                                         s->v.ClassDef.name);
1696
135
        if (!type_params_name) {
1697
0
            return ERROR;
1698
0
        }
1699
135
        int ret = codegen_enter_scope(c, type_params_name, COMPILE_SCOPE_ANNOTATIONS,
1700
135
                                      (void *)type_params, firstlineno, s->v.ClassDef.name, NULL);
1701
135
        Py_DECREF(type_params_name);
1702
135
        RETURN_IF_ERROR(ret);
1703
135
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_type_params(c, type_params));
1704
135
        _Py_DECLARE_STR(type_params, ".type_params");
1705
135
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_STR(type_params), Store));
1706
135
    }
1707
1708
4.92k
    int ret = codegen_class_body(c, s, firstlineno);
1709
4.92k
    if (is_generic) {
1710
135
        RETURN_IF_ERROR_IN_SCOPE(c, ret);
1711
135
    }
1712
4.78k
    else {
1713
4.78k
        RETURN_IF_ERROR(ret);
1714
4.78k
    }
1715
1716
    /* generate the rest of the code for the call */
1717
1718
4.91k
    if (is_generic) {
1719
135
        _Py_DECLARE_STR(type_params, ".type_params");
1720
135
        _Py_DECLARE_STR(generic_base, ".generic_base");
1721
135
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_STR(type_params), Load));
1722
135
        ADDOP_I_IN_SCOPE(c, loc, CALL_INTRINSIC_1, INTRINSIC_SUBSCRIPT_GENERIC);
1723
135
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_STR(generic_base), Store));
1724
1725
135
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_call_helper_impl(c, loc, 2,
1726
135
                                                             s->v.ClassDef.bases,
1727
135
                                                             &_Py_STR(generic_base),
1728
135
                                                             s->v.ClassDef.keywords));
1729
1730
135
        PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 0);
1731
1732
135
        _PyCompile_ExitScope(c);
1733
135
        if (co == NULL) {
1734
0
            return ERROR;
1735
0
        }
1736
135
        int ret = codegen_make_closure(c, loc, co, 0);
1737
135
        Py_DECREF(co);
1738
135
        RETURN_IF_ERROR(ret);
1739
135
        ADDOP(c, loc, PUSH_NULL);
1740
135
        ADDOP_I(c, loc, CALL, 0);
1741
4.77k
    } else {
1742
4.77k
        RETURN_IF_ERROR(codegen_call_helper(c, loc, 2,
1743
4.77k
                                            s->v.ClassDef.bases,
1744
4.77k
                                            s->v.ClassDef.keywords));
1745
4.77k
    }
1746
1747
    /* 6. apply decorators */
1748
4.91k
    RETURN_IF_ERROR(codegen_apply_decorators(c, decos));
1749
1750
    /* 7. store into <name> */
1751
4.91k
    RETURN_IF_ERROR(codegen_nameop(c, loc, s->v.ClassDef.name, Store));
1752
4.91k
    return SUCCESS;
1753
4.91k
}
1754
1755
static int
1756
codegen_typealias_body(compiler *c, stmt_ty s)
1757
31
{
1758
31
    location loc = LOC(s);
1759
31
    PyObject *name = s->v.TypeAlias.name->v.Name.id;
1760
31
    PyObject *defaults = PyTuple_Pack(1, _PyLong_GetOne());
1761
31
    ADDOP_LOAD_CONST_NEW(c, loc, defaults);
1762
31
    RETURN_IF_ERROR(
1763
31
        codegen_setup_annotations_scope(c, LOC(s), s, name));
1764
1765
31
    assert(!SYMTABLE_ENTRY(c)->ste_has_docstring);
1766
31
    VISIT_IN_SCOPE(c, expr, s->v.TypeAlias.value);
1767
31
    ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
1768
31
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 0);
1769
31
    _PyCompile_ExitScope(c);
1770
31
    if (co == NULL) {
1771
0
        return ERROR;
1772
0
    }
1773
31
    int ret = codegen_make_closure(c, loc, co, MAKE_FUNCTION_DEFAULTS);
1774
31
    Py_DECREF(co);
1775
31
    RETURN_IF_ERROR(ret);
1776
1777
31
    ADDOP_I(c, loc, BUILD_TUPLE, 3);
1778
31
    ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_TYPEALIAS);
1779
31
    return SUCCESS;
1780
31
}
1781
1782
static int
1783
codegen_typealias(compiler *c, stmt_ty s)
1784
31
{
1785
31
    location loc = LOC(s);
1786
31
    asdl_type_param_seq *type_params = s->v.TypeAlias.type_params;
1787
31
    int is_generic = asdl_seq_LEN(type_params) > 0;
1788
31
    PyObject *name = s->v.TypeAlias.name->v.Name.id;
1789
31
    if (is_generic) {
1790
0
        PyObject *type_params_name = PyUnicode_FromFormat("<generic parameters of %U>",
1791
0
                                                         name);
1792
0
        if (!type_params_name) {
1793
0
            return ERROR;
1794
0
        }
1795
0
        int ret = codegen_enter_scope(c, type_params_name, COMPILE_SCOPE_ANNOTATIONS,
1796
0
                                      (void *)type_params, loc.lineno, NULL, NULL);
1797
0
        Py_DECREF(type_params_name);
1798
0
        RETURN_IF_ERROR(ret);
1799
0
        ADDOP_LOAD_CONST_IN_SCOPE(c, loc, name);
1800
0
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_type_params(c, type_params));
1801
0
    }
1802
31
    else {
1803
31
        ADDOP_LOAD_CONST(c, loc, name);
1804
31
        ADDOP_LOAD_CONST(c, loc, Py_None);
1805
31
    }
1806
1807
31
    int ret = codegen_typealias_body(c, s);
1808
31
    if (is_generic) {
1809
0
        RETURN_IF_ERROR_IN_SCOPE(c, ret);
1810
0
    }
1811
31
    else {
1812
31
        RETURN_IF_ERROR(ret);
1813
31
    }
1814
1815
31
    if (is_generic) {
1816
0
        PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 0);
1817
0
        _PyCompile_ExitScope(c);
1818
0
        if (co == NULL) {
1819
0
            return ERROR;
1820
0
        }
1821
0
        int ret = codegen_make_closure(c, loc, co, 0);
1822
0
        Py_DECREF(co);
1823
0
        RETURN_IF_ERROR(ret);
1824
0
        ADDOP(c, loc, PUSH_NULL);
1825
0
        ADDOP_I(c, loc, CALL, 0);
1826
0
    }
1827
31
    RETURN_IF_ERROR(codegen_nameop(c, loc, name, Store));
1828
31
    return SUCCESS;
1829
31
}
1830
1831
static bool
1832
is_const_tuple(asdl_expr_seq *elts)
1833
1
{
1834
1
    for (Py_ssize_t i = 0; i < asdl_seq_LEN(elts); i++) {
1835
0
        expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
1836
0
        if (e->kind != Constant_kind) {
1837
0
            return false;
1838
0
        }
1839
0
    }
1840
1
    return true;
1841
1
}
1842
1843
/* Return false if the expression is a constant value except named singletons.
1844
   Return true otherwise. */
1845
static bool
1846
check_is_arg(expr_ty e)
1847
29.9k
{
1848
29.9k
    if (e->kind == Tuple_kind) {
1849
1
        return !is_const_tuple(e->v.Tuple.elts);
1850
1
    }
1851
29.9k
    if (e->kind != Constant_kind) {
1852
24.6k
        return true;
1853
24.6k
    }
1854
5.26k
    PyObject *value = e->v.Constant.value;
1855
5.26k
    return (value == Py_None
1856
5.26k
         || value == Py_False
1857
5.26k
         || value == Py_True
1858
2.97k
         || value == Py_Ellipsis);
1859
29.9k
}
1860
1861
static PyTypeObject * infer_type(expr_ty e);
1862
1863
/* Check operands of identity checks ("is" and "is not").
1864
   Emit a warning if any operand is a constant except named singletons.
1865
 */
1866
static int
1867
codegen_check_compare(compiler *c, expr_ty e)
1868
6.94k
{
1869
6.94k
    Py_ssize_t i, n;
1870
6.94k
    bool left = check_is_arg(e->v.Compare.left);
1871
6.94k
    expr_ty left_expr = e->v.Compare.left;
1872
6.94k
    n = asdl_seq_LEN(e->v.Compare.ops);
1873
29.8k
    for (i = 0; i < n; i++) {
1874
23.0k
        cmpop_ty op = (cmpop_ty)asdl_seq_GET(e->v.Compare.ops, i);
1875
23.0k
        expr_ty right_expr = (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i);
1876
23.0k
        bool right = check_is_arg(right_expr);
1877
23.0k
        if (op == Is || op == IsNot) {
1878
751
            if (!right || !left) {
1879
87
                const char *msg = (op == Is)
1880
87
                        ? "\"is\" with '%.200s' literal. Did you mean \"==\"?"
1881
87
                        : "\"is not\" with '%.200s' literal. Did you mean \"!=\"?";
1882
87
                expr_ty literal = !left ? left_expr : right_expr;
1883
87
                return _PyCompile_Warn(
1884
87
                    c, LOC(e), msg, infer_type(literal)->tp_name
1885
87
                );
1886
87
            }
1887
751
        }
1888
22.9k
        left = right;
1889
22.9k
        left_expr = right_expr;
1890
22.9k
    }
1891
6.86k
    return SUCCESS;
1892
6.94k
}
1893
1894
static int
1895
codegen_addcompare(compiler *c, location loc, cmpop_ty op)
1896
23.0k
{
1897
23.0k
    int cmp;
1898
23.0k
    switch (op) {
1899
629
    case Eq:
1900
629
        cmp = Py_EQ;
1901
629
        break;
1902
157
    case NotEq:
1903
157
        cmp = Py_NE;
1904
157
        break;
1905
5.82k
    case Lt:
1906
5.82k
        cmp = Py_LT;
1907
5.82k
        break;
1908
375
    case LtE:
1909
375
        cmp = Py_LE;
1910
375
        break;
1911
12.7k
    case Gt:
1912
12.7k
        cmp = Py_GT;
1913
12.7k
        break;
1914
2.31k
    case GtE:
1915
2.31k
        cmp = Py_GE;
1916
2.31k
        break;
1917
759
    case Is:
1918
759
        ADDOP_I(c, loc, IS_OP, 0);
1919
759
        return SUCCESS;
1920
5
    case IsNot:
1921
5
        ADDOP_I(c, loc, IS_OP, 1);
1922
5
        return SUCCESS;
1923
203
    case In:
1924
203
        ADDOP_I(c, loc, CONTAINS_OP, 0);
1925
203
        return SUCCESS;
1926
35
    case NotIn:
1927
35
        ADDOP_I(c, loc, CONTAINS_OP, 1);
1928
35
        return SUCCESS;
1929
0
    default:
1930
0
        Py_UNREACHABLE();
1931
23.0k
    }
1932
    // cmp goes in top three bits of the oparg, while the low four bits are used
1933
    // by quickened versions of this opcode to store the comparison mask. The
1934
    // fifth-lowest bit indicates whether the result should be converted to bool
1935
    // and is set later):
1936
22.0k
    ADDOP_I(c, loc, COMPARE_OP, (cmp << 5) | compare_masks[cmp]);
1937
22.0k
    return SUCCESS;
1938
22.0k
}
1939
1940
static int
1941
codegen_jump_if(compiler *c, location loc,
1942
                expr_ty e, jump_target_label next, int cond)
1943
3.05k
{
1944
3.05k
    switch (e->kind) {
1945
131
    case UnaryOp_kind:
1946
131
        if (e->v.UnaryOp.op == Not) {
1947
0
            return codegen_jump_if(c, loc, e->v.UnaryOp.operand, next, !cond);
1948
0
        }
1949
        /* fallback to general implementation */
1950
131
        break;
1951
131
    case BoolOp_kind: {
1952
16
        asdl_expr_seq *s = e->v.BoolOp.values;
1953
16
        Py_ssize_t i, n = asdl_seq_LEN(s) - 1;
1954
16
        assert(n >= 0);
1955
16
        int cond2 = e->v.BoolOp.op == Or;
1956
16
        jump_target_label next2 = next;
1957
16
        if (!cond2 != !cond) {
1958
3
            NEW_JUMP_TARGET_LABEL(c, new_next2);
1959
3
            next2 = new_next2;
1960
3
        }
1961
58
        for (i = 0; i < n; ++i) {
1962
42
            RETURN_IF_ERROR(
1963
42
                codegen_jump_if(c, loc, (expr_ty)asdl_seq_GET(s, i), next2, cond2));
1964
42
        }
1965
16
        RETURN_IF_ERROR(
1966
16
            codegen_jump_if(c, loc, (expr_ty)asdl_seq_GET(s, n), next, cond));
1967
16
        if (!SAME_JUMP_TARGET_LABEL(next2, next)) {
1968
3
            USE_LABEL(c, next2);
1969
3
        }
1970
16
        return SUCCESS;
1971
16
    }
1972
4
    case IfExp_kind: {
1973
4
        NEW_JUMP_TARGET_LABEL(c, end);
1974
4
        NEW_JUMP_TARGET_LABEL(c, next2);
1975
4
        RETURN_IF_ERROR(
1976
4
            codegen_jump_if(c, loc, e->v.IfExp.test, next2, 0));
1977
4
        RETURN_IF_ERROR(
1978
4
            codegen_jump_if(c, loc, e->v.IfExp.body, next, cond));
1979
4
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
1980
1981
4
        USE_LABEL(c, next2);
1982
4
        RETURN_IF_ERROR(
1983
4
            codegen_jump_if(c, loc, e->v.IfExp.orelse, next, cond));
1984
1985
4
        USE_LABEL(c, end);
1986
4
        return SUCCESS;
1987
4
    }
1988
20
    case Compare_kind: {
1989
20
        Py_ssize_t n = asdl_seq_LEN(e->v.Compare.ops) - 1;
1990
20
        if (n > 0) {
1991
13
            RETURN_IF_ERROR(codegen_check_compare(c, e));
1992
13
            NEW_JUMP_TARGET_LABEL(c, cleanup);
1993
13
            VISIT(c, expr, e->v.Compare.left);
1994
41
            for (Py_ssize_t i = 0; i < n; i++) {
1995
28
                VISIT(c, expr,
1996
28
                    (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
1997
28
                ADDOP_I(c, LOC(e), SWAP, 2);
1998
28
                ADDOP_I(c, LOC(e), COPY, 2);
1999
28
                ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, i));
2000
28
                ADDOP(c, LOC(e), TO_BOOL);
2001
28
                ADDOP_JUMP(c, LOC(e), POP_JUMP_IF_FALSE, cleanup);
2002
28
            }
2003
13
            VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
2004
13
            ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, n));
2005
13
            ADDOP(c, LOC(e), TO_BOOL);
2006
13
            ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
2007
13
            NEW_JUMP_TARGET_LABEL(c, end);
2008
13
            ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2009
2010
13
            USE_LABEL(c, cleanup);
2011
13
            ADDOP(c, LOC(e), POP_TOP);
2012
13
            if (!cond) {
2013
10
                ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, next);
2014
10
            }
2015
2016
13
            USE_LABEL(c, end);
2017
13
            return SUCCESS;
2018
13
        }
2019
        /* fallback to general implementation */
2020
7
        break;
2021
20
    }
2022
2.88k
    default:
2023
        /* fallback to general implementation */
2024
2.88k
        break;
2025
3.05k
    }
2026
2027
    /* general implementation */
2028
3.01k
    VISIT(c, expr, e);
2029
3.01k
    ADDOP(c, LOC(e), TO_BOOL);
2030
3.01k
    ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
2031
3.01k
    return SUCCESS;
2032
3.01k
}
2033
2034
static int
2035
codegen_ifexp(compiler *c, expr_ty e)
2036
353
{
2037
353
    assert(e->kind == IfExp_kind);
2038
353
    NEW_JUMP_TARGET_LABEL(c, end);
2039
353
    NEW_JUMP_TARGET_LABEL(c, next);
2040
2041
353
    RETURN_IF_ERROR(
2042
353
        codegen_jump_if(c, LOC(e), e->v.IfExp.test, next, 0));
2043
2044
353
    VISIT(c, expr, e->v.IfExp.body);
2045
353
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2046
2047
353
    USE_LABEL(c, next);
2048
353
    VISIT(c, expr, e->v.IfExp.orelse);
2049
2050
346
    USE_LABEL(c, end);
2051
346
    return SUCCESS;
2052
346
}
2053
2054
static int
2055
codegen_lambda(compiler *c, expr_ty e)
2056
478
{
2057
478
    PyCodeObject *co;
2058
478
    Py_ssize_t funcflags;
2059
478
    arguments_ty args = e->v.Lambda.args;
2060
478
    assert(e->kind == Lambda_kind);
2061
2062
478
    location loc = LOC(e);
2063
478
    funcflags = codegen_default_arguments(c, loc, args);
2064
478
    RETURN_IF_ERROR(funcflags);
2065
2066
478
    _PyCompile_CodeUnitMetadata umd = {
2067
478
        .u_argcount = asdl_seq_LEN(args->args),
2068
478
        .u_posonlyargcount = asdl_seq_LEN(args->posonlyargs),
2069
478
        .u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs),
2070
478
    };
2071
478
    _Py_DECLARE_STR(anon_lambda, "<lambda>");
2072
478
    RETURN_IF_ERROR(
2073
478
        codegen_enter_scope(c, &_Py_STR(anon_lambda), COMPILE_SCOPE_LAMBDA,
2074
478
                            (void *)e, e->lineno, NULL, &umd));
2075
2076
478
    assert(!SYMTABLE_ENTRY(c)->ste_has_docstring);
2077
2078
478
    VISIT_IN_SCOPE(c, expr, e->v.Lambda.body);
2079
478
    if (SYMTABLE_ENTRY(c)->ste_generator) {
2080
0
        co = _PyCompile_OptimizeAndAssemble(c, 0);
2081
0
    }
2082
478
    else {
2083
478
        location loc = LOC(e->v.Lambda.body);
2084
478
        ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
2085
478
        co = _PyCompile_OptimizeAndAssemble(c, 1);
2086
478
    }
2087
478
    _PyCompile_ExitScope(c);
2088
478
    if (co == NULL) {
2089
0
        return ERROR;
2090
0
    }
2091
2092
478
    int ret = codegen_make_closure(c, loc, co, funcflags);
2093
478
    Py_DECREF(co);
2094
478
    RETURN_IF_ERROR(ret);
2095
478
    return SUCCESS;
2096
478
}
2097
2098
static int
2099
codegen_if(compiler *c, stmt_ty s)
2100
695
{
2101
695
    jump_target_label next;
2102
695
    assert(s->kind == If_kind);
2103
695
    NEW_JUMP_TARGET_LABEL(c, end);
2104
695
    if (asdl_seq_LEN(s->v.If.orelse)) {
2105
64
        NEW_JUMP_TARGET_LABEL(c, orelse);
2106
64
        next = orelse;
2107
64
    }
2108
631
    else {
2109
631
        next = end;
2110
631
    }
2111
695
    RETURN_IF_ERROR(
2112
695
        codegen_jump_if(c, LOC(s), s->v.If.test, next, 0));
2113
2114
695
    VISIT_SEQ(c, stmt, s->v.If.body);
2115
694
    if (asdl_seq_LEN(s->v.If.orelse)) {
2116
64
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2117
2118
64
        USE_LABEL(c, next);
2119
64
        VISIT_SEQ(c, stmt, s->v.If.orelse);
2120
64
    }
2121
2122
694
    USE_LABEL(c, end);
2123
694
    return SUCCESS;
2124
694
}
2125
2126
static int
2127
codegen_for(compiler *c, stmt_ty s)
2128
232
{
2129
232
    location loc = LOC(s);
2130
232
    NEW_JUMP_TARGET_LABEL(c, start);
2131
232
    NEW_JUMP_TARGET_LABEL(c, body);
2132
232
    NEW_JUMP_TARGET_LABEL(c, cleanup);
2133
232
    NEW_JUMP_TARGET_LABEL(c, end);
2134
2135
232
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FOR_LOOP, start, end, NULL));
2136
2137
232
    VISIT(c, expr, s->v.For.iter);
2138
2139
232
    loc = LOC(s->v.For.iter);
2140
232
    ADDOP_I(c, loc, GET_ITER, 0);
2141
2142
232
    USE_LABEL(c, start);
2143
232
    ADDOP_JUMP(c, loc, FOR_ITER, cleanup);
2144
2145
    /* Add NOP to ensure correct line tracing of multiline for statements.
2146
     * It will be removed later if redundant.
2147
     */
2148
232
    ADDOP(c, LOC(s->v.For.target), NOP);
2149
2150
232
    USE_LABEL(c, body);
2151
232
    VISIT(c, expr, s->v.For.target);
2152
232
    VISIT_SEQ(c, stmt, s->v.For.body);
2153
    /* Mark jump as artificial */
2154
231
    ADDOP_JUMP(c, NO_LOCATION, JUMP, start);
2155
2156
231
    USE_LABEL(c, cleanup);
2157
    /* It is important for instrumentation that the `END_FOR` comes first.
2158
    * Iteration over a generator will jump to the first of these instructions,
2159
    * but a non-generator will jump to the second instruction.
2160
    */
2161
231
    ADDOP(c, NO_LOCATION, END_FOR);
2162
231
    ADDOP(c, NO_LOCATION, POP_ITER);
2163
2164
231
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_FOR_LOOP, start);
2165
2166
231
    VISIT_SEQ(c, stmt, s->v.For.orelse);
2167
2168
228
    USE_LABEL(c, end);
2169
228
    return SUCCESS;
2170
228
}
2171
2172
static int
2173
codegen_async_for(compiler *c, stmt_ty s)
2174
1
{
2175
1
    location loc = LOC(s);
2176
2177
1
    NEW_JUMP_TARGET_LABEL(c, start);
2178
1
    NEW_JUMP_TARGET_LABEL(c, send);
2179
1
    NEW_JUMP_TARGET_LABEL(c, except);
2180
1
    NEW_JUMP_TARGET_LABEL(c, end);
2181
2182
1
    VISIT(c, expr, s->v.AsyncFor.iter);
2183
1
    ADDOP(c, LOC(s->v.AsyncFor.iter), GET_AITER);
2184
2185
1
    USE_LABEL(c, start);
2186
1
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_ASYNC_FOR_LOOP, start, end, NULL));
2187
2188
    /* SETUP_FINALLY to guard the __anext__ call */
2189
1
    ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
2190
1
    ADDOP(c, loc, GET_ANEXT);
2191
1
    ADDOP(c, loc, PUSH_NULL);
2192
1
    ADDOP_LOAD_CONST(c, loc, Py_None);
2193
1
    USE_LABEL(c, send);
2194
1
    ADD_YIELD_FROM(c, loc, 1);
2195
1
    ADDOP(c, loc, POP_BLOCK);  /* for SETUP_FINALLY */
2196
1
    ADDOP(c, loc, NOT_TAKEN);
2197
2198
    /* Success block for __anext__ */
2199
1
    VISIT(c, expr, s->v.AsyncFor.target);
2200
1
    VISIT_SEQ(c, stmt, s->v.AsyncFor.body);
2201
    /* Mark jump as artificial */
2202
1
    ADDOP_JUMP(c, NO_LOCATION, JUMP, start);
2203
2204
1
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_ASYNC_FOR_LOOP, start);
2205
2206
    /* Except block for __anext__ */
2207
1
    USE_LABEL(c, except);
2208
2209
    /* Use same line number as the iterator,
2210
     * as the END_ASYNC_FOR succeeds the `for`, not the body. */
2211
1
    loc = LOC(s->v.AsyncFor.iter);
2212
1
    ADDOP_JUMP(c, loc, END_ASYNC_FOR, send);
2213
2214
    /* `else` block */
2215
1
    VISIT_SEQ(c, stmt, s->v.AsyncFor.orelse);
2216
2217
1
    USE_LABEL(c, end);
2218
1
    return SUCCESS;
2219
1
}
2220
2221
static int
2222
codegen_while(compiler *c, stmt_ty s)
2223
1.13k
{
2224
1.13k
    NEW_JUMP_TARGET_LABEL(c, loop);
2225
1.13k
    NEW_JUMP_TARGET_LABEL(c, end);
2226
1.13k
    NEW_JUMP_TARGET_LABEL(c, anchor);
2227
2228
1.13k
    USE_LABEL(c, loop);
2229
2230
1.13k
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, LOC(s), COMPILE_FBLOCK_WHILE_LOOP, loop, end, NULL));
2231
1.13k
    RETURN_IF_ERROR(codegen_jump_if(c, LOC(s), s->v.While.test, anchor, 0));
2232
2233
1.13k
    VISIT_SEQ(c, stmt, s->v.While.body);
2234
1.13k
    ADDOP_JUMP(c, NO_LOCATION, JUMP, loop);
2235
2236
1.13k
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_WHILE_LOOP, loop);
2237
2238
1.13k
    USE_LABEL(c, anchor);
2239
1.13k
    if (s->v.While.orelse) {
2240
0
        VISIT_SEQ(c, stmt, s->v.While.orelse);
2241
0
    }
2242
2243
1.13k
    USE_LABEL(c, end);
2244
1.13k
    return SUCCESS;
2245
1.13k
}
2246
2247
static int
2248
codegen_return(compiler *c, stmt_ty s)
2249
172
{
2250
172
    location loc = LOC(s);
2251
172
    int preserve_tos = ((s->v.Return.value != NULL) &&
2252
16
                        (s->v.Return.value->kind != Constant_kind));
2253
2254
172
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
2255
172
    if (!_PyST_IsFunctionLike(ste)) {
2256
12
        return _PyCompile_Error(c, loc, "'return' outside function");
2257
12
    }
2258
160
    if (s->v.Return.value != NULL && ste->ste_coroutine && ste->ste_generator) {
2259
0
        return _PyCompile_Error(c, loc, "'return' with value in async generator");
2260
0
    }
2261
2262
160
    if (preserve_tos) {
2263
10
        VISIT(c, expr, s->v.Return.value);
2264
150
    } else {
2265
        /* Emit instruction with line number for return value */
2266
150
        if (s->v.Return.value != NULL) {
2267
1
            loc = LOC(s->v.Return.value);
2268
1
            ADDOP(c, loc, NOP);
2269
1
        }
2270
150
    }
2271
157
    if (s->v.Return.value == NULL || s->v.Return.value->lineno != s->lineno) {
2272
149
        loc = LOC(s);
2273
149
        ADDOP(c, loc, NOP);
2274
149
    }
2275
2276
157
    RETURN_IF_ERROR(codegen_unwind_fblock_stack(c, &loc, preserve_tos, NULL));
2277
157
    if (s->v.Return.value == NULL) {
2278
149
        ADDOP_LOAD_CONST(c, loc, Py_None);
2279
149
    }
2280
8
    else if (!preserve_tos) {
2281
1
        ADDOP_LOAD_CONST(c, loc, s->v.Return.value->v.Constant.value);
2282
1
    }
2283
157
    ADDOP(c, loc, RETURN_VALUE);
2284
2285
157
    return SUCCESS;
2286
157
}
2287
2288
static int
2289
codegen_break(compiler *c, location loc)
2290
1
{
2291
1
    fblockinfo *loop = NULL;
2292
1
    location origin_loc = loc;
2293
    /* Emit instruction with line number */
2294
1
    ADDOP(c, loc, NOP);
2295
1
    RETURN_IF_ERROR(codegen_unwind_fblock_stack(c, &loc, 0, &loop));
2296
1
    if (loop == NULL) {
2297
1
        return _PyCompile_Error(c, origin_loc, "'break' outside loop");
2298
1
    }
2299
0
    RETURN_IF_ERROR(codegen_unwind_fblock(c, &loc, loop, 0));
2300
0
    ADDOP_JUMP(c, loc, JUMP, loop->fb_exit);
2301
0
    return SUCCESS;
2302
0
}
2303
2304
static int
2305
codegen_continue(compiler *c, location loc)
2306
63
{
2307
63
    fblockinfo *loop = NULL;
2308
63
    location origin_loc = loc;
2309
    /* Emit instruction with line number */
2310
63
    ADDOP(c, loc, NOP);
2311
63
    RETURN_IF_ERROR(codegen_unwind_fblock_stack(c, &loc, 0, &loop));
2312
59
    if (loop == NULL) {
2313
8
        return _PyCompile_Error(c, origin_loc, "'continue' not properly in loop");
2314
8
    }
2315
51
    ADDOP_JUMP(c, loc, JUMP, loop->fb_block);
2316
51
    return SUCCESS;
2317
51
}
2318
2319
2320
/* Code generated for "try: <body> finally: <finalbody>" is as follows:
2321
2322
        SETUP_FINALLY           L
2323
        <code for body>
2324
        POP_BLOCK
2325
        <code for finalbody>
2326
        JUMP E
2327
    L:
2328
        <code for finalbody>
2329
    E:
2330
2331
   The special instructions use the block stack.  Each block
2332
   stack entry contains the instruction that created it (here
2333
   SETUP_FINALLY), the level of the value stack at the time the
2334
   block stack entry was created, and a label (here L).
2335
2336
   SETUP_FINALLY:
2337
    Pushes the current value stack level and the label
2338
    onto the block stack.
2339
   POP_BLOCK:
2340
    Pops en entry from the block stack.
2341
2342
   The block stack is unwound when an exception is raised:
2343
   when a SETUP_FINALLY entry is found, the raised and the caught
2344
   exceptions are pushed onto the value stack (and the exception
2345
   condition is cleared), and the interpreter jumps to the label
2346
   gotten from the block stack.
2347
*/
2348
2349
static int
2350
codegen_try_finally(compiler *c, stmt_ty s)
2351
477
{
2352
477
    location loc = LOC(s);
2353
2354
477
    NEW_JUMP_TARGET_LABEL(c, body);
2355
477
    NEW_JUMP_TARGET_LABEL(c, end);
2356
477
    NEW_JUMP_TARGET_LABEL(c, exit);
2357
477
    NEW_JUMP_TARGET_LABEL(c, cleanup);
2358
2359
    /* `try` block */
2360
477
    ADDOP_JUMP(c, loc, SETUP_FINALLY, end);
2361
2362
477
    USE_LABEL(c, body);
2363
477
    RETURN_IF_ERROR(
2364
477
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FINALLY_TRY, body, end,
2365
477
                              s->v.Try.finalbody));
2366
2367
477
    if (s->v.Try.handlers && asdl_seq_LEN(s->v.Try.handlers)) {
2368
210
        RETURN_IF_ERROR(codegen_try_except(c, s));
2369
210
    }
2370
267
    else {
2371
267
        VISIT_SEQ(c, stmt, s->v.Try.body);
2372
267
    }
2373
476
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2374
476
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_FINALLY_TRY, body);
2375
476
    VISIT_SEQ(c, stmt, s->v.Try.finalbody);
2376
2377
475
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, exit);
2378
    /* `finally` block */
2379
2380
475
    USE_LABEL(c, end);
2381
2382
475
    loc = NO_LOCATION;
2383
475
    ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
2384
475
    ADDOP(c, loc, PUSH_EXC_INFO);
2385
475
    RETURN_IF_ERROR(
2386
475
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FINALLY_END, end, NO_LABEL, NULL));
2387
475
    VISIT_SEQ(c, stmt, s->v.Try.finalbody);
2388
475
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_FINALLY_END, end);
2389
2390
475
    loc = NO_LOCATION;
2391
475
    ADDOP_I(c, loc, RERAISE, 0);
2392
2393
475
    USE_LABEL(c, cleanup);
2394
475
    POP_EXCEPT_AND_RERAISE(c, loc);
2395
2396
475
    USE_LABEL(c, exit);
2397
475
    return SUCCESS;
2398
475
}
2399
2400
static int
2401
codegen_try_star_finally(compiler *c, stmt_ty s)
2402
9
{
2403
9
    location loc = LOC(s);
2404
2405
9
    NEW_JUMP_TARGET_LABEL(c, body);
2406
9
    NEW_JUMP_TARGET_LABEL(c, end);
2407
9
    NEW_JUMP_TARGET_LABEL(c, exit);
2408
9
    NEW_JUMP_TARGET_LABEL(c, cleanup);
2409
    /* `try` block */
2410
9
    ADDOP_JUMP(c, loc, SETUP_FINALLY, end);
2411
2412
9
    USE_LABEL(c, body);
2413
9
    RETURN_IF_ERROR(
2414
9
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FINALLY_TRY, body, end,
2415
9
                              s->v.TryStar.finalbody));
2416
2417
9
    if (s->v.TryStar.handlers && asdl_seq_LEN(s->v.TryStar.handlers)) {
2418
9
        RETURN_IF_ERROR(codegen_try_star_except(c, s));
2419
9
    }
2420
0
    else {
2421
0
        VISIT_SEQ(c, stmt, s->v.TryStar.body);
2422
0
    }
2423
9
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2424
9
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_FINALLY_TRY, body);
2425
9
    VISIT_SEQ(c, stmt, s->v.TryStar.finalbody);
2426
2427
5
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, exit);
2428
2429
    /* `finally` block */
2430
5
    USE_LABEL(c, end);
2431
2432
5
    loc = NO_LOCATION;
2433
5
    ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
2434
5
    ADDOP(c, loc, PUSH_EXC_INFO);
2435
5
    RETURN_IF_ERROR(
2436
5
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FINALLY_END, end, NO_LABEL, NULL));
2437
2438
5
    VISIT_SEQ(c, stmt, s->v.TryStar.finalbody);
2439
2440
5
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_FINALLY_END, end);
2441
5
    loc = NO_LOCATION;
2442
5
    ADDOP_I(c, loc, RERAISE, 0);
2443
2444
5
    USE_LABEL(c, cleanup);
2445
5
    POP_EXCEPT_AND_RERAISE(c, loc);
2446
2447
5
    USE_LABEL(c, exit);
2448
5
    return SUCCESS;
2449
5
}
2450
2451
2452
/*
2453
   Code generated for "try: S except E1 as V1: S1 except E2 as V2: S2 ...":
2454
   (The contents of the value stack is shown in [], with the top
2455
   at the right; 'tb' is trace-back info, 'val' the exception's
2456
   associated value, and 'exc' the exception.)
2457
2458
   Value stack          Label   Instruction     Argument
2459
   []                           SETUP_FINALLY   L1
2460
   []                           <code for S>
2461
   []                           POP_BLOCK
2462
   []                           JUMP            L0
2463
2464
   [exc]                L1:     <evaluate E1>           )
2465
   [exc, E1]                    CHECK_EXC_MATCH         )
2466
   [exc, bool]                  POP_JUMP_IF_FALSE L2    ) only if E1
2467
   [exc]                        <assign to V1>  (or POP if no V1)
2468
   []                           <code for S1>
2469
                                JUMP            L0
2470
2471
   [exc]                L2:     <evaluate E2>
2472
   .............................etc.......................
2473
2474
   [exc]                Ln+1:   RERAISE     # re-raise exception
2475
2476
   []                   L0:     <next statement>
2477
2478
   Of course, parts are not generated if Vi or Ei is not present.
2479
*/
2480
static int
2481
codegen_try_except(compiler *c, stmt_ty s)
2482
324
{
2483
324
    location loc = LOC(s);
2484
324
    Py_ssize_t i, n;
2485
2486
324
    NEW_JUMP_TARGET_LABEL(c, body);
2487
324
    NEW_JUMP_TARGET_LABEL(c, except);
2488
324
    NEW_JUMP_TARGET_LABEL(c, end);
2489
324
    NEW_JUMP_TARGET_LABEL(c, cleanup);
2490
2491
324
    ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
2492
2493
324
    USE_LABEL(c, body);
2494
324
    RETURN_IF_ERROR(
2495
324
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_TRY_EXCEPT, body, NO_LABEL, NULL));
2496
324
    VISIT_SEQ(c, stmt, s->v.Try.body);
2497
323
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_TRY_EXCEPT, body);
2498
323
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2499
323
    if (s->v.Try.orelse && asdl_seq_LEN(s->v.Try.orelse)) {
2500
66
        VISIT_SEQ(c, stmt, s->v.Try.orelse);
2501
66
    }
2502
322
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2503
322
    n = asdl_seq_LEN(s->v.Try.handlers);
2504
2505
322
    USE_LABEL(c, except);
2506
2507
322
    ADDOP_JUMP(c, NO_LOCATION, SETUP_CLEANUP, cleanup);
2508
322
    ADDOP(c, NO_LOCATION, PUSH_EXC_INFO);
2509
2510
    /* Runtime will push a block here, so we need to account for that */
2511
322
    RETURN_IF_ERROR(
2512
322
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_EXCEPTION_HANDLER,
2513
322
                              NO_LABEL, NO_LABEL, NULL));
2514
2515
670
    for (i = 0; i < n; i++) {
2516
351
        excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
2517
351
            s->v.Try.handlers, i);
2518
351
        location loc = LOC(handler);
2519
351
        if (!handler->v.ExceptHandler.type && i < n-1) {
2520
1
            return _PyCompile_Error(c, loc, "default 'except:' must be last");
2521
1
        }
2522
350
        NEW_JUMP_TARGET_LABEL(c, next_except);
2523
350
        except = next_except;
2524
350
        if (handler->v.ExceptHandler.type) {
2525
39
            VISIT(c, expr, handler->v.ExceptHandler.type);
2526
39
            ADDOP(c, loc, CHECK_EXC_MATCH);
2527
39
            ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, except);
2528
39
        }
2529
350
        if (handler->v.ExceptHandler.name) {
2530
0
            NEW_JUMP_TARGET_LABEL(c, cleanup_end);
2531
0
            NEW_JUMP_TARGET_LABEL(c, cleanup_body);
2532
2533
0
            RETURN_IF_ERROR(
2534
0
                codegen_nameop(c, loc, handler->v.ExceptHandler.name, Store));
2535
2536
            /*
2537
              try:
2538
                  # body
2539
              except type as name:
2540
                  try:
2541
                      # body
2542
                  finally:
2543
                      name = None # in case body contains "del name"
2544
                      del name
2545
            */
2546
2547
            /* second try: */
2548
0
            ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup_end);
2549
2550
0
            USE_LABEL(c, cleanup_body);
2551
0
            RETURN_IF_ERROR(
2552
0
                _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body,
2553
0
                                      NO_LABEL, handler->v.ExceptHandler.name));
2554
2555
            /* second # body */
2556
0
            VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
2557
0
            _PyCompile_PopFBlock(c, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body);
2558
            /* name = None; del name; # Mark as artificial */
2559
0
            ADDOP(c, NO_LOCATION, POP_BLOCK);
2560
0
            ADDOP(c, NO_LOCATION, POP_BLOCK);
2561
0
            ADDOP(c, NO_LOCATION, POP_EXCEPT);
2562
0
            ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
2563
0
            RETURN_IF_ERROR(
2564
0
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
2565
0
            RETURN_IF_ERROR(
2566
0
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
2567
0
            ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2568
2569
            /* except: */
2570
0
            USE_LABEL(c, cleanup_end);
2571
2572
            /* name = None; del name; # artificial */
2573
0
            ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
2574
0
            RETURN_IF_ERROR(
2575
0
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
2576
0
            RETURN_IF_ERROR(
2577
0
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
2578
2579
0
            ADDOP_I(c, NO_LOCATION, RERAISE, 1);
2580
0
        }
2581
350
        else {
2582
350
            NEW_JUMP_TARGET_LABEL(c, cleanup_body);
2583
2584
350
            ADDOP(c, loc, POP_TOP); /* exc_value */
2585
2586
350
            USE_LABEL(c, cleanup_body);
2587
350
            RETURN_IF_ERROR(
2588
350
                _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body,
2589
350
                                      NO_LABEL, NULL));
2590
2591
350
            VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
2592
348
            _PyCompile_PopFBlock(c, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body);
2593
348
            ADDOP(c, NO_LOCATION, POP_BLOCK);
2594
348
            ADDOP(c, NO_LOCATION, POP_EXCEPT);
2595
348
            ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2596
348
        }
2597
2598
348
        USE_LABEL(c, except);
2599
348
    }
2600
    /* artificial */
2601
319
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_EXCEPTION_HANDLER, NO_LABEL);
2602
319
    ADDOP_I(c, NO_LOCATION, RERAISE, 0);
2603
2604
319
    USE_LABEL(c, cleanup);
2605
319
    POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
2606
2607
319
    USE_LABEL(c, end);
2608
319
    return SUCCESS;
2609
319
}
2610
2611
/*
2612
   Code generated for "try: S except* E1 as V1: S1 except* E2 as V2: S2 ...":
2613
   (The contents of the value stack is shown in [], with the top
2614
   at the right; 'tb' is trace-back info, 'val' the exception instance,
2615
   and 'typ' the exception's type.)
2616
2617
   Value stack                   Label         Instruction     Argument
2618
   []                                         SETUP_FINALLY         L1
2619
   []                                         <code for S>
2620
   []                                         POP_BLOCK
2621
   []                                         JUMP                  L0
2622
2623
   [exc]                            L1:       BUILD_LIST   )  list for raised/reraised excs ("result")
2624
   [orig, res]                                COPY 2       )  make a copy of the original EG
2625
2626
   [orig, res, exc]                           <evaluate E1>
2627
   [orig, res, exc, E1]                       CHECK_EG_MATCH
2628
   [orig, res, rest/exc, match?]              COPY 1
2629
   [orig, res, rest/exc, match?, match?]      POP_JUMP_IF_NONE      C1
2630
2631
   [orig, res, rest, match]                   <assign to V1>  (or POP if no V1)
2632
2633
   [orig, res, rest]                          SETUP_FINALLY         R1
2634
   [orig, res, rest]                          <code for S1>
2635
   [orig, res, rest]                          JUMP                  L2
2636
2637
   [orig, res, rest, i, v]          R1:       LIST_APPEND   3 ) exc raised in except* body - add to res
2638
   [orig, res, rest, i]                       POP
2639
   [orig, res, rest]                          JUMP                  LE2
2640
2641
   [orig, res, rest]                L2:       NOP  ) for lineno
2642
   [orig, res, rest]                          JUMP                  LE2
2643
2644
   [orig, res, rest/exc, None]      C1:       POP
2645
2646
   [orig, res, rest]               LE2:       <evaluate E2>
2647
   .............................etc.......................
2648
2649
   [orig, res, rest]                Ln+1:     LIST_APPEND 1  ) add unhandled exc to res (could be None)
2650
2651
   [orig, res]                                CALL_INTRINSIC_2 PREP_RERAISE_STAR
2652
   [exc]                                      COPY 1
2653
   [exc, exc]                                 POP_JUMP_IF_NOT_NONE  RER
2654
   [exc]                                      POP_TOP
2655
   []                                         JUMP                  L0
2656
2657
   [exc]                            RER:      SWAP 2
2658
   [exc, prev_exc_info]                       POP_EXCEPT
2659
   [exc]                                      RERAISE               0
2660
2661
   []                               L0:       <next statement>
2662
*/
2663
static int
2664
codegen_try_star_except(compiler *c, stmt_ty s)
2665
253
{
2666
253
    location loc = LOC(s);
2667
2668
253
    NEW_JUMP_TARGET_LABEL(c, body);
2669
253
    NEW_JUMP_TARGET_LABEL(c, except);
2670
253
    NEW_JUMP_TARGET_LABEL(c, orelse);
2671
253
    NEW_JUMP_TARGET_LABEL(c, end);
2672
253
    NEW_JUMP_TARGET_LABEL(c, cleanup);
2673
253
    NEW_JUMP_TARGET_LABEL(c, reraise_star);
2674
2675
253
    ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
2676
2677
253
    USE_LABEL(c, body);
2678
253
    RETURN_IF_ERROR(
2679
253
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_TRY_EXCEPT, body, NO_LABEL, NULL));
2680
253
    VISIT_SEQ(c, stmt, s->v.TryStar.body);
2681
252
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_TRY_EXCEPT, body);
2682
252
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2683
252
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, orelse);
2684
252
    Py_ssize_t n = asdl_seq_LEN(s->v.TryStar.handlers);
2685
2686
252
    USE_LABEL(c, except);
2687
2688
252
    ADDOP_JUMP(c, NO_LOCATION, SETUP_CLEANUP, cleanup);
2689
252
    ADDOP(c, NO_LOCATION, PUSH_EXC_INFO);
2690
2691
    /* Runtime will push a block here, so we need to account for that */
2692
252
    RETURN_IF_ERROR(
2693
252
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_EXCEPTION_GROUP_HANDLER,
2694
252
                              NO_LABEL, NO_LABEL, "except handler"));
2695
2696
564
    for (Py_ssize_t i = 0; i < n; i++) {
2697
317
        excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
2698
317
            s->v.TryStar.handlers, i);
2699
317
        location loc = LOC(handler);
2700
317
        NEW_JUMP_TARGET_LABEL(c, next_except);
2701
317
        except = next_except;
2702
317
        NEW_JUMP_TARGET_LABEL(c, except_with_error);
2703
317
        NEW_JUMP_TARGET_LABEL(c, no_match);
2704
317
        if (i == 0) {
2705
            /* create empty list for exceptions raised/reraise in the except* blocks */
2706
            /*
2707
               [orig]       BUILD_LIST
2708
            */
2709
            /* Create a copy of the original EG */
2710
            /*
2711
               [orig, []]   COPY 2
2712
               [orig, [], exc]
2713
            */
2714
252
            ADDOP_I(c, loc, BUILD_LIST, 0);
2715
252
            ADDOP_I(c, loc, COPY, 2);
2716
252
        }
2717
317
        if (handler->v.ExceptHandler.type) {
2718
317
            VISIT(c, expr, handler->v.ExceptHandler.type);
2719
317
            ADDOP(c, loc, CHECK_EG_MATCH);
2720
317
            ADDOP_I(c, loc, COPY, 1);
2721
317
            ADDOP_JUMP(c, loc, POP_JUMP_IF_NONE, no_match);
2722
317
        }
2723
2724
317
        NEW_JUMP_TARGET_LABEL(c, cleanup_end);
2725
317
        NEW_JUMP_TARGET_LABEL(c, cleanup_body);
2726
2727
317
        if (handler->v.ExceptHandler.name) {
2728
3
            RETURN_IF_ERROR(
2729
3
                codegen_nameop(c, loc, handler->v.ExceptHandler.name, Store));
2730
3
        }
2731
314
        else {
2732
314
            ADDOP(c, loc, POP_TOP);  // match
2733
314
        }
2734
2735
        /*
2736
          try:
2737
              # body
2738
          except type as name:
2739
              try:
2740
                  # body
2741
              finally:
2742
                  name = None # in case body contains "del name"
2743
                  del name
2744
        */
2745
        /* second try: */
2746
317
        ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup_end);
2747
2748
317
        USE_LABEL(c, cleanup_body);
2749
317
        RETURN_IF_ERROR(
2750
317
            _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body,
2751
317
                                  NO_LABEL, handler->v.ExceptHandler.name));
2752
2753
        /* second # body */
2754
317
        VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
2755
312
        _PyCompile_PopFBlock(c, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body);
2756
        /* name = None; del name; # artificial */
2757
312
        ADDOP(c, NO_LOCATION, POP_BLOCK);
2758
312
        if (handler->v.ExceptHandler.name) {
2759
3
            ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
2760
3
            RETURN_IF_ERROR(
2761
3
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
2762
3
            RETURN_IF_ERROR(
2763
3
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
2764
3
        }
2765
312
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, except);
2766
2767
        /* except: */
2768
312
        USE_LABEL(c, cleanup_end);
2769
2770
        /* name = None; del name; # artificial */
2771
312
        if (handler->v.ExceptHandler.name) {
2772
3
            ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
2773
3
            RETURN_IF_ERROR(
2774
3
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
2775
3
            RETURN_IF_ERROR(
2776
3
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
2777
3
        }
2778
2779
        /* add exception raised to the res list */
2780
312
        ADDOP_I(c, NO_LOCATION, LIST_APPEND, 3); // exc
2781
312
        ADDOP(c, NO_LOCATION, POP_TOP); // lasti
2782
312
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, except_with_error);
2783
2784
312
        USE_LABEL(c, except);
2785
312
        ADDOP(c, NO_LOCATION, NOP);  // to hold a propagated location info
2786
312
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, except_with_error);
2787
2788
312
        USE_LABEL(c, no_match);
2789
312
        ADDOP(c, loc, POP_TOP);  // match (None)
2790
2791
312
        USE_LABEL(c, except_with_error);
2792
2793
312
        if (i == n - 1) {
2794
            /* Add exc to the list (if not None it's the unhandled part of the EG) */
2795
247
            ADDOP_I(c, NO_LOCATION, LIST_APPEND, 1);
2796
247
            ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, reraise_star);
2797
247
        }
2798
312
    }
2799
    /* artificial */
2800
247
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_EXCEPTION_GROUP_HANDLER, NO_LABEL);
2801
247
    NEW_JUMP_TARGET_LABEL(c, reraise);
2802
2803
247
    USE_LABEL(c, reraise_star);
2804
247
    ADDOP_I(c, NO_LOCATION, CALL_INTRINSIC_2, INTRINSIC_PREP_RERAISE_STAR);
2805
247
    ADDOP_I(c, NO_LOCATION, COPY, 1);
2806
247
    ADDOP_JUMP(c, NO_LOCATION, POP_JUMP_IF_NOT_NONE, reraise);
2807
2808
    /* Nothing to reraise */
2809
247
    ADDOP(c, NO_LOCATION, POP_TOP);
2810
247
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2811
247
    ADDOP(c, NO_LOCATION, POP_EXCEPT);
2812
247
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2813
2814
247
    USE_LABEL(c, reraise);
2815
247
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2816
247
    ADDOP_I(c, NO_LOCATION, SWAP, 2);
2817
247
    ADDOP(c, NO_LOCATION, POP_EXCEPT);
2818
247
    ADDOP_I(c, NO_LOCATION, RERAISE, 0);
2819
2820
247
    USE_LABEL(c, cleanup);
2821
247
    POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
2822
2823
247
    USE_LABEL(c, orelse);
2824
247
    VISIT_SEQ(c, stmt, s->v.TryStar.orelse);
2825
2826
243
    USE_LABEL(c, end);
2827
243
    return SUCCESS;
2828
243
}
2829
2830
static int
2831
591
codegen_try(compiler *c, stmt_ty s) {
2832
591
    if (s->v.Try.finalbody && asdl_seq_LEN(s->v.Try.finalbody))
2833
477
        return codegen_try_finally(c, s);
2834
114
    else
2835
114
        return codegen_try_except(c, s);
2836
591
}
2837
2838
static int
2839
codegen_try_star(compiler *c, stmt_ty s)
2840
253
{
2841
253
    if (s->v.TryStar.finalbody && asdl_seq_LEN(s->v.TryStar.finalbody)) {
2842
9
        return codegen_try_star_finally(c, s);
2843
9
    }
2844
244
    else {
2845
244
        return codegen_try_star_except(c, s);
2846
244
    }
2847
253
}
2848
2849
static int
2850
codegen_import_as(compiler *c, location loc,
2851
                  identifier name, identifier asname)
2852
21
{
2853
    /* The IMPORT_NAME opcode was already generated.  This function
2854
       merely needs to bind the result to a name.
2855
2856
       If there is a dot in name, we need to split it and emit a
2857
       IMPORT_FROM for each name.
2858
    */
2859
21
    Py_ssize_t len = PyUnicode_GET_LENGTH(name);
2860
21
    Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0, len, 1);
2861
21
    if (dot == -2) {
2862
0
        return ERROR;
2863
0
    }
2864
21
    if (dot != -1) {
2865
        /* Consume the base module name to get the first attribute */
2866
213
        while (1) {
2867
213
            Py_ssize_t pos = dot + 1;
2868
213
            PyObject *attr;
2869
213
            dot = PyUnicode_FindChar(name, '.', pos, len, 1);
2870
213
            if (dot == -2) {
2871
0
                return ERROR;
2872
0
            }
2873
213
            attr = PyUnicode_Substring(name, pos, (dot != -1) ? dot : len);
2874
213
            if (!attr) {
2875
0
                return ERROR;
2876
0
            }
2877
213
            ADDOP_N(c, loc, IMPORT_FROM, attr, names);
2878
213
            if (dot == -1) {
2879
20
                break;
2880
20
            }
2881
193
            ADDOP_I(c, loc, SWAP, 2);
2882
193
            ADDOP(c, loc, POP_TOP);
2883
193
        }
2884
20
        RETURN_IF_ERROR(codegen_nameop(c, loc, asname, Store));
2885
20
        ADDOP(c, loc, POP_TOP);
2886
20
        return SUCCESS;
2887
20
    }
2888
1
    return codegen_nameop(c, loc, asname, Store);
2889
21
}
2890
2891
static int
2892
codegen_validate_lazy_import(compiler *c, location loc)
2893
0
{
2894
0
    if (_PyCompile_ScopeType(c) != COMPILE_SCOPE_MODULE) {
2895
0
        return _PyCompile_Error(
2896
0
            c, loc, "lazy imports only allowed in module scope");
2897
0
    }
2898
2899
0
    return SUCCESS;
2900
0
}
2901
2902
static int
2903
codegen_import(compiler *c, stmt_ty s)
2904
845
{
2905
845
    location loc = LOC(s);
2906
    /* The Import node stores a module name like a.b.c as a single
2907
       string.  This is convenient for all cases except
2908
         import a.b.c as d
2909
       where we need to parse that string to extract the individual
2910
       module names.
2911
       XXX Perhaps change the representation to make this case simpler?
2912
     */
2913
845
    Py_ssize_t i, n = asdl_seq_LEN(s->v.Import.names);
2914
2915
845
    PyObject *zero = _PyLong_GetZero();  // borrowed reference
2916
3.63k
    for (i = 0; i < n; i++) {
2917
2.78k
        alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i);
2918
2.78k
        int r;
2919
2920
2.78k
        ADDOP_LOAD_CONST(c, loc, zero);
2921
2.78k
        ADDOP_LOAD_CONST(c, loc, Py_None);
2922
2.78k
        if (s->v.Import.is_lazy) {
2923
0
            RETURN_IF_ERROR(codegen_validate_lazy_import(c, loc));
2924
0
            ADDOP_NAME_CUSTOM(c, loc, IMPORT_NAME, alias->name, names, 2, 1);
2925
2.78k
        } else {
2926
2.78k
            if (_PyCompile_InExceptionHandler(c) ||
2927
2.78k
                _PyCompile_ScopeType(c) != COMPILE_SCOPE_MODULE) {
2928
                // force eager import in try/except block
2929
132
                ADDOP_NAME_CUSTOM(c, loc, IMPORT_NAME, alias->name, names, 2, 2);
2930
2.65k
            } else {
2931
2.65k
                ADDOP_NAME_CUSTOM(c, loc, IMPORT_NAME, alias->name, names, 2, 0);
2932
2.65k
            }
2933
2.78k
        }
2934
2935
2.78k
        if (alias->asname) {
2936
21
            r = codegen_import_as(c, loc, alias->name, alias->asname);
2937
21
            RETURN_IF_ERROR(r);
2938
21
        }
2939
2.76k
        else {
2940
2.76k
            identifier tmp = alias->name;
2941
2.76k
            Py_ssize_t dot = PyUnicode_FindChar(
2942
2.76k
                alias->name, '.', 0, PyUnicode_GET_LENGTH(alias->name), 1);
2943
2.76k
            if (dot != -1) {
2944
1.20k
                tmp = PyUnicode_Substring(alias->name, 0, dot);
2945
1.20k
                if (tmp == NULL) {
2946
0
                    return ERROR;
2947
0
                }
2948
1.20k
            }
2949
2.76k
            r = codegen_nameop(c, loc, tmp, Store);
2950
2.76k
            if (dot != -1) {
2951
1.20k
                Py_DECREF(tmp);
2952
1.20k
            }
2953
2.76k
            RETURN_IF_ERROR(r);
2954
2.76k
        }
2955
2.78k
    }
2956
845
    return SUCCESS;
2957
845
}
2958
2959
static int
2960
codegen_from_import(compiler *c, stmt_ty s)
2961
555
{
2962
555
    Py_ssize_t n = asdl_seq_LEN(s->v.ImportFrom.names);
2963
2964
555
    ADDOP_LOAD_CONST_NEW(c, LOC(s), PyLong_FromLong(s->v.ImportFrom.level));
2965
2966
555
    PyObject *names = PyTuple_New(n);
2967
555
    if (!names) {
2968
0
        return ERROR;
2969
0
    }
2970
2971
    /* build up the names */
2972
1.53k
    for (Py_ssize_t i = 0; i < n; i++) {
2973
984
        alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
2974
984
        PyTuple_SET_ITEM(names, i, Py_NewRef(alias->name));
2975
984
    }
2976
2977
555
    ADDOP_LOAD_CONST_NEW(c, LOC(s), names);
2978
2979
555
    identifier from = &_Py_STR(empty);
2980
555
    if (s->v.ImportFrom.module) {
2981
543
        from = s->v.ImportFrom.module;
2982
543
    }
2983
555
    if (s->v.ImportFrom.is_lazy) {
2984
0
        alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, 0);
2985
0
        if (PyUnicode_READ_CHAR(alias->name, 0) == '*') {
2986
0
            return _PyCompile_Error(c, LOC(s), "cannot lazy import *");
2987
0
        }
2988
0
        RETURN_IF_ERROR(codegen_validate_lazy_import(c, LOC(s)));
2989
0
        ADDOP_NAME_CUSTOM(c, LOC(s), IMPORT_NAME, from, names, 2, 1);
2990
555
    } else {
2991
555
        alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, 0);
2992
555
        if (_PyCompile_InExceptionHandler(c) ||
2993
555
            _PyCompile_ScopeType(c) != COMPILE_SCOPE_MODULE ||
2994
555
            PyUnicode_READ_CHAR(alias->name, 0) == '*') {
2995
            // forced non-lazy import due to try/except or import *
2996
1
            ADDOP_NAME_CUSTOM(c, LOC(s), IMPORT_NAME, from, names, 2, 2);
2997
554
        } else {
2998
554
            ADDOP_NAME_CUSTOM(c, LOC(s), IMPORT_NAME, from, names, 2, 0);
2999
554
        }
3000
555
    }
3001
3002
1.53k
    for (Py_ssize_t i = 0; i < n; i++) {
3003
984
        alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
3004
984
        identifier store_name;
3005
3006
984
        if (i == 0 && PyUnicode_READ_CHAR(alias->name, 0) == '*') {
3007
1
            assert(n == 1);
3008
1
            ADDOP_I(c, LOC(s), CALL_INTRINSIC_1, INTRINSIC_IMPORT_STAR);
3009
1
            ADDOP(c, NO_LOCATION, POP_TOP);
3010
1
            return SUCCESS;
3011
1
        }
3012
3013
983
        ADDOP_NAME(c, LOC(s), IMPORT_FROM, alias->name, names);
3014
983
        store_name = alias->name;
3015
983
        if (alias->asname) {
3016
55
            store_name = alias->asname;
3017
55
        }
3018
3019
983
        RETURN_IF_ERROR(codegen_nameop(c, LOC(s), store_name, Store));
3020
983
    }
3021
    /* remove imported module */
3022
554
    ADDOP(c, LOC(s), POP_TOP);
3023
554
    return SUCCESS;
3024
554
}
3025
3026
static int
3027
codegen_assert(compiler *c, stmt_ty s)
3028
788
{
3029
    /* Always emit a warning if the test is a non-zero length tuple */
3030
788
    if ((s->v.Assert.test->kind == Tuple_kind &&
3031
158
        asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) ||
3032
728
        (s->v.Assert.test->kind == Constant_kind &&
3033
728
         PyTuple_Check(s->v.Assert.test->v.Constant.value) &&
3034
0
         PyTuple_Size(s->v.Assert.test->v.Constant.value) > 0))
3035
60
    {
3036
60
        RETURN_IF_ERROR(
3037
60
            _PyCompile_Warn(c, LOC(s), "assertion is always true, "
3038
60
                                       "perhaps remove parentheses?"));
3039
60
    }
3040
788
    if (OPTIMIZATION_LEVEL(c)) {
3041
62
        return SUCCESS;
3042
62
    }
3043
726
    NEW_JUMP_TARGET_LABEL(c, end);
3044
726
    RETURN_IF_ERROR(codegen_jump_if(c, LOC(s), s->v.Assert.test, end, 1));
3045
726
    ADDOP_I(c, LOC(s), LOAD_COMMON_CONSTANT, CONSTANT_ASSERTIONERROR);
3046
726
    if (s->v.Assert.msg) {
3047
54
        VISIT(c, expr, s->v.Assert.msg);
3048
54
        ADDOP_I(c, LOC(s), CALL, 0);
3049
54
    }
3050
726
    ADDOP_I(c, LOC(s->v.Assert.test), RAISE_VARARGS, 1);
3051
3052
726
    USE_LABEL(c, end);
3053
726
    return SUCCESS;
3054
726
}
3055
3056
static int
3057
codegen_stmt_expr(compiler *c, location loc, expr_ty value)
3058
28.7k
{
3059
28.7k
    if (IS_INTERACTIVE_TOP_LEVEL(c)) {
3060
1.07k
        VISIT(c, expr, value);
3061
1.04k
        ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_PRINT);
3062
1.04k
        ADDOP(c, NO_LOCATION, POP_TOP);
3063
1.04k
        return SUCCESS;
3064
1.04k
    }
3065
3066
27.6k
    if (value->kind == Constant_kind) {
3067
        /* ignore constant statement */
3068
812
        ADDOP(c, loc, NOP);
3069
812
        return SUCCESS;
3070
812
    }
3071
3072
26.8k
    VISIT(c, expr, value);
3073
26.7k
    ADDOP(c, NO_LOCATION, POP_TOP); /* artificial */
3074
26.7k
    return SUCCESS;
3075
26.7k
}
3076
3077
#define CODEGEN_COND_BLOCK(FUNC, C, S) \
3078
3.79k
    do { \
3079
3.79k
        _PyCompile_EnterConditionalBlock((C)); \
3080
3.79k
        int result = FUNC((C), (S)); \
3081
3.79k
        _PyCompile_LeaveConditionalBlock((C)); \
3082
3.79k
        return result; \
3083
3.79k
    } while(0)
3084
3085
static int
3086
codegen_visit_stmt(compiler *c, stmt_ty s)
3087
60.1k
{
3088
3089
60.1k
    switch (s->kind) {
3090
3.25k
    case FunctionDef_kind:
3091
3.25k
        return codegen_function(c, s, 0);
3092
4.92k
    case ClassDef_kind:
3093
4.92k
        return codegen_class(c, s);
3094
31
    case TypeAlias_kind:
3095
31
        return codegen_typealias(c, s);
3096
172
    case Return_kind:
3097
172
        return codegen_return(c, s);
3098
291
    case Delete_kind:
3099
291
        VISIT_SEQ(c, expr, s->v.Delete.targets);
3100
291
        break;
3101
2.08k
    case Assign_kind:
3102
2.08k
    {
3103
2.08k
        Py_ssize_t n = asdl_seq_LEN(s->v.Assign.targets);
3104
2.08k
        VISIT(c, expr, s->v.Assign.value);
3105
15.3k
        for (Py_ssize_t i = 0; i < n; i++) {
3106
13.2k
            if (i < n - 1) {
3107
11.1k
                ADDOP_I(c, LOC(s), COPY, 1);
3108
11.1k
            }
3109
13.2k
            VISIT(c, expr,
3110
13.2k
                  (expr_ty)asdl_seq_GET(s->v.Assign.targets, i));
3111
13.2k
        }
3112
2.07k
        break;
3113
2.07k
    }
3114
2.07k
    case AugAssign_kind:
3115
1.46k
        return codegen_augassign(c, s);
3116
12.1k
    case AnnAssign_kind:
3117
12.1k
        return codegen_annassign(c, s);
3118
232
    case For_kind:
3119
232
        CODEGEN_COND_BLOCK(codegen_for, c, s);
3120
0
        break;
3121
1.13k
    case While_kind:
3122
1.13k
        CODEGEN_COND_BLOCK(codegen_while, c, s);
3123
0
        break;
3124
695
    case If_kind:
3125
695
        CODEGEN_COND_BLOCK(codegen_if, c, s);
3126
0
        break;
3127
46
    case Match_kind:
3128
46
        CODEGEN_COND_BLOCK(codegen_match, c, s);
3129
0
        break;
3130
32
    case Raise_kind:
3131
32
    {
3132
32
        Py_ssize_t n = 0;
3133
32
        if (s->v.Raise.exc) {
3134
8
            VISIT(c, expr, s->v.Raise.exc);
3135
8
            n++;
3136
8
            if (s->v.Raise.cause) {
3137
6
                VISIT(c, expr, s->v.Raise.cause);
3138
6
                n++;
3139
6
            }
3140
8
        }
3141
32
        ADDOP_I(c, LOC(s), RAISE_VARARGS, (int)n);
3142
32
        break;
3143
32
    }
3144
591
    case Try_kind:
3145
591
        CODEGEN_COND_BLOCK(codegen_try, c, s);
3146
0
        break;
3147
253
    case TryStar_kind:
3148
253
        CODEGEN_COND_BLOCK(codegen_try_star, c, s);
3149
0
        break;
3150
788
    case Assert_kind:
3151
788
        return codegen_assert(c, s);
3152
845
    case Import_kind:
3153
845
        return codegen_import(c, s);
3154
555
    case ImportFrom_kind:
3155
555
        return codegen_from_import(c, s);
3156
61
    case Global_kind:
3157
61
    case Nonlocal_kind:
3158
61
        break;
3159
28.7k
    case Expr_kind:
3160
28.7k
    {
3161
28.7k
        return codegen_stmt_expr(c, LOC(s), s->v.Expr.value);
3162
61
    }
3163
162
    case Pass_kind:
3164
162
    {
3165
162
        ADDOP(c, LOC(s), NOP);
3166
162
        break;
3167
162
    }
3168
162
    case Break_kind:
3169
1
    {
3170
1
        return codegen_break(c, LOC(s));
3171
162
    }
3172
63
    case Continue_kind:
3173
63
    {
3174
63
        return codegen_continue(c, LOC(s));
3175
162
    }
3176
29
    case With_kind:
3177
29
        CODEGEN_COND_BLOCK(codegen_with, c, s);
3178
0
        break;
3179
833
    case AsyncFunctionDef_kind:
3180
833
        return codegen_function(c, s, 1);
3181
815
    case AsyncWith_kind:
3182
815
        CODEGEN_COND_BLOCK(codegen_async_with, c, s);
3183
0
        break;
3184
1
    case AsyncFor_kind:
3185
1
        CODEGEN_COND_BLOCK(codegen_async_for, c, s);
3186
0
        break;
3187
60.1k
    }
3188
3189
2.62k
    return SUCCESS;
3190
60.1k
}
3191
3192
static int
3193
unaryop(unaryop_ty op)
3194
65.2k
{
3195
65.2k
    switch (op) {
3196
5.10k
    case Invert:
3197
5.10k
        return UNARY_INVERT;
3198
60.1k
    case USub:
3199
60.1k
        return UNARY_NEGATIVE;
3200
0
    default:
3201
0
        PyErr_Format(PyExc_SystemError,
3202
0
            "unary op %d should not be possible", op);
3203
0
        return 0;
3204
65.2k
    }
3205
65.2k
}
3206
3207
static int
3208
addop_binary(compiler *c, location loc, operator_ty binop,
3209
             bool inplace)
3210
238k
{
3211
238k
    int oparg;
3212
238k
    switch (binop) {
3213
42.6k
        case Add:
3214
42.6k
            oparg = inplace ? NB_INPLACE_ADD : NB_ADD;
3215
42.6k
            break;
3216
52.0k
        case Sub:
3217
52.0k
            oparg = inplace ? NB_INPLACE_SUBTRACT : NB_SUBTRACT;
3218
52.0k
            break;
3219
33.7k
        case Mult:
3220
33.7k
            oparg = inplace ? NB_INPLACE_MULTIPLY : NB_MULTIPLY;
3221
33.7k
            break;
3222
261
        case MatMult:
3223
261
            oparg = inplace ? NB_INPLACE_MATRIX_MULTIPLY : NB_MATRIX_MULTIPLY;
3224
261
            break;
3225
24.3k
        case Div:
3226
24.3k
            oparg = inplace ? NB_INPLACE_TRUE_DIVIDE : NB_TRUE_DIVIDE;
3227
24.3k
            break;
3228
18.6k
        case Mod:
3229
18.6k
            oparg = inplace ? NB_INPLACE_REMAINDER : NB_REMAINDER;
3230
18.6k
            break;
3231
40.7k
        case Pow:
3232
40.7k
            oparg = inplace ? NB_INPLACE_POWER : NB_POWER;
3233
40.7k
            break;
3234
2.28k
        case LShift:
3235
2.28k
            oparg = inplace ? NB_INPLACE_LSHIFT : NB_LSHIFT;
3236
2.28k
            break;
3237
4.88k
        case RShift:
3238
4.88k
            oparg = inplace ? NB_INPLACE_RSHIFT : NB_RSHIFT;
3239
4.88k
            break;
3240
1.94k
        case BitOr:
3241
1.94k
            oparg = inplace ? NB_INPLACE_OR : NB_OR;
3242
1.94k
            break;
3243
3.43k
        case BitXor:
3244
3.43k
            oparg = inplace ? NB_INPLACE_XOR : NB_XOR;
3245
3.43k
            break;
3246
5.33k
        case BitAnd:
3247
5.33k
            oparg = inplace ? NB_INPLACE_AND : NB_AND;
3248
5.33k
            break;
3249
7.97k
        case FloorDiv:
3250
7.97k
            oparg = inplace ? NB_INPLACE_FLOOR_DIVIDE : NB_FLOOR_DIVIDE;
3251
7.97k
            break;
3252
0
        default:
3253
0
            PyErr_Format(PyExc_SystemError, "%s op %d should not be possible",
3254
0
                         inplace ? "inplace" : "binary", binop);
3255
0
            return ERROR;
3256
238k
    }
3257
238k
    ADDOP_I(c, loc, BINARY_OP, oparg);
3258
238k
    return SUCCESS;
3259
238k
}
3260
3261
3262
static int
3263
7
codegen_addop_yield(compiler *c, location loc) {
3264
7
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
3265
7
    if (ste->ste_generator && ste->ste_coroutine) {
3266
4
        ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_ASYNC_GEN_WRAP);
3267
4
    }
3268
7
    ADDOP_I(c, loc, YIELD_VALUE, 0);
3269
7
    ADDOP_I(c, loc, RESUME, RESUME_AFTER_YIELD);
3270
7
    return SUCCESS;
3271
7
}
3272
3273
static int
3274
codegen_load_classdict_freevar(compiler *c, location loc)
3275
7.57k
{
3276
7.57k
    ADDOP_N(c, loc, LOAD_DEREF, &_Py_ID(__classdict__), freevars);
3277
7.57k
    return SUCCESS;
3278
7.57k
}
3279
3280
static int
3281
codegen_nameop(compiler *c, location loc,
3282
               identifier name, expr_context_ty ctx)
3283
151k
{
3284
151k
    assert(!_PyUnicode_EqualToASCIIString(name, "None") &&
3285
151k
           !_PyUnicode_EqualToASCIIString(name, "True") &&
3286
151k
           !_PyUnicode_EqualToASCIIString(name, "False"));
3287
3288
151k
    PyObject *mangled = _PyCompile_MaybeMangle(c, name);
3289
151k
    if (!mangled) {
3290
0
        return ERROR;
3291
0
    }
3292
3293
151k
    int scope = _PyST_GetScope(SYMTABLE_ENTRY(c), mangled);
3294
151k
    if (scope == -1) {
3295
0
        goto error;
3296
0
    }
3297
3298
151k
    _PyCompile_optype optype;
3299
151k
    Py_ssize_t arg = 0;
3300
151k
    if (_PyCompile_ResolveNameop(c, mangled, scope, &optype, &arg) < 0) {
3301
0
        Py_DECREF(mangled);
3302
0
        return ERROR;
3303
0
    }
3304
3305
    /* XXX Leave assert here, but handle __doc__ and the like better */
3306
151k
    assert(scope || PyUnicode_READ_CHAR(name, 0) == '_');
3307
3308
151k
    int op = 0;
3309
151k
    switch (optype) {
3310
708
    case COMPILE_OP_DEREF:
3311
708
        switch (ctx) {
3312
341
        case Load:
3313
341
            if (SYMTABLE_ENTRY(c)->ste_type == ClassBlock && !_PyCompile_IsInInlinedComp(c)) {
3314
135
                op = LOAD_FROM_DICT_OR_DEREF;
3315
                // First load the locals
3316
135
                if (codegen_addop_noarg(INSTR_SEQUENCE(c), LOAD_LOCALS, loc) < 0) {
3317
0
                    goto error;
3318
0
                }
3319
135
            }
3320
206
            else if (SYMTABLE_ENTRY(c)->ste_can_see_class_scope) {
3321
95
                op = LOAD_FROM_DICT_OR_DEREF;
3322
                // First load the classdict
3323
95
                if (codegen_load_classdict_freevar(c, loc) < 0) {
3324
0
                    goto error;
3325
0
                }
3326
95
            }
3327
111
            else {
3328
111
                op = LOAD_DEREF;
3329
111
            }
3330
341
            break;
3331
367
        case Store: op = STORE_DEREF; break;
3332
0
        case Del: op = DELETE_DEREF; break;
3333
708
        }
3334
708
        break;
3335
28.9k
    case COMPILE_OP_FAST:
3336
28.9k
        switch (ctx) {
3337
4.79k
        case Load: op = LOAD_FAST; break;
3338
23.2k
        case Store: op = STORE_FAST; break;
3339
888
        case Del: op = DELETE_FAST; break;
3340
28.9k
        }
3341
28.9k
        ADDOP_N(c, loc, op, mangled, varnames);
3342
28.9k
        return SUCCESS;
3343
30.7k
    case COMPILE_OP_GLOBAL:
3344
30.7k
        switch (ctx) {
3345
30.7k
        case Load:
3346
30.7k
            if (SYMTABLE_ENTRY(c)->ste_can_see_class_scope && scope == GLOBAL_IMPLICIT) {
3347
7.47k
                op = LOAD_FROM_DICT_OR_GLOBALS;
3348
                // First load the classdict
3349
7.47k
                if (codegen_load_classdict_freevar(c, loc) < 0) {
3350
0
                    goto error;
3351
0
                }
3352
23.2k
            } else {
3353
23.2k
                op = LOAD_GLOBAL;
3354
23.2k
            }
3355
30.7k
            break;
3356
30.7k
        case Store: op = STORE_GLOBAL; break;
3357
6
        case Del: op = DELETE_GLOBAL; break;
3358
30.7k
        }
3359
30.7k
        break;
3360
90.9k
    case COMPILE_OP_NAME:
3361
90.9k
        switch (ctx) {
3362
45.6k
        case Load:
3363
45.6k
            op = (SYMTABLE_ENTRY(c)->ste_type == ClassBlock
3364
19.8k
                    && _PyCompile_IsInInlinedComp(c))
3365
45.6k
                ? LOAD_GLOBAL
3366
45.6k
                : LOAD_NAME;
3367
45.6k
            break;
3368
45.1k
        case Store: op = STORE_NAME; break;
3369
167
        case Del: op = DELETE_NAME; break;
3370
90.9k
        }
3371
90.9k
        break;
3372
151k
    }
3373
3374
151k
    assert(op);
3375
122k
    Py_DECREF(mangled);
3376
122k
    if (op == LOAD_GLOBAL) {
3377
23.2k
        arg <<= 1;
3378
23.2k
    }
3379
122k
    ADDOP_I(c, loc, op, arg);
3380
122k
    return SUCCESS;
3381
3382
0
error:
3383
0
    Py_DECREF(mangled);
3384
0
    return ERROR;
3385
122k
}
3386
3387
static int
3388
codegen_boolop(compiler *c, expr_ty e)
3389
1.32k
{
3390
1.32k
    int jumpi;
3391
1.32k
    Py_ssize_t i, n;
3392
1.32k
    asdl_expr_seq *s;
3393
3394
1.32k
    location loc = LOC(e);
3395
1.32k
    assert(e->kind == BoolOp_kind);
3396
1.32k
    if (e->v.BoolOp.op == And)
3397
748
        jumpi = JUMP_IF_FALSE;
3398
572
    else
3399
572
        jumpi = JUMP_IF_TRUE;
3400
1.32k
    NEW_JUMP_TARGET_LABEL(c, end);
3401
1.32k
    s = e->v.BoolOp.values;
3402
1.32k
    n = asdl_seq_LEN(s) - 1;
3403
1.32k
    assert(n >= 0);
3404
3.85k
    for (i = 0; i < n; ++i) {
3405
2.53k
        VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i));
3406
2.53k
        ADDOP_JUMP(c, loc, jumpi, end);
3407
2.53k
        ADDOP(c, loc, POP_TOP);
3408
2.53k
    }
3409
1.32k
    VISIT(c, expr, (expr_ty)asdl_seq_GET(s, n));
3410
3411
1.31k
    USE_LABEL(c, end);
3412
1.31k
    return SUCCESS;
3413
1.31k
}
3414
3415
static int
3416
starunpack_helper_impl(compiler *c, location loc,
3417
                       asdl_expr_seq *elts, PyObject *injected_arg, int pushed,
3418
                       int build, int add, int extend, int tuple)
3419
7.86k
{
3420
7.86k
    Py_ssize_t n = asdl_seq_LEN(elts);
3421
7.86k
    int big = n + pushed + (injected_arg ? 1 : 0) > _PY_STACK_USE_GUIDELINE;
3422
7.86k
    int seen_star = 0;
3423
38.2k
    for (Py_ssize_t i = 0; i < n; i++) {
3424
30.8k
        expr_ty elt = asdl_seq_GET(elts, i);
3425
30.8k
        if (elt->kind == Starred_kind) {
3426
450
            seen_star = 1;
3427
450
            break;
3428
450
        }
3429
30.8k
    }
3430
7.86k
    if (!seen_star && !big) {
3431
29.7k
        for (Py_ssize_t i = 0; i < n; i++) {
3432
22.4k
            expr_ty elt = asdl_seq_GET(elts, i);
3433
22.4k
            VISIT(c, expr, elt);
3434
22.4k
        }
3435
7.33k
        if (injected_arg) {
3436
0
            RETURN_IF_ERROR(codegen_nameop(c, loc, injected_arg, Load));
3437
0
            n++;
3438
0
        }
3439
7.33k
        if (tuple) {
3440
6.87k
            ADDOP_I(c, loc, BUILD_TUPLE, n+pushed);
3441
6.87k
        } else {
3442
455
            ADDOP_I(c, loc, build, n+pushed);
3443
455
        }
3444
7.33k
        return SUCCESS;
3445
7.33k
    }
3446
520
    int sequence_built = 0;
3447
520
    if (big) {
3448
82
        ADDOP_I(c, loc, build, pushed);
3449
82
        sequence_built = 1;
3450
82
    }
3451
10.2k
    for (Py_ssize_t i = 0; i < n; i++) {
3452
9.73k
        expr_ty elt = asdl_seq_GET(elts, i);
3453
9.73k
        if (elt->kind == Starred_kind) {
3454
650
            if (sequence_built == 0) {
3455
438
                ADDOP_I(c, loc, build, i+pushed);
3456
438
                sequence_built = 1;
3457
438
            }
3458
650
            VISIT(c, expr, elt->v.Starred.value);
3459
647
            ADDOP_I(c, loc, extend, 1);
3460
647
        }
3461
9.08k
        else {
3462
9.08k
            VISIT(c, expr, elt);
3463
9.08k
            if (sequence_built) {
3464
8.68k
                ADDOP_I(c, loc, add, 1);
3465
8.68k
            }
3466
9.08k
        }
3467
9.73k
    }
3468
520
    assert(sequence_built);
3469
517
    if (injected_arg) {
3470
0
        RETURN_IF_ERROR(codegen_nameop(c, loc, injected_arg, Load));
3471
0
        ADDOP_I(c, loc, add, 1);
3472
0
    }
3473
517
    if (tuple) {
3474
494
        ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_LIST_TO_TUPLE);
3475
494
    }
3476
517
    return SUCCESS;
3477
517
}
3478
3479
static int
3480
starunpack_helper(compiler *c, location loc,
3481
                  asdl_expr_seq *elts, int pushed,
3482
                  int build, int add, int extend, int tuple)
3483
7.51k
{
3484
7.51k
    return starunpack_helper_impl(c, loc, elts, NULL, pushed,
3485
7.51k
                                  build, add, extend, tuple);
3486
7.51k
}
3487
3488
static int
3489
unpack_helper(compiler *c, location loc, asdl_expr_seq *elts)
3490
6.09k
{
3491
6.09k
    Py_ssize_t n = asdl_seq_LEN(elts);
3492
6.09k
    int seen_star = 0;
3493
20.8k
    for (Py_ssize_t i = 0; i < n; i++) {
3494
14.7k
        expr_ty elt = asdl_seq_GET(elts, i);
3495
14.7k
        if (elt->kind == Starred_kind && !seen_star) {
3496
51
            if ((i >= (1 << 8)) ||
3497
51
                (n-i-1 >= (INT_MAX >> 8))) {
3498
0
                return _PyCompile_Error(c, loc,
3499
0
                    "too many expressions in "
3500
0
                    "star-unpacking assignment");
3501
0
            }
3502
51
            ADDOP_I(c, loc, UNPACK_EX, (i + ((n-i-1) << 8)));
3503
51
            seen_star = 1;
3504
51
        }
3505
14.7k
        else if (elt->kind == Starred_kind) {
3506
1
            return _PyCompile_Error(c, loc,
3507
1
                "multiple starred expressions in assignment");
3508
1
        }
3509
14.7k
    }
3510
6.09k
    if (!seen_star) {
3511
6.04k
        ADDOP_I(c, loc, UNPACK_SEQUENCE, n);
3512
6.04k
    }
3513
6.09k
    return SUCCESS;
3514
6.09k
}
3515
3516
static int
3517
assignment_helper(compiler *c, location loc, asdl_expr_seq *elts)
3518
6.09k
{
3519
6.09k
    Py_ssize_t n = asdl_seq_LEN(elts);
3520
6.09k
    RETURN_IF_ERROR(unpack_helper(c, loc, elts));
3521
20.8k
    for (Py_ssize_t i = 0; i < n; i++) {
3522
14.7k
        expr_ty elt = asdl_seq_GET(elts, i);
3523
14.7k
        VISIT(c, expr, elt->kind != Starred_kind ? elt : elt->v.Starred.value);
3524
14.7k
    }
3525
6.09k
    return SUCCESS;
3526
6.09k
}
3527
3528
static int
3529
codegen_list(compiler *c, expr_ty e)
3530
110
{
3531
110
    location loc = LOC(e);
3532
110
    asdl_expr_seq *elts = e->v.List.elts;
3533
110
    if (e->v.List.ctx == Store) {
3534
7
        return assignment_helper(c, loc, elts);
3535
7
    }
3536
103
    else if (e->v.List.ctx == Load) {
3537
99
        return starunpack_helper(c, loc, elts, 0,
3538
99
                                 BUILD_LIST, LIST_APPEND, LIST_EXTEND, 0);
3539
99
    }
3540
4
    else {
3541
4
        VISIT_SEQ(c, expr, elts);
3542
4
    }
3543
4
    return SUCCESS;
3544
110
}
3545
3546
static int
3547
codegen_tuple(compiler *c, expr_ty e)
3548
13.1k
{
3549
13.1k
    location loc = LOC(e);
3550
13.1k
    asdl_expr_seq *elts = e->v.Tuple.elts;
3551
13.1k
    if (e->v.Tuple.ctx == Store) {
3552
6.09k
        return assignment_helper(c, loc, elts);
3553
6.09k
    }
3554
7.03k
    else if (e->v.Tuple.ctx == Load) {
3555
7.03k
        return starunpack_helper(c, loc, elts, 0,
3556
7.03k
                                 BUILD_LIST, LIST_APPEND, LIST_EXTEND, 1);
3557
7.03k
    }
3558
1
    else {
3559
1
        VISIT_SEQ(c, expr, elts);
3560
1
    }
3561
1
    return SUCCESS;
3562
13.1k
}
3563
3564
static int
3565
codegen_set(compiler *c, expr_ty e)
3566
379
{
3567
379
    location loc = LOC(e);
3568
379
    return starunpack_helper(c, loc, e->v.Set.elts, 0,
3569
379
                             BUILD_SET, SET_ADD, SET_UPDATE, 0);
3570
379
}
3571
3572
static int
3573
codegen_subdict(compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end)
3574
3
{
3575
3
    Py_ssize_t i, n = end - begin;
3576
3
    int big = n*2 > _PY_STACK_USE_GUIDELINE;
3577
3
    location loc = LOC(e);
3578
3
    if (big) {
3579
0
        ADDOP_I(c, loc, BUILD_MAP, 0);
3580
0
    }
3581
6
    for (i = begin; i < end; i++) {
3582
3
        VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i));
3583
3
        VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
3584
3
        if (big) {
3585
0
            ADDOP_I(c, loc, MAP_ADD, 1);
3586
0
        }
3587
3
    }
3588
3
    if (!big) {
3589
3
        ADDOP_I(c, loc, BUILD_MAP, n);
3590
3
    }
3591
3
    return SUCCESS;
3592
3
}
3593
3594
static int
3595
codegen_dict(compiler *c, expr_ty e)
3596
35
{
3597
35
    location loc = LOC(e);
3598
35
    Py_ssize_t i, n, elements;
3599
35
    int have_dict;
3600
35
    int is_unpacking = 0;
3601
35
    n = asdl_seq_LEN(e->v.Dict.values);
3602
35
    have_dict = 0;
3603
35
    elements = 0;
3604
44
    for (i = 0; i < n; i++) {
3605
9
        is_unpacking = (expr_ty)asdl_seq_GET(e->v.Dict.keys, i) == NULL;
3606
9
        if (is_unpacking) {
3607
6
            if (elements) {
3608
1
                RETURN_IF_ERROR(codegen_subdict(c, e, i - elements, i));
3609
1
                if (have_dict) {
3610
0
                    ADDOP_I(c, loc, DICT_UPDATE, 1);
3611
0
                }
3612
1
                have_dict = 1;
3613
1
                elements = 0;
3614
1
            }
3615
6
            if (have_dict == 0) {
3616
5
                ADDOP_I(c, loc, BUILD_MAP, 0);
3617
5
                have_dict = 1;
3618
5
            }
3619
6
            VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
3620
6
            ADDOP_I(c, loc, DICT_UPDATE, 1);
3621
6
        }
3622
3
        else {
3623
3
            if (elements*2 > _PY_STACK_USE_GUIDELINE) {
3624
0
                RETURN_IF_ERROR(codegen_subdict(c, e, i - elements, i + 1));
3625
0
                if (have_dict) {
3626
0
                    ADDOP_I(c, loc, DICT_UPDATE, 1);
3627
0
                }
3628
0
                have_dict = 1;
3629
0
                elements = 0;
3630
0
            }
3631
3
            else {
3632
3
                elements++;
3633
3
            }
3634
3
        }
3635
9
    }
3636
35
    if (elements) {
3637
2
        RETURN_IF_ERROR(codegen_subdict(c, e, n - elements, n));
3638
2
        if (have_dict) {
3639
0
            ADDOP_I(c, loc, DICT_UPDATE, 1);
3640
0
        }
3641
2
        have_dict = 1;
3642
2
    }
3643
35
    if (!have_dict) {
3644
27
        ADDOP_I(c, loc, BUILD_MAP, 0);
3645
27
    }
3646
35
    return SUCCESS;
3647
35
}
3648
3649
static int
3650
codegen_compare(compiler *c, expr_ty e)
3651
6.93k
{
3652
6.93k
    location loc = LOC(e);
3653
6.93k
    Py_ssize_t i, n;
3654
3655
6.93k
    RETURN_IF_ERROR(codegen_check_compare(c, e));
3656
6.93k
    VISIT(c, expr, e->v.Compare.left);
3657
6.93k
    assert(asdl_seq_LEN(e->v.Compare.ops) > 0);
3658
6.92k
    n = asdl_seq_LEN(e->v.Compare.ops) - 1;
3659
6.92k
    if (n == 0) {
3660
3.73k
        VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, 0));
3661
3.73k
        ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, 0));
3662
3.73k
    }
3663
3.19k
    else {
3664
3.19k
        NEW_JUMP_TARGET_LABEL(c, cleanup);
3665
19.2k
        for (i = 0; i < n; i++) {
3666
16.0k
            VISIT(c, expr,
3667
16.0k
                (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
3668
16.0k
            ADDOP_I(c, loc, SWAP, 2);
3669
16.0k
            ADDOP_I(c, loc, COPY, 2);
3670
16.0k
            ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, i));
3671
16.0k
            ADDOP_I(c, loc, COPY, 1);
3672
16.0k
            ADDOP(c, loc, TO_BOOL);
3673
16.0k
            ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, cleanup);
3674
16.0k
            ADDOP(c, loc, POP_TOP);
3675
16.0k
        }
3676
3.19k
        VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
3677
3.19k
        ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, n));
3678
3.19k
        NEW_JUMP_TARGET_LABEL(c, end);
3679
3.19k
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
3680
3681
3.19k
        USE_LABEL(c, cleanup);
3682
3.19k
        ADDOP_I(c, loc, SWAP, 2);
3683
3.19k
        ADDOP(c, loc, POP_TOP);
3684
3685
3.19k
        USE_LABEL(c, end);
3686
3.19k
    }
3687
6.92k
    return SUCCESS;
3688
6.92k
}
3689
3690
static PyTypeObject *
3691
infer_type(expr_ty e)
3692
2.96k
{
3693
2.96k
    switch (e->kind) {
3694
155
    case Tuple_kind:
3695
155
        return &PyTuple_Type;
3696
15
    case List_kind:
3697
15
    case ListComp_kind:
3698
15
        return &PyList_Type;
3699
9
    case Dict_kind:
3700
118
    case DictComp_kind:
3701
118
        return &PyDict_Type;
3702
104
    case Set_kind:
3703
245
    case SetComp_kind:
3704
245
        return &PySet_Type;
3705
0
    case GeneratorExp_kind:
3706
0
        return &PyGen_Type;
3707
1
    case Lambda_kind:
3708
1
        return &PyFunction_Type;
3709
11
    case TemplateStr_kind:
3710
11
    case Interpolation_kind:
3711
11
        return &_PyTemplate_Type;
3712
1
    case JoinedStr_kind:
3713
1
    case FormattedValue_kind:
3714
1
        return &PyUnicode_Type;
3715
784
    case Constant_kind:
3716
784
        return Py_TYPE(e->v.Constant.value);
3717
1.63k
    default:
3718
1.63k
        return NULL;
3719
2.96k
    }
3720
2.96k
}
3721
3722
static int
3723
check_caller(compiler *c, expr_ty e)
3724
1.65k
{
3725
1.65k
    switch (e->kind) {
3726
560
    case Constant_kind:
3727
573
    case Tuple_kind:
3728
576
    case List_kind:
3729
576
    case ListComp_kind:
3730
579
    case Dict_kind:
3731
688
    case DictComp_kind:
3732
689
    case Set_kind:
3733
829
    case SetComp_kind:
3734
829
    case GeneratorExp_kind:
3735
830
    case JoinedStr_kind:
3736
833
    case TemplateStr_kind:
3737
833
    case FormattedValue_kind:
3738
833
    case Interpolation_kind: {
3739
833
        location loc = LOC(e);
3740
833
        return _PyCompile_Warn(c, loc, "'%.200s' object is not callable; "
3741
833
                                       "perhaps you missed a comma?",
3742
833
                                       infer_type(e)->tp_name);
3743
833
    }
3744
817
    default:
3745
817
        return SUCCESS;
3746
1.65k
    }
3747
1.65k
}
3748
3749
static int
3750
check_subscripter(compiler *c, expr_ty e)
3751
1.95k
{
3752
1.95k
    PyObject *v;
3753
3754
1.95k
    switch (e->kind) {
3755
1.58k
    case Constant_kind:
3756
1.58k
        v = e->v.Constant.value;
3757
1.58k
        if (!(v == Py_None || v == Py_Ellipsis ||
3758
1.58k
              PyLong_Check(v) || PyFloat_Check(v) || PyComplex_Check(v) ||
3759
1.54k
              PyAnySet_Check(v)))
3760
1.54k
        {
3761
1.54k
            return SUCCESS;
3762
1.54k
        }
3763
35
        _Py_FALLTHROUGH;
3764
35
    case Set_kind:
3765
35
    case SetComp_kind:
3766
35
    case GeneratorExp_kind:
3767
43
    case TemplateStr_kind:
3768
43
    case Interpolation_kind:
3769
43
    case Lambda_kind: {
3770
43
        location loc = LOC(e);
3771
43
        return _PyCompile_Warn(c, loc, "'%.200s' object is not subscriptable; "
3772
43
                                       "perhaps you missed a comma?",
3773
43
                                       infer_type(e)->tp_name);
3774
43
    }
3775
366
    default:
3776
366
        return SUCCESS;
3777
1.95k
    }
3778
1.95k
}
3779
3780
static int
3781
check_index(compiler *c, expr_ty e, expr_ty s)
3782
1.95k
{
3783
1.95k
    PyObject *v;
3784
3785
1.95k
    PyTypeObject *index_type = infer_type(s);
3786
1.95k
    if (index_type == NULL
3787
325
        || PyType_FastSubclass(index_type, Py_TPFLAGS_LONG_SUBCLASS)
3788
1.70k
        || index_type == &PySlice_Type) {
3789
1.70k
        return SUCCESS;
3790
1.70k
    }
3791
3792
254
    switch (e->kind) {
3793
38
    case Constant_kind:
3794
38
        v = e->v.Constant.value;
3795
38
        if (!(PyUnicode_Check(v) || PyBytes_Check(v) || PyTuple_Check(v))) {
3796
26
            return SUCCESS;
3797
26
        }
3798
12
        _Py_FALLTHROUGH;
3799
30
    case Tuple_kind:
3800
42
    case List_kind:
3801
42
    case ListComp_kind:
3802
42
    case JoinedStr_kind:
3803
42
    case FormattedValue_kind: {
3804
42
        location loc = LOC(e);
3805
42
        return _PyCompile_Warn(c, loc, "%.200s indices must be integers "
3806
42
                                       "or slices, not %.200s; "
3807
42
                                       "perhaps you missed a comma?",
3808
42
                                       infer_type(e)->tp_name,
3809
42
                                       index_type->tp_name);
3810
42
    }
3811
186
    default:
3812
186
        return SUCCESS;
3813
254
    }
3814
254
}
3815
3816
static int
3817
is_import_originated(compiler *c, expr_ty e)
3818
875
{
3819
    /* Check whether the global scope has an import named
3820
     e, if it is a Name object. For not traversing all the
3821
     scope stack every time this function is called, it will
3822
     only check the global scope to determine whether something
3823
     is imported or not. */
3824
3825
875
    if (e->kind != Name_kind) {
3826
869
        return 0;
3827
869
    }
3828
3829
6
    long flags = _PyST_GetSymbol(SYMTABLE(c)->st_top, e->v.Name.id);
3830
6
    RETURN_IF_ERROR(flags);
3831
6
    return flags & DEF_IMPORT;
3832
6
}
3833
3834
static int
3835
can_optimize_super_call(compiler *c, expr_ty attr)
3836
3.79k
{
3837
3.79k
    expr_ty e = attr->v.Attribute.value;
3838
3.79k
    if (e->kind != Call_kind ||
3839
2.05k
        e->v.Call.func->kind != Name_kind ||
3840
596
        !_PyUnicode_EqualToASCIIString(e->v.Call.func->v.Name.id, "super") ||
3841
217
        _PyUnicode_EqualToASCIIString(attr->v.Attribute.attr, "__class__") ||
3842
3.58k
        asdl_seq_LEN(e->v.Call.keywords) != 0) {
3843
3.58k
        return 0;
3844
3.58k
    }
3845
217
    Py_ssize_t num_args = asdl_seq_LEN(e->v.Call.args);
3846
3847
217
    PyObject *super_name = e->v.Call.func->v.Name.id;
3848
    // detect statically-visible shadowing of 'super' name
3849
217
    int scope = _PyST_GetScope(SYMTABLE_ENTRY(c), super_name);
3850
217
    RETURN_IF_ERROR(scope);
3851
217
    if (scope != GLOBAL_IMPLICIT) {
3852
5
        return 0;
3853
5
    }
3854
212
    scope = _PyST_GetScope(SYMTABLE(c)->st_top, super_name);
3855
212
    RETURN_IF_ERROR(scope);
3856
212
    if (scope != 0) {
3857
15
        return 0;
3858
15
    }
3859
3860
197
    if (num_args == 2) {
3861
588
        for (Py_ssize_t i = 0; i < num_args; i++) {
3862
392
            expr_ty elt = asdl_seq_GET(e->v.Call.args, i);
3863
392
            if (elt->kind == Starred_kind) {
3864
0
                return 0;
3865
0
            }
3866
392
        }
3867
        // exactly two non-starred args; we can just load
3868
        // the provided args
3869
196
        return 1;
3870
196
    }
3871
3872
1
    if (num_args != 0) {
3873
1
        return 0;
3874
1
    }
3875
    // we need the following for zero-arg super():
3876
3877
    // enclosing function should have at least one argument
3878
0
    if (METADATA(c)->u_argcount == 0 &&
3879
0
        METADATA(c)->u_posonlyargcount == 0) {
3880
0
        return 0;
3881
0
    }
3882
    // __class__ cell should be available
3883
0
    if (_PyCompile_GetRefType(c, &_Py_ID(__class__)) == FREE) {
3884
0
        return 1;
3885
0
    }
3886
0
    return 0;
3887
0
}
3888
3889
static int
3890
196
load_args_for_super(compiler *c, expr_ty e) {
3891
196
    location loc = LOC(e);
3892
3893
    // load super() global
3894
196
    PyObject *super_name = e->v.Call.func->v.Name.id;
3895
196
    RETURN_IF_ERROR(codegen_nameop(c, LOC(e->v.Call.func), super_name, Load));
3896
3897
196
    if (asdl_seq_LEN(e->v.Call.args) == 2) {
3898
196
        VISIT(c, expr, asdl_seq_GET(e->v.Call.args, 0));
3899
196
        VISIT(c, expr, asdl_seq_GET(e->v.Call.args, 1));
3900
196
        return SUCCESS;
3901
196
    }
3902
3903
    // load __class__ cell
3904
0
    PyObject *name = &_Py_ID(__class__);
3905
0
    assert(_PyCompile_GetRefType(c, name) == FREE);
3906
0
    RETURN_IF_ERROR(codegen_nameop(c, loc, name, Load));
3907
3908
    // load self (first argument)
3909
0
    Py_ssize_t i = 0;
3910
0
    PyObject *key, *value;
3911
0
    if (!PyDict_Next(METADATA(c)->u_varnames, &i, &key, &value)) {
3912
0
        return ERROR;
3913
0
    }
3914
0
    RETURN_IF_ERROR(codegen_nameop(c, loc, key, Load));
3915
3916
0
    return SUCCESS;
3917
0
}
3918
3919
// If an attribute access spans multiple lines, update the current start
3920
// location to point to the attribute name.
3921
static location
3922
update_start_location_to_match_attr(compiler *c, location loc,
3923
                                    expr_ty attr)
3924
4.67k
{
3925
4.67k
    assert(attr->kind == Attribute_kind);
3926
4.67k
    if (loc.lineno != attr->end_lineno) {
3927
1.54k
        loc.lineno = attr->end_lineno;
3928
1.54k
        int len = (int)PyUnicode_GET_LENGTH(attr->v.Attribute.attr);
3929
1.54k
        if (len <= attr->end_col_offset) {
3930
1.54k
            loc.col_offset = attr->end_col_offset - len;
3931
1.54k
        }
3932
0
        else {
3933
            // GH-94694: Somebody's compiling weird ASTs. Just drop the columns:
3934
0
            loc.col_offset = -1;
3935
0
            loc.end_col_offset = -1;
3936
0
        }
3937
        // Make sure the end position still follows the start position, even for
3938
        // weird ASTs:
3939
1.54k
        loc.end_lineno = Py_MAX(loc.lineno, loc.end_lineno);
3940
1.54k
        if (loc.lineno == loc.end_lineno) {
3941
939
            loc.end_col_offset = Py_MAX(loc.col_offset, loc.end_col_offset);
3942
939
        }
3943
1.54k
    }
3944
4.67k
    return loc;
3945
4.67k
}
3946
3947
static int
3948
maybe_optimize_function_call(compiler *c, expr_ty e, jump_target_label end)
3949
1.65k
{
3950
1.65k
    asdl_expr_seq *args = e->v.Call.args;
3951
1.65k
    asdl_keyword_seq *kwds = e->v.Call.keywords;
3952
1.65k
    expr_ty func = e->v.Call.func;
3953
3954
1.65k
    if (! (func->kind == Name_kind &&
3955
649
           asdl_seq_LEN(args) == 1 &&
3956
189
           asdl_seq_LEN(kwds) == 0))
3957
1.49k
    {
3958
1.49k
        return 0;
3959
1.49k
    }
3960
3961
152
    location loc = LOC(func);
3962
3963
152
    expr_ty arg_expr = asdl_seq_GET(args, 0);
3964
3965
152
    if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "frozenset")
3966
0
        && (arg_expr->kind == Set_kind || arg_expr->kind == SetComp_kind)) {
3967
0
        NEW_JUMP_TARGET_LABEL(c, skip_optimization);
3968
3969
0
        ADDOP_I(c, loc, COPY, 1);
3970
0
        ADDOP_I(c, loc, LOAD_COMMON_CONSTANT, CONSTANT_BUILTIN_FROZENSET);
3971
0
        ADDOP_COMPARE(c, loc, Is);
3972
0
        ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, skip_optimization);
3973
0
        ADDOP(c, loc, POP_TOP);
3974
3975
0
        VISIT(c, expr, arg_expr);
3976
0
        ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_BUILD_FROZENSET);
3977
3978
0
        ADDOP_JUMP(c, loc, JUMP, end);
3979
3980
0
        USE_LABEL(c, skip_optimization);
3981
0
        return 1;
3982
0
    }
3983
3984
152
    if (arg_expr->kind != GeneratorExp_kind) {
3985
151
        return 0;
3986
151
    }
3987
3988
1
    PySTEntryObject *generator_entry = _PySymtable_Lookup(SYMTABLE(c), (void *)arg_expr);
3989
1
    if (generator_entry->ste_coroutine) {
3990
0
        Py_DECREF(generator_entry);
3991
0
        return 0;
3992
0
    }
3993
1
    Py_DECREF(generator_entry);
3994
3995
1
    int optimized = 0;
3996
1
    NEW_JUMP_TARGET_LABEL(c, skip_optimization);
3997
3998
1
    int const_oparg = -1;
3999
1
    PyObject *initial_res = NULL;
4000
1
    int continue_jump_opcode = -1;
4001
1
    if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "all")) {
4002
0
        const_oparg = CONSTANT_BUILTIN_ALL;
4003
0
        initial_res = Py_True;
4004
0
        continue_jump_opcode = POP_JUMP_IF_TRUE;
4005
0
    }
4006
1
    else if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "any")) {
4007
0
        const_oparg = CONSTANT_BUILTIN_ANY;
4008
0
        initial_res = Py_False;
4009
0
        continue_jump_opcode = POP_JUMP_IF_FALSE;
4010
0
    }
4011
1
    else if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "tuple")) {
4012
0
        const_oparg = CONSTANT_BUILTIN_TUPLE;
4013
0
    }
4014
1
    else if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "list")) {
4015
0
        const_oparg = CONSTANT_BUILTIN_LIST;
4016
0
    }
4017
1
    else if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "set")) {
4018
0
        const_oparg = CONSTANT_BUILTIN_SET;
4019
0
    }
4020
1
    else if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "frozenset")) {
4021
0
        const_oparg = CONSTANT_BUILTIN_FROZENSET;
4022
0
    }
4023
1
    if (const_oparg != -1) {
4024
0
        ADDOP_I(c, loc, COPY, 1); // the function
4025
0
        ADDOP_I(c, loc, LOAD_COMMON_CONSTANT, const_oparg);
4026
0
        ADDOP_COMPARE(c, loc, Is);
4027
0
        ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, skip_optimization);
4028
0
        ADDOP(c, loc, POP_TOP);
4029
4030
0
        if (const_oparg == CONSTANT_BUILTIN_TUPLE || const_oparg == CONSTANT_BUILTIN_LIST) {
4031
0
            ADDOP_I(c, loc, BUILD_LIST, 0);
4032
0
        } else if (const_oparg == CONSTANT_BUILTIN_SET || const_oparg == CONSTANT_BUILTIN_FROZENSET) {
4033
0
            ADDOP_I(c, loc, BUILD_SET, 0);
4034
0
        }
4035
0
        VISIT(c, expr, arg_expr);
4036
4037
0
        NEW_JUMP_TARGET_LABEL(c, loop);
4038
0
        NEW_JUMP_TARGET_LABEL(c, cleanup);
4039
4040
0
        ADDOP(c, loc, PUSH_NULL); // Push NULL index for loop
4041
0
        USE_LABEL(c, loop);
4042
0
        ADDOP_JUMP(c, loc, FOR_ITER, cleanup);
4043
0
        if (const_oparg == CONSTANT_BUILTIN_TUPLE || const_oparg == CONSTANT_BUILTIN_LIST) {
4044
0
            ADDOP_I(c, loc, LIST_APPEND, 3);
4045
0
            ADDOP_JUMP(c, loc, JUMP, loop);
4046
0
        } else if (const_oparg == CONSTANT_BUILTIN_SET || const_oparg == CONSTANT_BUILTIN_FROZENSET) {
4047
0
            ADDOP_I(c, loc, SET_ADD, 3);
4048
0
            ADDOP_JUMP(c, loc, JUMP, loop);
4049
0
        }
4050
0
        else {
4051
0
            ADDOP(c, loc, TO_BOOL);
4052
0
            ADDOP_JUMP(c, loc, continue_jump_opcode, loop);
4053
0
        }
4054
4055
0
        ADDOP(c, NO_LOCATION, POP_ITER);
4056
0
        if (const_oparg != CONSTANT_BUILTIN_TUPLE &&
4057
0
            const_oparg != CONSTANT_BUILTIN_LIST &&
4058
0
            const_oparg != CONSTANT_BUILTIN_SET &&
4059
0
            const_oparg != CONSTANT_BUILTIN_FROZENSET) {
4060
0
            ADDOP_LOAD_CONST(c, loc, initial_res == Py_True ? Py_False : Py_True);
4061
0
        }
4062
0
        ADDOP_JUMP(c, loc, JUMP, end);
4063
4064
0
        USE_LABEL(c, cleanup);
4065
0
        ADDOP(c, NO_LOCATION, END_FOR);
4066
0
        ADDOP(c, NO_LOCATION, POP_ITER);
4067
0
        if (const_oparg == CONSTANT_BUILTIN_TUPLE) {
4068
0
            ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_LIST_TO_TUPLE);
4069
0
        } else if (const_oparg == CONSTANT_BUILTIN_LIST) {
4070
            // result is already a list
4071
0
        } else if (const_oparg == CONSTANT_BUILTIN_SET) {
4072
            // result is already a set
4073
0
        }
4074
0
        else if (const_oparg == CONSTANT_BUILTIN_FROZENSET) {
4075
0
            ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_BUILD_FROZENSET);
4076
0
        }
4077
0
        else {
4078
0
            ADDOP_LOAD_CONST(c, loc, initial_res);
4079
0
        }
4080
4081
0
        optimized = 1;
4082
0
        ADDOP_JUMP(c, loc, JUMP, end);
4083
0
    }
4084
1
    USE_LABEL(c, skip_optimization);
4085
1
    return optimized;
4086
1
}
4087
4088
// Return 1 if the method call was optimized, 0 if not, and -1 on error.
4089
static int
4090
maybe_optimize_method_call(compiler *c, expr_ty e)
4091
2.47k
{
4092
2.47k
    Py_ssize_t argsl, i, kwdsl;
4093
2.47k
    expr_ty meth = e->v.Call.func;
4094
2.47k
    asdl_expr_seq *args = e->v.Call.args;
4095
2.47k
    asdl_keyword_seq *kwds = e->v.Call.keywords;
4096
4097
    /* Check that the call node is an attribute access */
4098
2.47k
    if (meth->kind != Attribute_kind || meth->v.Attribute.ctx != Load) {
4099
1.60k
        return 0;
4100
1.60k
    }
4101
4102
    /* Check that the base object is not something that is imported */
4103
875
    int ret = is_import_originated(c, meth->v.Attribute.value);
4104
875
    RETURN_IF_ERROR(ret);
4105
875
    if (ret) {
4106
0
        return 0;
4107
0
    }
4108
4109
    /* Check that there aren't too many arguments */
4110
875
    argsl = asdl_seq_LEN(args);
4111
875
    kwdsl = asdl_seq_LEN(kwds);
4112
875
    if (argsl + kwdsl + (kwdsl != 0) >= _PY_STACK_USE_GUIDELINE) {
4113
0
        return 0;
4114
0
    }
4115
    /* Check that there are no *varargs types of arguments. */
4116
1.51k
    for (i = 0; i < argsl; i++) {
4117
653
        expr_ty elt = asdl_seq_GET(args, i);
4118
653
        if (elt->kind == Starred_kind) {
4119
11
            return 0;
4120
11
        }
4121
653
    }
4122
4123
874
    for (i = 0; i < kwdsl; i++) {
4124
45
        keyword_ty kw = asdl_seq_GET(kwds, i);
4125
45
        if (kw->arg == NULL) {
4126
35
            return 0;
4127
35
        }
4128
45
    }
4129
4130
    /* Alright, we can optimize the code. */
4131
829
    location loc = LOC(meth);
4132
4133
829
    ret = can_optimize_super_call(c, meth);
4134
829
    RETURN_IF_ERROR(ret);
4135
829
    if (ret) {
4136
7
        RETURN_IF_ERROR(load_args_for_super(c, meth->v.Attribute.value));
4137
7
        int opcode = asdl_seq_LEN(meth->v.Attribute.value->v.Call.args) ?
4138
7
            LOAD_SUPER_METHOD : LOAD_ZERO_SUPER_METHOD;
4139
7
        ADDOP_NAME(c, loc, opcode, meth->v.Attribute.attr, names);
4140
7
        loc = update_start_location_to_match_attr(c, loc, meth);
4141
7
        ADDOP(c, loc, NOP);
4142
822
    } else {
4143
822
        VISIT(c, expr, meth->v.Attribute.value);
4144
822
        loc = update_start_location_to_match_attr(c, loc, meth);
4145
822
        ADDOP_NAME(c, loc, LOAD_METHOD, meth->v.Attribute.attr, names);
4146
822
    }
4147
4148
829
    VISIT_SEQ(c, expr, e->v.Call.args);
4149
4150
828
    if (kwdsl) {
4151
4
        VISIT_SEQ(c, keyword, kwds);
4152
4
        RETURN_IF_ERROR(
4153
4
            codegen_call_simple_kw_helper(c, loc, kwds, kwdsl));
4154
4
        loc = update_start_location_to_match_attr(c, LOC(e), meth);
4155
4
        ADDOP_I(c, loc, CALL_KW, argsl + kwdsl);
4156
4
    }
4157
824
    else {
4158
824
        loc = update_start_location_to_match_attr(c, LOC(e), meth);
4159
824
        ADDOP_I(c, loc, CALL, argsl);
4160
824
    }
4161
828
    return 1;
4162
828
}
4163
4164
static int
4165
codegen_validate_keywords(compiler *c, asdl_keyword_seq *keywords)
4166
9.05k
{
4167
9.05k
    Py_ssize_t nkeywords = asdl_seq_LEN(keywords);
4168
9.36k
    for (Py_ssize_t i = 0; i < nkeywords; i++) {
4169
319
        keyword_ty key = ((keyword_ty)asdl_seq_GET(keywords, i));
4170
319
        if (key->arg == NULL) {
4171
176
            continue;
4172
176
        }
4173
217
        for (Py_ssize_t j = i + 1; j < nkeywords; j++) {
4174
86
            keyword_ty other = ((keyword_ty)asdl_seq_GET(keywords, j));
4175
86
            if (other->arg && !PyUnicode_Compare(key->arg, other->arg)) {
4176
12
                return _PyCompile_Error(c, LOC(other), "keyword argument repeated: %U", key->arg);
4177
12
            }
4178
86
        }
4179
143
    }
4180
9.04k
    return SUCCESS;
4181
9.05k
}
4182
4183
static int
4184
codegen_call(compiler *c, expr_ty e)
4185
2.49k
{
4186
2.49k
    RETURN_IF_ERROR(codegen_validate_keywords(c, e->v.Call.keywords));
4187
2.47k
    int ret = maybe_optimize_method_call(c, e);
4188
2.47k
    if (ret < 0) {
4189
1
        return ERROR;
4190
1
    }
4191
2.47k
    if (ret == 1) {
4192
828
        return SUCCESS;
4193
828
    }
4194
1.65k
    NEW_JUMP_TARGET_LABEL(c, skip_normal_call);
4195
1.65k
    RETURN_IF_ERROR(check_caller(c, e->v.Call.func));
4196
1.65k
    VISIT(c, expr, e->v.Call.func);
4197
1.65k
    RETURN_IF_ERROR(maybe_optimize_function_call(c, e, skip_normal_call));
4198
1.65k
    location loc = LOC(e->v.Call.func);
4199
1.65k
    ADDOP(c, loc, PUSH_NULL);
4200
1.65k
    loc = LOC(e);
4201
1.65k
    ret = codegen_call_helper(c, loc, 0,
4202
1.65k
                              e->v.Call.args,
4203
1.65k
                              e->v.Call.keywords);
4204
1.65k
    USE_LABEL(c, skip_normal_call);
4205
1.65k
    return ret;
4206
1.65k
}
4207
4208
static int
4209
codegen_template_str(compiler *c, expr_ty e)
4210
145
{
4211
145
    location loc = LOC(e);
4212
145
    expr_ty value;
4213
4214
145
    Py_ssize_t value_count = asdl_seq_LEN(e->v.TemplateStr.values);
4215
145
    int last_was_interpolation = 1;
4216
145
    Py_ssize_t stringslen = 0;
4217
361
    for (Py_ssize_t i = 0; i < value_count; i++) {
4218
216
        value = asdl_seq_GET(e->v.TemplateStr.values, i);
4219
216
        if (value->kind == Interpolation_kind) {
4220
102
            if (last_was_interpolation) {
4221
85
                ADDOP_LOAD_CONST(c, loc, Py_NewRef(&_Py_STR(empty)));
4222
85
                stringslen++;
4223
85
            }
4224
102
            last_was_interpolation = 1;
4225
102
        }
4226
114
        else {
4227
114
            VISIT(c, expr, value);
4228
114
            stringslen++;
4229
114
            last_was_interpolation = 0;
4230
114
        }
4231
216
    }
4232
145
    if (last_was_interpolation) {
4233
48
        ADDOP_LOAD_CONST(c, loc, Py_NewRef(&_Py_STR(empty)));
4234
48
        stringslen++;
4235
48
    }
4236
145
    ADDOP_I(c, loc, BUILD_TUPLE, stringslen);
4237
4238
145
    Py_ssize_t interpolationslen = 0;
4239
361
    for (Py_ssize_t i = 0; i < value_count; i++) {
4240
216
        value = asdl_seq_GET(e->v.TemplateStr.values, i);
4241
216
        if (value->kind == Interpolation_kind) {
4242
102
            VISIT(c, expr, value);
4243
102
            interpolationslen++;
4244
102
        }
4245
216
    }
4246
145
    ADDOP_I(c, loc, BUILD_TUPLE, interpolationslen);
4247
145
    ADDOP(c, loc, BUILD_TEMPLATE);
4248
145
    return SUCCESS;
4249
145
}
4250
4251
static int
4252
codegen_joined_str(compiler *c, expr_ty e)
4253
287
{
4254
287
    location loc = LOC(e);
4255
287
    Py_ssize_t value_count = asdl_seq_LEN(e->v.JoinedStr.values);
4256
287
    if (value_count > _PY_STACK_USE_GUIDELINE) {
4257
3
        _Py_DECLARE_STR(empty, "");
4258
3
        ADDOP_LOAD_CONST_NEW(c, loc, Py_NewRef(&_Py_STR(empty)));
4259
3
        ADDOP_NAME(c, loc, LOAD_METHOD, &_Py_ID(join), names);
4260
3
        ADDOP_I(c, loc, BUILD_LIST, 0);
4261
80
        for (Py_ssize_t i = 0; i < asdl_seq_LEN(e->v.JoinedStr.values); i++) {
4262
78
            VISIT(c, expr, asdl_seq_GET(e->v.JoinedStr.values, i));
4263
77
            ADDOP_I(c, loc, LIST_APPEND, 1);
4264
77
        }
4265
2
        ADDOP_I(c, loc, CALL, 1);
4266
2
    }
4267
284
    else {
4268
284
        VISIT_SEQ(c, expr, e->v.JoinedStr.values);
4269
273
        if (value_count > 1) {
4270
150
            ADDOP_I(c, loc, BUILD_STRING, value_count);
4271
150
        }
4272
123
        else if (value_count == 0) {
4273
68
            _Py_DECLARE_STR(empty, "");
4274
68
            ADDOP_LOAD_CONST_NEW(c, loc, Py_NewRef(&_Py_STR(empty)));
4275
68
        }
4276
273
    }
4277
275
    return SUCCESS;
4278
287
}
4279
4280
static int
4281
codegen_interpolation(compiler *c, expr_ty e)
4282
102
{
4283
102
    location loc = LOC(e);
4284
4285
102
    VISIT(c, expr, e->v.Interpolation.value);
4286
102
    ADDOP_LOAD_CONST(c, loc, e->v.Interpolation.str);
4287
4288
102
    int oparg = 2;
4289
102
    if (e->v.Interpolation.format_spec) {
4290
12
        oparg++;
4291
12
        VISIT(c, expr, e->v.Interpolation.format_spec);
4292
12
    }
4293
4294
102
    int conversion = e->v.Interpolation.conversion;
4295
102
    if (conversion != -1) {
4296
71
        switch (conversion) {
4297
0
        case 's': oparg |= FVC_STR << 2;   break;
4298
0
        case 'r': oparg |= FVC_REPR << 2;  break;
4299
71
        case 'a': oparg |= FVC_ASCII << 2; break;
4300
0
        default:
4301
0
            PyErr_Format(PyExc_SystemError,
4302
0
                     "Unrecognized conversion character %d", conversion);
4303
0
            return ERROR;
4304
71
        }
4305
71
    }
4306
4307
102
    ADDOP_I(c, loc, BUILD_INTERPOLATION, oparg);
4308
102
    return SUCCESS;
4309
102
}
4310
4311
/* Used to implement f-strings. Format a single value. */
4312
static int
4313
codegen_formatted_value(compiler *c, expr_ty e)
4314
243
{
4315
243
    int conversion = e->v.FormattedValue.conversion;
4316
243
    int oparg;
4317
4318
    /* The expression to be formatted. */
4319
243
    VISIT(c, expr, e->v.FormattedValue.value);
4320
4321
235
    location loc = LOC(e);
4322
235
    if (conversion != -1) {
4323
176
        switch (conversion) {
4324
41
        case 's': oparg = FVC_STR;   break;
4325
62
        case 'r': oparg = FVC_REPR;  break;
4326
73
        case 'a': oparg = FVC_ASCII; break;
4327
0
        default:
4328
0
            PyErr_Format(PyExc_SystemError,
4329
0
                     "Unrecognized conversion character %d", conversion);
4330
0
            return ERROR;
4331
176
        }
4332
176
        ADDOP_I(c, loc, CONVERT_VALUE, oparg);
4333
176
    }
4334
235
    if (e->v.FormattedValue.format_spec) {
4335
        /* Evaluate the format spec, and update our opcode arg. */
4336
60
        VISIT(c, expr, e->v.FormattedValue.format_spec);
4337
56
        ADDOP(c, loc, FORMAT_WITH_SPEC);
4338
175
    } else {
4339
175
        ADDOP(c, loc, FORMAT_SIMPLE);
4340
175
    }
4341
231
    return SUCCESS;
4342
235
}
4343
4344
static int
4345
codegen_subkwargs(compiler *c, location loc,
4346
                  asdl_keyword_seq *keywords,
4347
                  Py_ssize_t begin, Py_ssize_t end)
4348
11
{
4349
11
    Py_ssize_t i, n = end - begin;
4350
11
    keyword_ty kw;
4351
11
    assert(n > 0);
4352
11
    int big = n*2 > _PY_STACK_USE_GUIDELINE;
4353
11
    if (big) {
4354
0
        ADDOP_I(c, NO_LOCATION, BUILD_MAP, 0);
4355
0
    }
4356
22
    for (i = begin; i < end; i++) {
4357
11
        kw = asdl_seq_GET(keywords, i);
4358
11
        ADDOP_LOAD_CONST(c, loc, kw->arg);
4359
11
        VISIT(c, expr, kw->value);
4360
11
        if (big) {
4361
0
            ADDOP_I(c, NO_LOCATION, MAP_ADD, 1);
4362
0
        }
4363
11
    }
4364
11
    if (!big) {
4365
11
        ADDOP_I(c, loc, BUILD_MAP, n);
4366
11
    }
4367
11
    return SUCCESS;
4368
11
}
4369
4370
/* Used by codegen_call_helper and maybe_optimize_method_call to emit
4371
 * a tuple of keyword names before CALL.
4372
 */
4373
static int
4374
codegen_call_simple_kw_helper(compiler *c, location loc,
4375
                              asdl_keyword_seq *keywords, Py_ssize_t nkwelts)
4376
49
{
4377
49
    PyObject *names;
4378
49
    names = PyTuple_New(nkwelts);
4379
49
    if (names == NULL) {
4380
0
        return ERROR;
4381
0
    }
4382
106
    for (Py_ssize_t i = 0; i < nkwelts; i++) {
4383
57
        keyword_ty kw = asdl_seq_GET(keywords, i);
4384
57
        PyTuple_SET_ITEM(names, i, Py_NewRef(kw->arg));
4385
57
    }
4386
49
    ADDOP_LOAD_CONST_NEW(c, loc, names);
4387
49
    return SUCCESS;
4388
49
}
4389
4390
/* shared code between codegen_call and codegen_class */
4391
static int
4392
codegen_call_helper_impl(compiler *c, location loc,
4393
                         int n, /* Args already pushed */
4394
                         asdl_expr_seq *args,
4395
                         PyObject *injected_arg,
4396
                         asdl_keyword_seq *keywords)
4397
6.56k
{
4398
6.56k
    Py_ssize_t i, nseen, nelts, nkwelts;
4399
4400
6.56k
    RETURN_IF_ERROR(codegen_validate_keywords(c, keywords));
4401
4402
6.56k
    nelts = asdl_seq_LEN(args);
4403
6.56k
    nkwelts = asdl_seq_LEN(keywords);
4404
4405
6.56k
    if (nelts + nkwelts*2 > _PY_STACK_USE_GUIDELINE) {
4406
0
         goto ex_call;
4407
0
    }
4408
7.78k
    for (i = 0; i < nelts; i++) {
4409
1.52k
        expr_ty elt = asdl_seq_GET(args, i);
4410
1.52k
        if (elt->kind == Starred_kind) {
4411
296
            goto ex_call;
4412
296
        }
4413
1.52k
    }
4414
6.32k
    for (i = 0; i < nkwelts; i++) {
4415
131
        keyword_ty kw = asdl_seq_GET(keywords, i);
4416
131
        if (kw->arg == NULL) {
4417
78
            goto ex_call;
4418
78
        }
4419
131
    }
4420
4421
    /* No * or ** args, so can use faster calling sequence */
4422
7.33k
    for (i = 0; i < nelts; i++) {
4423
1.14k
        expr_ty elt = asdl_seq_GET(args, i);
4424
1.14k
        assert(elt->kind != Starred_kind);
4425
1.14k
        VISIT(c, expr, elt);
4426
1.14k
    }
4427
6.18k
    if (injected_arg) {
4428
135
        RETURN_IF_ERROR(codegen_nameop(c, loc, injected_arg, Load));
4429
135
        nelts++;
4430
135
    }
4431
6.18k
    if (nkwelts) {
4432
45
        VISIT_SEQ(c, keyword, keywords);
4433
45
        RETURN_IF_ERROR(
4434
45
            codegen_call_simple_kw_helper(c, loc, keywords, nkwelts));
4435
45
        ADDOP_I(c, loc, CALL_KW, n + nelts + nkwelts);
4436
45
    }
4437
6.14k
    else {
4438
6.14k
        ADDOP_I(c, loc, CALL, n + nelts);
4439
6.14k
    }
4440
6.18k
    return SUCCESS;
4441
4442
374
ex_call:
4443
4444
    /* Do positional arguments. */
4445
374
    if (n == 0 && nelts == 1 && ((expr_ty)asdl_seq_GET(args, 0))->kind == Starred_kind) {
4446
26
        VISIT(c, expr, ((expr_ty)asdl_seq_GET(args, 0))->v.Starred.value);
4447
26
    }
4448
348
    else {
4449
348
        RETURN_IF_ERROR(starunpack_helper_impl(c, loc, args, injected_arg, n,
4450
348
                                               BUILD_LIST, LIST_APPEND, LIST_EXTEND, 1));
4451
348
    }
4452
    /* Then keyword arguments */
4453
374
    if (nkwelts) {
4454
        /* Has a new dict been pushed */
4455
78
        int have_dict = 0;
4456
4457
78
        nseen = 0;  /* the number of keyword arguments on the stack following */
4458
177
        for (i = 0; i < nkwelts; i++) {
4459
99
            keyword_ty kw = asdl_seq_GET(keywords, i);
4460
99
            if (kw->arg == NULL) {
4461
                /* A keyword argument unpacking. */
4462
88
                if (nseen) {
4463
7
                    RETURN_IF_ERROR(codegen_subkwargs(c, loc, keywords, i - nseen, i));
4464
7
                    if (have_dict) {
4465
1
                        ADDOP_I(c, loc, DICT_MERGE, 1);
4466
1
                    }
4467
7
                    have_dict = 1;
4468
7
                    nseen = 0;
4469
7
                }
4470
88
                if (!have_dict) {
4471
72
                    ADDOP_I(c, loc, BUILD_MAP, 0);
4472
72
                    have_dict = 1;
4473
72
                }
4474
88
                VISIT(c, expr, kw->value);
4475
88
                ADDOP_I(c, loc, DICT_MERGE, 1);
4476
88
            }
4477
11
            else {
4478
11
                nseen++;
4479
11
            }
4480
99
        }
4481
78
        if (nseen) {
4482
            /* Pack up any trailing keyword arguments. */
4483
4
            RETURN_IF_ERROR(codegen_subkwargs(c, loc, keywords, nkwelts - nseen, nkwelts));
4484
4
            if (have_dict) {
4485
4
                ADDOP_I(c, loc, DICT_MERGE, 1);
4486
4
            }
4487
4
            have_dict = 1;
4488
4
        }
4489
78
        assert(have_dict);
4490
78
    }
4491
374
    if (nkwelts == 0) {
4492
296
        ADDOP(c, loc, PUSH_NULL);
4493
296
    }
4494
374
    ADDOP(c, loc, CALL_FUNCTION_EX);
4495
374
    return SUCCESS;
4496
374
}
4497
4498
static int
4499
codegen_call_helper(compiler *c, location loc,
4500
                    int n, /* Args already pushed */
4501
                    asdl_expr_seq *args,
4502
                    asdl_keyword_seq *keywords)
4503
6.42k
{
4504
6.42k
    return codegen_call_helper_impl(c, loc, n, args, NULL, keywords);
4505
6.42k
}
4506
4507
/* List and set comprehensions work by being inlined at the location where
4508
  they are defined. The isolation of iteration variables is provided by
4509
  pushing/popping clashing locals on the stack. Generator expressions work
4510
  by creating a nested function to perform the actual iteration.
4511
  This means that the iteration variables don't leak into the current scope.
4512
  See https://peps.python.org/pep-0709/ for additional information.
4513
  The defined function is called immediately following its definition, with the
4514
  result of that call being the result of the expression.
4515
  The LC/SC version returns the populated container, while the GE version is
4516
  flagged in symtable.c as a generator, so it returns the generator object
4517
  when the function is called.
4518
4519
  Possible cleanups:
4520
    - iterate over the generator sequence instead of using recursion
4521
*/
4522
4523
4524
static int
4525
codegen_comprehension_generator(compiler *c, location loc,
4526
                                asdl_comprehension_seq *generators, int gen_index,
4527
                                int depth,
4528
                                expr_ty elt, expr_ty val, int type,
4529
                                IterStackPosition iter_pos)
4530
505
{
4531
505
    comprehension_ty gen;
4532
505
    gen = (comprehension_ty)asdl_seq_GET(generators, gen_index);
4533
505
    if (gen->is_async) {
4534
245
        return codegen_async_comprehension_generator(
4535
245
            c, loc, generators, gen_index, depth, elt, val, type,
4536
245
            iter_pos);
4537
260
    } else {
4538
260
        return codegen_sync_comprehension_generator(
4539
260
            c, loc, generators, gen_index, depth, elt, val, type,
4540
260
            iter_pos);
4541
260
    }
4542
505
}
4543
4544
static int
4545
codegen_sync_comprehension_generator(compiler *c, location loc,
4546
                                     asdl_comprehension_seq *generators,
4547
                                     int gen_index, int depth,
4548
                                     expr_ty elt, expr_ty val, int type,
4549
                                     IterStackPosition iter_pos)
4550
260
{
4551
    /* generate code for the iterator, then each of the ifs,
4552
       and then write to the element */
4553
4554
260
    NEW_JUMP_TARGET_LABEL(c, start);
4555
260
    NEW_JUMP_TARGET_LABEL(c, if_cleanup);
4556
260
    NEW_JUMP_TARGET_LABEL(c, anchor);
4557
4558
260
    comprehension_ty gen = (comprehension_ty)asdl_seq_GET(generators,
4559
260
                                                          gen_index);
4560
4561
260
    if (iter_pos == ITERABLE_IN_LOCAL) {
4562
9
        if (gen_index == 0) {
4563
0
            assert(METADATA(c)->u_argcount == 1);
4564
0
            ADDOP_I(c, loc, LOAD_FAST, 0);
4565
0
        }
4566
9
        else {
4567
            /* Sub-iter - calculate on the fly */
4568
            /* Fast path for the temporary variable assignment idiom:
4569
                for y in [f(x)]
4570
            */
4571
9
            asdl_expr_seq *elts;
4572
9
            switch (gen->iter->kind) {
4573
0
                case List_kind:
4574
0
                    elts = gen->iter->v.List.elts;
4575
0
                    break;
4576
0
                case Tuple_kind:
4577
0
                    elts = gen->iter->v.Tuple.elts;
4578
0
                    break;
4579
9
                default:
4580
9
                    elts = NULL;
4581
9
            }
4582
9
            if (asdl_seq_LEN(elts) == 1) {
4583
0
                expr_ty elt = asdl_seq_GET(elts, 0);
4584
0
                if (elt->kind != Starred_kind) {
4585
0
                    VISIT(c, expr, elt);
4586
0
                    start = NO_LABEL;
4587
0
                }
4588
0
            }
4589
9
            if (IS_JUMP_TARGET_LABEL(start)) {
4590
9
                VISIT(c, expr, gen->iter);
4591
9
            }
4592
9
        }
4593
9
    }
4594
4595
260
    if (IS_JUMP_TARGET_LABEL(start)) {
4596
260
        if (iter_pos != ITERATOR_ON_STACK) {
4597
257
            ADDOP_I(c, LOC(gen->iter), GET_ITER, 0);
4598
257
            depth += 1;
4599
257
        }
4600
260
        USE_LABEL(c, start);
4601
260
        depth += 1;
4602
260
        ADDOP_JUMP(c, LOC(gen->iter), FOR_ITER, anchor);
4603
260
    }
4604
260
    VISIT(c, expr, gen->target);
4605
4606
    /* XXX this needs to be cleaned up...a lot! */
4607
260
    Py_ssize_t n = asdl_seq_LEN(gen->ifs);
4608
330
    for (Py_ssize_t i = 0; i < n; i++) {
4609
70
        expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i);
4610
70
        RETURN_IF_ERROR(codegen_jump_if(c, loc, e, if_cleanup, 0));
4611
70
    }
4612
4613
260
    if (++gen_index < asdl_seq_LEN(generators)) {
4614
11
        RETURN_IF_ERROR(
4615
11
            codegen_comprehension_generator(c, loc,
4616
11
                                            generators, gen_index, depth,
4617
11
                                            elt, val, type, ITERABLE_IN_LOCAL));
4618
11
    }
4619
4620
260
    location elt_loc = LOC(elt);
4621
4622
    /* only append after the last for generator */
4623
260
    if (gen_index >= asdl_seq_LEN(generators)) {
4624
        /* comprehension specific code */
4625
249
        switch (type) {
4626
3
        case COMP_GENEXP:
4627
3
            if (elt->kind == Starred_kind) {
4628
0
                NEW_JUMP_TARGET_LABEL(c, unpack_start);
4629
0
                NEW_JUMP_TARGET_LABEL(c, unpack_end);
4630
0
                VISIT(c, expr, elt->v.Starred.value);
4631
0
                ADDOP_I(c, elt_loc, GET_ITER, 0);
4632
0
                USE_LABEL(c, unpack_start);
4633
0
                ADDOP_JUMP(c, elt_loc, FOR_ITER, unpack_end);
4634
0
                ADDOP_YIELD(c, elt_loc);
4635
0
                ADDOP(c, elt_loc, POP_TOP);
4636
0
                ADDOP_JUMP(c, NO_LOCATION, JUMP, unpack_start);
4637
0
                USE_LABEL(c, unpack_end);
4638
0
                ADDOP(c, NO_LOCATION, END_FOR);
4639
0
                ADDOP(c, NO_LOCATION, POP_ITER);
4640
0
            }
4641
3
            else {
4642
3
                VISIT(c, expr, elt);
4643
3
                ADDOP_YIELD(c, elt_loc);
4644
3
                ADDOP(c, elt_loc, POP_TOP);
4645
3
            }
4646
3
            break;
4647
3
        case COMP_LISTCOMP:
4648
1
            if (elt->kind == Starred_kind) {
4649
0
                VISIT(c, expr, elt->v.Starred.value);
4650
0
                ADDOP_I(c, elt_loc, LIST_EXTEND, depth + 1);
4651
0
            }
4652
1
            else {
4653
1
                VISIT(c, expr, elt);
4654
1
                ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1);
4655
1
            }
4656
1
            break;
4657
236
        case COMP_SETCOMP:
4658
236
            if (elt->kind == Starred_kind) {
4659
1
                VISIT(c, expr, elt->v.Starred.value);
4660
1
                ADDOP_I(c, elt_loc, SET_UPDATE, depth + 1);
4661
1
            }
4662
235
            else {
4663
235
                VISIT(c, expr, elt);
4664
235
                ADDOP_I(c, elt_loc, SET_ADD, depth + 1);
4665
235
            }
4666
236
            break;
4667
236
        case COMP_DICTCOMP:
4668
9
            if (val == NULL) {
4669
                /* unpacking (**) case */
4670
3
                VISIT(c, expr, elt);
4671
3
                ADDOP_I(c, elt_loc, DICT_UPDATE, depth+1);
4672
3
            }
4673
6
            else {
4674
                /* With '{k: v}', k is evaluated before v, so we do
4675
                the same. */
4676
6
                VISIT(c, expr, elt);
4677
6
                VISIT(c, expr, val);
4678
6
                elt_loc = LOCATION(elt->lineno,
4679
6
                                   val->end_lineno,
4680
6
                                   elt->col_offset,
4681
6
                                   val->end_col_offset);
4682
6
                ADDOP_I(c, elt_loc, MAP_ADD, depth + 1);
4683
6
            }
4684
9
            break;
4685
9
        default:
4686
0
            return ERROR;
4687
249
        }
4688
249
    }
4689
4690
260
    USE_LABEL(c, if_cleanup);
4691
260
    if (IS_JUMP_TARGET_LABEL(start)) {
4692
260
        ADDOP_JUMP(c, elt_loc, JUMP, start);
4693
4694
260
        USE_LABEL(c, anchor);
4695
        /* It is important for instrumentation that the `END_FOR` comes first.
4696
        * Iteration over a generator will jump to the first of these instructions,
4697
        * but a non-generator will jump to a later instruction.
4698
        */
4699
260
        ADDOP(c, NO_LOCATION, END_FOR);
4700
260
        ADDOP(c, NO_LOCATION, POP_ITER);
4701
260
    }
4702
4703
260
    return SUCCESS;
4704
260
}
4705
4706
static int
4707
codegen_async_comprehension_generator(compiler *c, location loc,
4708
                                      asdl_comprehension_seq *generators,
4709
                                      int gen_index, int depth,
4710
                                      expr_ty elt, expr_ty val, int type,
4711
                                      IterStackPosition iter_pos)
4712
245
{
4713
245
    NEW_JUMP_TARGET_LABEL(c, start);
4714
245
    NEW_JUMP_TARGET_LABEL(c, send);
4715
245
    NEW_JUMP_TARGET_LABEL(c, except);
4716
245
    NEW_JUMP_TARGET_LABEL(c, if_cleanup);
4717
4718
245
    comprehension_ty gen = (comprehension_ty)asdl_seq_GET(generators,
4719
245
                                                          gen_index);
4720
4721
245
    if (iter_pos == ITERABLE_IN_LOCAL) {
4722
3
        if (gen_index == 0) {
4723
0
            assert(METADATA(c)->u_argcount == 1);
4724
0
            ADDOP_I(c, loc, LOAD_FAST, 0);
4725
0
        }
4726
3
        else {
4727
            /* Sub-iter - calculate on the fly */
4728
3
            VISIT(c, expr, gen->iter);
4729
3
        }
4730
3
    }
4731
245
    if (iter_pos != ITERATOR_ON_STACK) {
4732
242
        ADDOP(c, LOC(gen->iter), GET_AITER);
4733
242
    }
4734
4735
245
    USE_LABEL(c, start);
4736
    /* Runtime will push a block here, so we need to account for that */
4737
245
    RETURN_IF_ERROR(
4738
245
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_ASYNC_COMPREHENSION_GENERATOR,
4739
245
                              start, NO_LABEL, NULL));
4740
4741
245
    ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
4742
245
    ADDOP(c, loc, GET_ANEXT);
4743
245
    ADDOP(c, loc, PUSH_NULL);
4744
245
    ADDOP_LOAD_CONST(c, loc, Py_None);
4745
245
    USE_LABEL(c, send);
4746
245
    ADD_YIELD_FROM(c, loc, 1);
4747
245
    ADDOP(c, loc, POP_BLOCK);
4748
245
    VISIT(c, expr, gen->target);
4749
4750
244
    Py_ssize_t n = asdl_seq_LEN(gen->ifs);
4751
244
    for (Py_ssize_t i = 0; i < n; i++) {
4752
0
        expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i);
4753
0
        RETURN_IF_ERROR(codegen_jump_if(c, loc, e, if_cleanup, 0));
4754
0
    }
4755
4756
244
    depth++;
4757
244
    if (++gen_index < asdl_seq_LEN(generators)) {
4758
1
        RETURN_IF_ERROR(
4759
1
            codegen_comprehension_generator(c, loc,
4760
1
                                            generators, gen_index, depth,
4761
1
                                            elt, val, type, 0));
4762
1
    }
4763
4764
244
    location elt_loc = LOC(elt);
4765
    /* only append after the last for generator */
4766
244
    if (gen_index >= asdl_seq_LEN(generators)) {
4767
        /* comprehension specific code */
4768
243
        switch (type) {
4769
2
        case COMP_GENEXP:
4770
2
            if (elt->kind == Starred_kind) {
4771
0
                NEW_JUMP_TARGET_LABEL(c, unpack_start);
4772
0
                NEW_JUMP_TARGET_LABEL(c, unpack_end);
4773
0
                VISIT(c, expr, elt->v.Starred.value);
4774
0
                ADDOP_I(c, elt_loc, GET_ITER, 0);
4775
0
                USE_LABEL(c, unpack_start);
4776
0
                ADDOP_JUMP(c, elt_loc, FOR_ITER, unpack_end);
4777
0
                ADDOP_YIELD(c, elt_loc);
4778
0
                ADDOP(c, elt_loc, POP_TOP);
4779
0
                ADDOP_JUMP(c, NO_LOCATION, JUMP, unpack_start);
4780
0
                USE_LABEL(c, unpack_end);
4781
0
                ADDOP(c, NO_LOCATION, END_FOR);
4782
0
                ADDOP(c, NO_LOCATION, POP_ITER);
4783
0
            }
4784
2
            else {
4785
2
                VISIT(c, expr, elt);
4786
2
                ADDOP_YIELD(c, elt_loc);
4787
2
                ADDOP(c, elt_loc, POP_TOP);
4788
2
            }
4789
2
            break;
4790
2
        case COMP_LISTCOMP:
4791
0
            if (elt->kind == Starred_kind) {
4792
0
                VISIT(c, expr, elt->v.Starred.value);
4793
0
                ADDOP_I(c, elt_loc, LIST_EXTEND, depth + 1);
4794
0
            }
4795
0
            else {
4796
0
                VISIT(c, expr, elt);
4797
0
                ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1);
4798
0
            }
4799
0
            break;
4800
136
        case COMP_SETCOMP:
4801
136
            if (elt->kind == Starred_kind) {
4802
1
                VISIT(c, expr, elt->v.Starred.value);
4803
1
                ADDOP_I(c, elt_loc, SET_UPDATE, depth + 1);
4804
1
            }
4805
135
            else {
4806
135
                VISIT(c, expr, elt);
4807
135
                ADDOP_I(c, elt_loc, SET_ADD, depth + 1);
4808
135
            }
4809
136
            break;
4810
136
        case COMP_DICTCOMP:
4811
105
            if (val == NULL) {
4812
                /* unpacking (**) case */
4813
88
                VISIT(c, expr, elt);
4814
88
                ADDOP_I(c, elt_loc, DICT_UPDATE, depth+1);
4815
88
            }
4816
17
            else {
4817
                /* With '{k: v}', k is evaluated before v, so we do
4818
                the same. */
4819
17
                VISIT(c, expr, elt);
4820
17
                VISIT(c, expr, val);
4821
17
                elt_loc = LOCATION(elt->lineno,
4822
17
                                   val->end_lineno,
4823
17
                                   elt->col_offset,
4824
17
                                   val->end_col_offset);
4825
17
                ADDOP_I(c, elt_loc, MAP_ADD, depth + 1);
4826
17
            }
4827
105
            break;
4828
105
        default:
4829
0
            return ERROR;
4830
243
        }
4831
243
    }
4832
4833
244
    USE_LABEL(c, if_cleanup);
4834
244
    ADDOP_JUMP(c, elt_loc, JUMP, start);
4835
4836
244
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_ASYNC_COMPREHENSION_GENERATOR, start);
4837
4838
244
    USE_LABEL(c, except);
4839
4840
244
    ADDOP_JUMP(c, loc, END_ASYNC_FOR, send);
4841
4842
244
    return SUCCESS;
4843
244
}
4844
4845
static int
4846
codegen_push_inlined_comprehension_locals(compiler *c, location loc,
4847
                                          PySTEntryObject *comp,
4848
                                          _PyCompile_InlinedComprehensionState *state)
4849
487
{
4850
487
    int in_class_block = (SYMTABLE_ENTRY(c)->ste_type == ClassBlock) &&
4851
2
                          !_PyCompile_IsInInlinedComp(c);
4852
487
    PySTEntryObject *outer = SYMTABLE_ENTRY(c);
4853
    // iterate over names bound in the comprehension and ensure we isolate
4854
    // them from the outer scope as needed
4855
487
    PyObject *k, *v;
4856
487
    Py_ssize_t pos = 0;
4857
2.31k
    while (PyDict_Next(comp->ste_symbols, &pos, &k, &v)) {
4858
1.83k
        long symbol = PyLong_AsLong(v);
4859
1.83k
        assert(symbol >= 0 || PyErr_Occurred());
4860
1.83k
        RETURN_IF_ERROR(symbol);
4861
1.83k
        long scope = SYMBOL_TO_SCOPE(symbol);
4862
4863
1.83k
        long outsymbol = _PyST_GetSymbol(outer, k);
4864
1.83k
        RETURN_IF_ERROR(outsymbol);
4865
1.83k
        long outsc = SYMBOL_TO_SCOPE(outsymbol);
4866
4867
1.83k
        if ((symbol & DEF_LOCAL && !(symbol & DEF_NONLOCAL)) || in_class_block) {
4868
            // local names bound in comprehension must be isolated from
4869
            // outer scope; push existing value (which may be NULL if
4870
            // not defined) on stack
4871
493
            if (state->pushed_locals == NULL) {
4872
486
                state->pushed_locals = PyList_New(0);
4873
486
                if (state->pushed_locals == NULL) {
4874
0
                    return ERROR;
4875
0
                }
4876
486
            }
4877
            // in the case of a cell, this will actually push the cell
4878
            // itself to the stack, then we'll create a new one for the
4879
            // comprehension and restore the original one after
4880
493
            ADDOP_NAME(c, loc, LOAD_FAST_AND_CLEAR, k, varnames);
4881
493
            if (scope == CELL) {
4882
0
                if (outsc == FREE) {
4883
0
                    ADDOP_NAME(c, loc, MAKE_CELL, k, freevars);
4884
0
                } else {
4885
0
                    ADDOP_NAME(c, loc, MAKE_CELL, k, cellvars);
4886
0
                }
4887
0
            }
4888
493
            if (PyList_Append(state->pushed_locals, k) < 0) {
4889
0
                return ERROR;
4890
0
            }
4891
493
        }
4892
1.83k
    }
4893
487
    if (state->pushed_locals) {
4894
        // Outermost iterable expression was already evaluated and is on the
4895
        // stack, we need to swap it back to TOS. This also rotates the order of
4896
        // `pushed_locals` on the stack, but this will be reversed when we swap
4897
        // out the comprehension result in pop_inlined_comprehension_state
4898
486
        ADDOP_I(c, loc, SWAP, PyList_GET_SIZE(state->pushed_locals) + 1);
4899
4900
        // Add our own cleanup handler to restore comprehension locals in case
4901
        // of exception, so they have the correct values inside an exception
4902
        // handler or finally block.
4903
486
        NEW_JUMP_TARGET_LABEL(c, cleanup);
4904
486
        state->cleanup = cleanup;
4905
4906
        // no need to push an fblock for this "virtual" try/finally; there can't
4907
        // be return/continue/break inside a comprehension
4908
486
        ADDOP_JUMP(c, loc, SETUP_FINALLY, cleanup);
4909
486
    }
4910
487
    return SUCCESS;
4911
487
}
4912
4913
static int
4914
push_inlined_comprehension_state(compiler *c, location loc,
4915
                                 PySTEntryObject *comp,
4916
                                 _PyCompile_InlinedComprehensionState *state)
4917
487
{
4918
487
    RETURN_IF_ERROR(
4919
487
        _PyCompile_TweakInlinedComprehensionScopes(c, loc, comp, state));
4920
487
    RETURN_IF_ERROR(
4921
487
        codegen_push_inlined_comprehension_locals(c, loc, comp, state));
4922
487
    return SUCCESS;
4923
487
}
4924
4925
static int
4926
restore_inlined_comprehension_locals(compiler *c, location loc,
4927
                                     _PyCompile_InlinedComprehensionState *state)
4928
972
{
4929
972
    PyObject *k;
4930
    // pop names we pushed to stack earlier
4931
972
    Py_ssize_t npops = PyList_GET_SIZE(state->pushed_locals);
4932
    // Preserve the comprehension result (or exception) as TOS. This
4933
    // reverses the SWAP we did in push_inlined_comprehension_state
4934
    // to get the outermost iterable to TOS, so we can still just iterate
4935
    // pushed_locals in simple reverse order
4936
972
    ADDOP_I(c, loc, SWAP, npops + 1);
4937
1.95k
    for (Py_ssize_t i = npops - 1; i >= 0; --i) {
4938
986
        k = PyList_GetItem(state->pushed_locals, i);
4939
986
        if (k == NULL) {
4940
0
            return ERROR;
4941
0
        }
4942
986
        ADDOP_NAME(c, loc, STORE_FAST_MAYBE_NULL, k, varnames);
4943
986
    }
4944
972
    return SUCCESS;
4945
972
}
4946
4947
static int
4948
codegen_pop_inlined_comprehension_locals(compiler *c, location loc,
4949
                                         _PyCompile_InlinedComprehensionState *state)
4950
487
{
4951
487
    if (state->pushed_locals) {
4952
486
        ADDOP(c, NO_LOCATION, POP_BLOCK);
4953
4954
486
        NEW_JUMP_TARGET_LABEL(c, end);
4955
486
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
4956
4957
        // cleanup from an exception inside the comprehension
4958
486
        USE_LABEL(c, state->cleanup);
4959
        // discard incomplete comprehension result (beneath exc on stack)
4960
486
        ADDOP_I(c, NO_LOCATION, SWAP, 2);
4961
486
        ADDOP(c, NO_LOCATION, POP_TOP);
4962
486
        RETURN_IF_ERROR(restore_inlined_comprehension_locals(c, loc, state));
4963
486
        ADDOP_I(c, NO_LOCATION, RERAISE, 0);
4964
4965
486
        USE_LABEL(c, end);
4966
486
        RETURN_IF_ERROR(restore_inlined_comprehension_locals(c, loc, state));
4967
486
        Py_CLEAR(state->pushed_locals);
4968
486
    }
4969
487
    return SUCCESS;
4970
487
}
4971
4972
static int
4973
pop_inlined_comprehension_state(compiler *c, location loc,
4974
                                _PyCompile_InlinedComprehensionState *state)
4975
487
{
4976
487
    RETURN_IF_ERROR(codegen_pop_inlined_comprehension_locals(c, loc, state));
4977
487
    RETURN_IF_ERROR(_PyCompile_RevertInlinedComprehensionScopes(c, loc, state));
4978
487
    return SUCCESS;
4979
487
}
4980
4981
static int
4982
codegen_comprehension(compiler *c, expr_ty e, int type,
4983
                      identifier name, asdl_comprehension_seq *generators, expr_ty elt,
4984
                      expr_ty val)
4985
493
{
4986
493
    PyCodeObject *co = NULL;
4987
493
    _PyCompile_InlinedComprehensionState inline_state = {NULL, NULL, NULL, NO_LABEL};
4988
493
    comprehension_ty outermost;
4989
493
    PySTEntryObject *entry = _PySymtable_Lookup(SYMTABLE(c), (void *)e);
4990
493
    if (entry == NULL) {
4991
0
        goto error;
4992
0
    }
4993
493
    int is_inlined = entry->ste_comp_inlined;
4994
493
    int is_async_comprehension = entry->ste_coroutine;
4995
4996
493
    location loc = LOC(e);
4997
4998
493
    outermost = (comprehension_ty) asdl_seq_GET(generators, 0);
4999
493
    IterStackPosition iter_state;
5000
493
    if (is_inlined) {
5001
487
        VISIT(c, expr, outermost->iter);
5002
487
        if (push_inlined_comprehension_state(c, loc, entry, &inline_state)) {
5003
0
            goto error;
5004
0
        }
5005
487
        iter_state = ITERABLE_ON_STACK;
5006
487
    }
5007
6
    else {
5008
        /* Receive outermost iter as an implicit argument */
5009
6
        _PyCompile_CodeUnitMetadata umd = {
5010
6
            .u_argcount = 1,
5011
6
        };
5012
6
        if (codegen_enter_scope(c, name, COMPILE_SCOPE_COMPREHENSION,
5013
6
                                (void *)e, e->lineno, NULL, &umd) < 0) {
5014
0
            goto error;
5015
0
        }
5016
6
        if (type == COMP_GENEXP) {
5017
            /* Insert GET_ITER before RETURN_GENERATOR.
5018
               https://docs.python.org/3/reference/expressions.html#generator-expressions */
5019
6
            RETURN_IF_ERROR(
5020
6
                _PyInstructionSequence_InsertInstruction(
5021
6
                    INSTR_SEQUENCE(c), 0,
5022
6
                    RESUME, RESUME_AT_GEN_EXPR_START, NO_LOCATION));
5023
6
            RETURN_IF_ERROR(
5024
6
                _PyInstructionSequence_InsertInstruction(
5025
6
                    INSTR_SEQUENCE(c), 1,
5026
6
                    LOAD_FAST, 0, LOC(outermost->iter)));
5027
6
            RETURN_IF_ERROR(
5028
6
                _PyInstructionSequence_InsertInstruction(
5029
6
                    INSTR_SEQUENCE(c), 2,
5030
6
                    outermost->is_async ? GET_AITER : GET_ITER,
5031
6
                    0, LOC(outermost->iter)));
5032
6
            iter_state = ITERATOR_ON_STACK;
5033
6
        }
5034
0
        else {
5035
0
            iter_state = ITERABLE_IN_LOCAL;
5036
0
        }
5037
6
    }
5038
493
    Py_CLEAR(entry);
5039
5040
493
    if (type != COMP_GENEXP) {
5041
487
        int op;
5042
487
        switch (type) {
5043
1
        case COMP_LISTCOMP:
5044
1
            op = BUILD_LIST;
5045
1
            break;
5046
372
        case COMP_SETCOMP:
5047
372
            op = BUILD_SET;
5048
372
            break;
5049
114
        case COMP_DICTCOMP:
5050
114
            op = BUILD_MAP;
5051
114
            break;
5052
0
        default:
5053
0
            PyErr_Format(PyExc_SystemError,
5054
0
                         "unknown comprehension type %d", type);
5055
0
            goto error_in_scope;
5056
487
        }
5057
5058
487
        ADDOP_I(c, loc, op, 0);
5059
487
        if (is_inlined) {
5060
487
            ADDOP_I(c, loc, SWAP, 2);
5061
487
        }
5062
487
    }
5063
493
    if (codegen_comprehension_generator(c, loc, generators, 0, 0,
5064
493
                                        elt, val, type, iter_state) < 0) {
5065
1
        goto error_in_scope;
5066
1
    }
5067
5068
492
    if (is_inlined) {
5069
487
        if (pop_inlined_comprehension_state(c, loc, &inline_state)) {
5070
0
            goto error;
5071
0
        }
5072
487
        return SUCCESS;
5073
487
    }
5074
5075
5
    if (type != COMP_GENEXP) {
5076
0
        ADDOP(c, LOC(e), RETURN_VALUE);
5077
0
    }
5078
5
    if (type == COMP_GENEXP) {
5079
5
        if (codegen_wrap_in_stopiteration_handler(c) < 0) {
5080
0
            goto error_in_scope;
5081
0
        }
5082
5
    }
5083
5084
5
    co = _PyCompile_OptimizeAndAssemble(c, 1);
5085
5
    _PyCompile_ExitScope(c);
5086
5
    if (co == NULL) {
5087
0
        goto error;
5088
0
    }
5089
5090
5
    loc = LOC(e);
5091
5
    if (codegen_make_closure(c, loc, co, 0) < 0) {
5092
0
        goto error;
5093
0
    }
5094
5
    Py_CLEAR(co);
5095
5096
5
    VISIT(c, expr, outermost->iter);
5097
5
    ADDOP_I(c, loc, CALL, 0);
5098
5099
5
    if (is_async_comprehension && type != COMP_GENEXP) {
5100
0
        ADDOP_I(c, loc, GET_AWAITABLE, 0);
5101
0
        ADDOP(c, loc, PUSH_NULL);
5102
0
        ADDOP_LOAD_CONST(c, loc, Py_None);
5103
0
        ADD_YIELD_FROM(c, loc, 1);
5104
0
    }
5105
5106
5
    return SUCCESS;
5107
1
error_in_scope:
5108
1
    if (!is_inlined) {
5109
1
        _PyCompile_ExitScope(c);
5110
1
    }
5111
1
error:
5112
1
    Py_XDECREF(co);
5113
1
    Py_XDECREF(entry);
5114
1
    Py_XDECREF(inline_state.pushed_locals);
5115
1
    Py_XDECREF(inline_state.temp_symbols);
5116
1
    Py_XDECREF(inline_state.fast_hidden);
5117
1
    return ERROR;
5118
1
}
5119
5120
static int
5121
codegen_genexp(compiler *c, expr_ty e)
5122
6
{
5123
6
    assert(e->kind == GeneratorExp_kind);
5124
6
    _Py_DECLARE_STR(anon_genexpr, "<genexpr>");
5125
6
    return codegen_comprehension(c, e, COMP_GENEXP, &_Py_STR(anon_genexpr),
5126
6
                                 e->v.GeneratorExp.generators,
5127
6
                                 e->v.GeneratorExp.elt, NULL);
5128
6
}
5129
5130
static int
5131
codegen_listcomp(compiler *c, expr_ty e)
5132
1
{
5133
1
    assert(e->kind == ListComp_kind);
5134
1
    _Py_DECLARE_STR(anon_listcomp, "<listcomp>");
5135
1
    return codegen_comprehension(c, e, COMP_LISTCOMP, &_Py_STR(anon_listcomp),
5136
1
                                 e->v.ListComp.generators,
5137
1
                                 e->v.ListComp.elt, NULL);
5138
1
}
5139
5140
static int
5141
codegen_setcomp(compiler *c, expr_ty e)
5142
372
{
5143
372
    assert(e->kind == SetComp_kind);
5144
372
    _Py_DECLARE_STR(anon_setcomp, "<setcomp>");
5145
372
    return codegen_comprehension(c, e, COMP_SETCOMP, &_Py_STR(anon_setcomp),
5146
372
                                 e->v.SetComp.generators,
5147
372
                                 e->v.SetComp.elt, NULL);
5148
372
}
5149
5150
5151
static int
5152
codegen_dictcomp(compiler *c, expr_ty e)
5153
114
{
5154
114
    assert(e->kind == DictComp_kind);
5155
114
    _Py_DECLARE_STR(anon_dictcomp, "<dictcomp>");
5156
114
    return codegen_comprehension(c, e, COMP_DICTCOMP, &_Py_STR(anon_dictcomp),
5157
114
                                 e->v.DictComp.generators,
5158
114
                                 e->v.DictComp.key, e->v.DictComp.value);
5159
114
}
5160
5161
5162
static int
5163
codegen_visit_keyword(compiler *c, keyword_ty k)
5164
57
{
5165
57
    VISIT(c, expr, k->value);
5166
57
    return SUCCESS;
5167
57
}
5168
5169
5170
static int
5171
4.51k
codegen_with_except_finish(compiler *c, jump_target_label cleanup) {
5172
4.51k
    NEW_JUMP_TARGET_LABEL(c, suppress);
5173
4.51k
    ADDOP(c, NO_LOCATION, TO_BOOL);
5174
4.51k
    ADDOP_JUMP(c, NO_LOCATION, POP_JUMP_IF_TRUE, suppress);
5175
4.51k
    ADDOP_I(c, NO_LOCATION, RERAISE, 2);
5176
5177
4.51k
    USE_LABEL(c, suppress);
5178
4.51k
    ADDOP(c, NO_LOCATION, POP_TOP); /* exc_value */
5179
4.51k
    ADDOP(c, NO_LOCATION, POP_BLOCK);
5180
4.51k
    ADDOP(c, NO_LOCATION, POP_EXCEPT);
5181
4.51k
    ADDOP(c, NO_LOCATION, POP_TOP);
5182
4.51k
    ADDOP(c, NO_LOCATION, POP_TOP);
5183
4.51k
    ADDOP(c, NO_LOCATION, POP_TOP);
5184
4.51k
    NEW_JUMP_TARGET_LABEL(c, exit);
5185
4.51k
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, exit);
5186
5187
4.51k
    USE_LABEL(c, cleanup);
5188
4.51k
    POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
5189
5190
4.51k
    USE_LABEL(c, exit);
5191
4.51k
    return SUCCESS;
5192
4.51k
}
5193
5194
/*
5195
   Implements the async with statement.
5196
5197
   The semantics outlined in that PEP are as follows:
5198
5199
   async with EXPR as VAR:
5200
       BLOCK
5201
5202
   It is implemented roughly as:
5203
5204
   context = EXPR
5205
   exit = context.__aexit__  # not calling it
5206
   value = await context.__aenter__()
5207
   try:
5208
       VAR = value  # if VAR present in the syntax
5209
       BLOCK
5210
   finally:
5211
       if an exception was raised:
5212
           exc = copy of (exception, instance, traceback)
5213
       else:
5214
           exc = (None, None, None)
5215
       if not (await exit(*exc)):
5216
           raise
5217
 */
5218
static int
5219
codegen_async_with_inner(compiler *c, stmt_ty s, int pos)
5220
4.57k
{
5221
4.57k
    location loc = LOC(s);
5222
4.57k
    withitem_ty item = asdl_seq_GET(s->v.AsyncWith.items, pos);
5223
5224
4.57k
    assert(s->kind == AsyncWith_kind);
5225
5226
4.57k
    NEW_JUMP_TARGET_LABEL(c, block);
5227
4.57k
    NEW_JUMP_TARGET_LABEL(c, final);
5228
4.57k
    NEW_JUMP_TARGET_LABEL(c, exit);
5229
4.57k
    NEW_JUMP_TARGET_LABEL(c, cleanup);
5230
5231
    /* Evaluate EXPR */
5232
4.57k
    VISIT(c, expr, item->context_expr);
5233
4.57k
    loc = LOC(item->context_expr);
5234
4.57k
    ADDOP_I(c, loc, COPY, 1);
5235
4.57k
    ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___AEXIT__);
5236
4.57k
    ADDOP_I(c, loc, SWAP, 2);
5237
4.57k
    ADDOP_I(c, loc, SWAP, 3);
5238
4.57k
    ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___AENTER__);
5239
4.57k
    ADDOP_I(c, loc, CALL, 0);
5240
4.57k
    ADDOP_I(c, loc, GET_AWAITABLE, 1);
5241
4.57k
    ADDOP(c, loc, PUSH_NULL);
5242
4.57k
    ADDOP_LOAD_CONST(c, loc, Py_None);
5243
4.57k
    ADD_YIELD_FROM(c, loc, 1);
5244
5245
4.57k
    ADDOP_JUMP(c, loc, SETUP_WITH, final);
5246
5247
    /* SETUP_WITH pushes a finally block. */
5248
4.57k
    USE_LABEL(c, block);
5249
4.57k
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_ASYNC_WITH, block, final, s));
5250
5251
4.56k
    if (item->optional_vars) {
5252
23
        VISIT(c, expr, item->optional_vars);
5253
23
    }
5254
4.54k
    else {
5255
        /* Discard result from context.__aenter__() */
5256
4.54k
        ADDOP(c, loc, POP_TOP);
5257
4.54k
    }
5258
5259
4.56k
    pos++;
5260
4.56k
    if (pos == asdl_seq_LEN(s->v.AsyncWith.items)) {
5261
        /* BLOCK code */
5262
812
        VISIT_SEQ(c, stmt, s->v.AsyncWith.body);
5263
812
    }
5264
3.75k
    else {
5265
3.75k
        RETURN_IF_ERROR(codegen_async_with_inner(c, s, pos));
5266
3.75k
    }
5267
5268
4.48k
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_ASYNC_WITH, block);
5269
5270
4.48k
    ADDOP(c, loc, POP_BLOCK);
5271
    /* End of body; start the cleanup */
5272
5273
    /* For successful outcome:
5274
     * call __exit__(None, None, None)
5275
     */
5276
4.48k
    RETURN_IF_ERROR(codegen_call_exit_with_nones(c, loc));
5277
4.48k
    ADDOP_I(c, loc, GET_AWAITABLE, 2);
5278
4.48k
    ADDOP(c, loc, PUSH_NULL);
5279
4.48k
    ADDOP_LOAD_CONST(c, loc, Py_None);
5280
4.48k
    ADD_YIELD_FROM(c, loc, 1);
5281
5282
4.48k
    ADDOP(c, loc, POP_TOP);
5283
5284
4.48k
    ADDOP_JUMP(c, loc, JUMP, exit);
5285
5286
    /* For exceptional outcome: */
5287
4.48k
    USE_LABEL(c, final);
5288
5289
4.48k
    ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
5290
4.48k
    ADDOP(c, loc, PUSH_EXC_INFO);
5291
4.48k
    ADDOP(c, loc, WITH_EXCEPT_START);
5292
4.48k
    ADDOP_I(c, loc, GET_AWAITABLE, 2);
5293
4.48k
    ADDOP(c, loc, PUSH_NULL);
5294
4.48k
    ADDOP_LOAD_CONST(c, loc, Py_None);
5295
4.48k
    ADD_YIELD_FROM(c, loc, 1);
5296
4.48k
    RETURN_IF_ERROR(codegen_with_except_finish(c, cleanup));
5297
5298
4.48k
    USE_LABEL(c, exit);
5299
4.48k
    return SUCCESS;
5300
4.48k
}
5301
5302
static int
5303
codegen_async_with(compiler *c, stmt_ty s)
5304
815
{
5305
815
    return codegen_async_with_inner(c, s, 0);
5306
815
}
5307
5308
5309
/*
5310
   Implements the with statement from PEP 343.
5311
   with EXPR as VAR:
5312
       BLOCK
5313
   is implemented as:
5314
        <code for EXPR>
5315
        SETUP_WITH  E
5316
        <code to store to VAR> or POP_TOP
5317
        <code for BLOCK>
5318
        LOAD_CONST (None, None, None)
5319
        CALL_FUNCTION_EX 0
5320
        JUMP  EXIT
5321
    E:  WITH_EXCEPT_START (calls EXPR.__exit__)
5322
        POP_JUMP_IF_TRUE T:
5323
        RERAISE
5324
    T:  POP_TOP (remove exception from stack)
5325
        POP_EXCEPT
5326
        POP_TOP
5327
    EXIT:
5328
 */
5329
5330
static int
5331
codegen_with_inner(compiler *c, stmt_ty s, int pos)
5332
33
{
5333
33
    withitem_ty item = asdl_seq_GET(s->v.With.items, pos);
5334
5335
33
    assert(s->kind == With_kind);
5336
5337
33
    NEW_JUMP_TARGET_LABEL(c, block);
5338
33
    NEW_JUMP_TARGET_LABEL(c, final);
5339
33
    NEW_JUMP_TARGET_LABEL(c, exit);
5340
33
    NEW_JUMP_TARGET_LABEL(c, cleanup);
5341
5342
    /* Evaluate EXPR */
5343
33
    VISIT(c, expr, item->context_expr);
5344
    /* Will push bound __exit__ */
5345
33
    location loc = LOC(item->context_expr);
5346
33
    ADDOP_I(c, loc, COPY, 1);
5347
33
    ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___EXIT__);
5348
33
    ADDOP_I(c, loc, SWAP, 2);
5349
33
    ADDOP_I(c, loc, SWAP, 3);
5350
33
    ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___ENTER__);
5351
33
    ADDOP_I(c, loc, CALL, 0);
5352
33
    ADDOP_JUMP(c, loc, SETUP_WITH, final);
5353
5354
    /* SETUP_WITH pushes a finally block. */
5355
33
    USE_LABEL(c, block);
5356
33
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_WITH, block, final, s));
5357
5358
33
    if (item->optional_vars) {
5359
4
        VISIT(c, expr, item->optional_vars);
5360
4
    }
5361
29
    else {
5362
    /* Discard result from context.__enter__() */
5363
29
        ADDOP(c, loc, POP_TOP);
5364
29
    }
5365
5366
33
    pos++;
5367
33
    if (pos == asdl_seq_LEN(s->v.With.items)) {
5368
        /* BLOCK code */
5369
29
        VISIT_SEQ(c, stmt, s->v.With.body);
5370
29
    }
5371
4
    else {
5372
4
        RETURN_IF_ERROR(codegen_with_inner(c, s, pos));
5373
4
    }
5374
5375
33
    ADDOP(c, NO_LOCATION, POP_BLOCK);
5376
33
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_WITH, block);
5377
5378
    /* End of body; start the cleanup. */
5379
5380
    /* For successful outcome:
5381
     * call __exit__(None, None, None)
5382
     */
5383
33
    RETURN_IF_ERROR(codegen_call_exit_with_nones(c, loc));
5384
33
    ADDOP(c, loc, POP_TOP);
5385
33
    ADDOP_JUMP(c, loc, JUMP, exit);
5386
5387
    /* For exceptional outcome: */
5388
33
    USE_LABEL(c, final);
5389
5390
33
    ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
5391
33
    ADDOP(c, loc, PUSH_EXC_INFO);
5392
33
    ADDOP(c, loc, WITH_EXCEPT_START);
5393
33
    RETURN_IF_ERROR(codegen_with_except_finish(c, cleanup));
5394
5395
33
    USE_LABEL(c, exit);
5396
33
    return SUCCESS;
5397
33
}
5398
5399
static int
5400
codegen_with(compiler *c, stmt_ty s)
5401
29
{
5402
29
    return codegen_with_inner(c, s, 0);
5403
29
}
5404
5405
static int
5406
codegen_visit_expr(compiler *c, expr_ty e)
5407
719k
{
5408
719k
    if (Py_EnterRecursiveCall(" during compilation")) {
5409
0
        return ERROR;
5410
0
    }
5411
719k
    location loc = LOC(e);
5412
719k
    switch (e->kind) {
5413
262
    case NamedExpr_kind:
5414
262
        VISIT(c, expr, e->v.NamedExpr.value);
5415
262
        ADDOP_I(c, loc, COPY, 1);
5416
262
        VISIT(c, expr, e->v.NamedExpr.target);
5417
262
        break;
5418
1.32k
    case BoolOp_kind:
5419
1.32k
        return codegen_boolop(c, e);
5420
236k
    case BinOp_kind:
5421
236k
        VISIT(c, expr, e->v.BinOp.left);
5422
236k
        VISIT(c, expr, e->v.BinOp.right);
5423
236k
        ADDOP_BINARY(c, loc, e->v.BinOp.op);
5424
236k
        break;
5425
236k
    case UnaryOp_kind:
5426
82.7k
        VISIT(c, expr, e->v.UnaryOp.operand);
5427
82.5k
        if (e->v.UnaryOp.op == UAdd) {
5428
16.9k
            ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_UNARY_POSITIVE);
5429
16.9k
        }
5430
65.5k
        else if (e->v.UnaryOp.op == Not) {
5431
328
            ADDOP(c, loc, TO_BOOL);
5432
328
            ADDOP(c, loc, UNARY_NOT);
5433
328
        }
5434
65.2k
        else {
5435
65.2k
            ADDOP(c, loc, unaryop(e->v.UnaryOp.op));
5436
65.2k
        }
5437
82.5k
        break;
5438
82.5k
    case Lambda_kind:
5439
478
        return codegen_lambda(c, e);
5440
353
    case IfExp_kind:
5441
353
        return codegen_ifexp(c, e);
5442
35
    case Dict_kind:
5443
35
        return codegen_dict(c, e);
5444
379
    case Set_kind:
5445
379
        return codegen_set(c, e);
5446
6
    case GeneratorExp_kind:
5447
6
        return codegen_genexp(c, e);
5448
1
    case ListComp_kind:
5449
1
        return codegen_listcomp(c, e);
5450
372
    case SetComp_kind:
5451
372
        return codegen_setcomp(c, e);
5452
114
    case DictComp_kind:
5453
114
        return codegen_dictcomp(c, e);
5454
19
    case Yield_kind:
5455
19
        if (!_PyST_IsFunctionLike(SYMTABLE_ENTRY(c))) {
5456
17
            return _PyCompile_Error(c, loc, "'yield' outside function");
5457
17
        }
5458
2
        if (e->v.Yield.value) {
5459
0
            VISIT(c, expr, e->v.Yield.value);
5460
0
        }
5461
2
        else {
5462
2
            ADDOP_LOAD_CONST(c, loc, Py_None);
5463
2
        }
5464
2
        ADDOP_YIELD(c, loc);
5465
2
        break;
5466
2
    case YieldFrom_kind:
5467
0
        if (!_PyST_IsFunctionLike(SYMTABLE_ENTRY(c))) {
5468
0
            return _PyCompile_Error(c, loc, "'yield from' outside function");
5469
0
        }
5470
0
        if (SCOPE_TYPE(c) == COMPILE_SCOPE_ASYNC_FUNCTION) {
5471
0
            return _PyCompile_Error(c, loc, "'yield from' inside async function");
5472
0
        }
5473
0
        VISIT(c, expr, e->v.YieldFrom.value);
5474
0
        ADDOP_I(c, loc, GET_ITER, GET_ITER_YIELD_FROM);
5475
0
        ADDOP_LOAD_CONST(c, loc, Py_None);
5476
0
        ADD_YIELD_FROM(c, loc, 0);
5477
0
        break;
5478
42
    case Await_kind:
5479
42
        VISIT(c, expr, e->v.Await.value);
5480
42
        ADDOP_I(c, loc, GET_AWAITABLE, 0);
5481
42
        ADDOP(c, loc, PUSH_NULL);
5482
42
        ADDOP_LOAD_CONST(c, loc, Py_None);
5483
42
        ADD_YIELD_FROM(c, loc, 1);
5484
42
        break;
5485
6.93k
    case Compare_kind:
5486
6.93k
        return codegen_compare(c, e);
5487
2.49k
    case Call_kind:
5488
2.49k
        return codegen_call(c, e);
5489
267k
    case Constant_kind:
5490
267k
        ADDOP_LOAD_CONST(c, loc, e->v.Constant.value);
5491
267k
        break;
5492
267k
    case JoinedStr_kind:
5493
287
        return codegen_joined_str(c, e);
5494
145
    case TemplateStr_kind:
5495
145
        return codegen_template_str(c, e);
5496
243
    case FormattedValue_kind:
5497
243
        return codegen_formatted_value(c, e);
5498
102
    case Interpolation_kind:
5499
102
        return codegen_interpolation(c, e);
5500
    /* The following exprs can be assignment targets. */
5501
3.00k
    case Attribute_kind:
5502
3.00k
        if (e->v.Attribute.ctx == Load) {
5503
2.96k
            int ret = can_optimize_super_call(c, e);
5504
2.96k
            RETURN_IF_ERROR(ret);
5505
2.96k
            if (ret) {
5506
189
                RETURN_IF_ERROR(load_args_for_super(c, e->v.Attribute.value));
5507
189
                int opcode = asdl_seq_LEN(e->v.Attribute.value->v.Call.args) ?
5508
189
                    LOAD_SUPER_ATTR : LOAD_ZERO_SUPER_ATTR;
5509
189
                ADDOP_NAME(c, loc, opcode, e->v.Attribute.attr, names);
5510
189
                loc = update_start_location_to_match_attr(c, loc, e);
5511
189
                ADDOP(c, loc, NOP);
5512
189
                return SUCCESS;
5513
189
            }
5514
2.96k
        }
5515
2.81k
        RETURN_IF_ERROR(_PyCompile_MaybeAddStaticAttributeToClass(c, e));
5516
2.81k
        VISIT(c, expr, e->v.Attribute.value);
5517
2.81k
        loc = LOC(e);
5518
2.81k
        loc = update_start_location_to_match_attr(c, loc, e);
5519
2.81k
        switch (e->v.Attribute.ctx) {
5520
2.77k
        case Load:
5521
2.77k
            ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names);
5522
2.77k
            break;
5523
2.77k
        case Store:
5524
29
            ADDOP_NAME(c, loc, STORE_ATTR, e->v.Attribute.attr, names);
5525
29
            break;
5526
29
        case Del:
5527
7
            ADDOP_NAME(c, loc, DELETE_ATTR, e->v.Attribute.attr, names);
5528
7
            break;
5529
2.81k
        }
5530
2.81k
        break;
5531
2.81k
    case Subscript_kind:
5532
1.97k
        return codegen_subscript(c, e);
5533
64
    case Starred_kind:
5534
64
        switch (e->v.Starred.ctx) {
5535
2
        case Store:
5536
            /* In all legitimate cases, the Starred node was already replaced
5537
             * by codegen_list/codegen_tuple. XXX: is that okay? */
5538
2
            return _PyCompile_Error(c, loc,
5539
2
                "starred assignment target must be in a list or tuple");
5540
62
        default:
5541
62
            return _PyCompile_Error(c, loc,
5542
62
                "can't use starred expression here");
5543
64
        }
5544
0
        break;
5545
1.79k
    case Slice_kind:
5546
1.79k
        RETURN_IF_ERROR(codegen_slice(c, e));
5547
1.79k
        break;
5548
98.6k
    case Name_kind:
5549
98.6k
        return codegen_nameop(c, loc, e->v.Name.id, e->v.Name.ctx);
5550
    /* child nodes of List and Tuple will have expr_context set */
5551
110
    case List_kind:
5552
110
        return codegen_list(c, e);
5553
13.1k
    case Tuple_kind:
5554
13.1k
        return codegen_tuple(c, e);
5555
719k
    }
5556
591k
    return SUCCESS;
5557
719k
}
5558
5559
static bool
5560
is_constant_slice(expr_ty s)
5561
3.81k
{
5562
3.81k
    return s->kind == Slice_kind &&
5563
3.21k
        (s->v.Slice.lower == NULL ||
5564
2.81k
         s->v.Slice.lower->kind == Constant_kind) &&
5565
2.87k
        (s->v.Slice.upper == NULL ||
5566
246
         s->v.Slice.upper->kind == Constant_kind) &&
5567
2.82k
        (s->v.Slice.step == NULL ||
5568
1.40k
         s->v.Slice.step->kind == Constant_kind);
5569
3.81k
}
5570
5571
static bool
5572
should_apply_two_element_slice_optimization(expr_ty s)
5573
2.01k
{
5574
2.01k
    return !is_constant_slice(s) &&
5575
650
           s->kind == Slice_kind &&
5576
53
           s->v.Slice.step == NULL;
5577
2.01k
}
5578
5579
static int
5580
codegen_augassign(compiler *c, stmt_ty s)
5581
1.46k
{
5582
1.46k
    assert(s->kind == AugAssign_kind);
5583
1.46k
    expr_ty e = s->v.AugAssign.target;
5584
5585
1.46k
    location loc = LOC(e);
5586
5587
1.46k
    switch (e->kind) {
5588
5
    case Attribute_kind:
5589
5
        VISIT(c, expr, e->v.Attribute.value);
5590
5
        ADDOP_I(c, loc, COPY, 1);
5591
5
        loc = update_start_location_to_match_attr(c, loc, e);
5592
5
        ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names);
5593
5
        break;
5594
21
    case Subscript_kind:
5595
21
        VISIT(c, expr, e->v.Subscript.value);
5596
21
        if (should_apply_two_element_slice_optimization(e->v.Subscript.slice)) {
5597
11
            RETURN_IF_ERROR(codegen_slice_two_parts(c, e->v.Subscript.slice));
5598
11
            ADDOP_I(c, loc, COPY, 3);
5599
11
            ADDOP_I(c, loc, COPY, 3);
5600
11
            ADDOP_I(c, loc, COPY, 3);
5601
11
            ADDOP(c, loc, BINARY_SLICE);
5602
11
        }
5603
10
        else {
5604
10
            VISIT(c, expr, e->v.Subscript.slice);
5605
10
            ADDOP_I(c, loc, COPY, 2);
5606
10
            ADDOP_I(c, loc, COPY, 2);
5607
10
            ADDOP_I(c, loc, BINARY_OP, NB_SUBSCR);
5608
10
        }
5609
21
        break;
5610
1.44k
    case Name_kind:
5611
1.44k
        RETURN_IF_ERROR(codegen_nameop(c, loc, e->v.Name.id, Load));
5612
1.44k
        break;
5613
1.44k
    default:
5614
0
        PyErr_Format(PyExc_SystemError,
5615
0
            "invalid node type (%d) for augmented assignment",
5616
0
            e->kind);
5617
0
        return ERROR;
5618
1.46k
    }
5619
5620
1.46k
    loc = LOC(s);
5621
5622
1.46k
    VISIT(c, expr, s->v.AugAssign.value);
5623
1.46k
    ADDOP_INPLACE(c, loc, s->v.AugAssign.op);
5624
5625
1.46k
    loc = LOC(e);
5626
5627
1.46k
    switch (e->kind) {
5628
5
    case Attribute_kind:
5629
5
        loc = update_start_location_to_match_attr(c, loc, e);
5630
5
        ADDOP_I(c, loc, SWAP, 2);
5631
5
        ADDOP_NAME(c, loc, STORE_ATTR, e->v.Attribute.attr, names);
5632
5
        break;
5633
21
    case Subscript_kind:
5634
21
        if (should_apply_two_element_slice_optimization(e->v.Subscript.slice)) {
5635
11
            ADDOP_I(c, loc, SWAP, 4);
5636
11
            ADDOP_I(c, loc, SWAP, 3);
5637
11
            ADDOP_I(c, loc, SWAP, 2);
5638
11
            ADDOP(c, loc, STORE_SLICE);
5639
11
        }
5640
10
        else {
5641
10
            ADDOP_I(c, loc, SWAP, 3);
5642
10
            ADDOP_I(c, loc, SWAP, 2);
5643
10
            ADDOP(c, loc, STORE_SUBSCR);
5644
10
        }
5645
21
        break;
5646
1.43k
    case Name_kind:
5647
1.43k
        return codegen_nameop(c, loc, e->v.Name.id, Store);
5648
0
    default:
5649
0
        Py_UNREACHABLE();
5650
1.46k
    }
5651
26
    return SUCCESS;
5652
1.46k
}
5653
5654
static int
5655
codegen_check_ann_expr(compiler *c, expr_ty e)
5656
542
{
5657
542
    VISIT(c, expr, e);
5658
541
    ADDOP(c, LOC(e), POP_TOP);
5659
541
    return SUCCESS;
5660
541
}
5661
5662
static int
5663
codegen_check_ann_subscr(compiler *c, expr_ty e)
5664
292
{
5665
    /* We check that everything in a subscript is defined at runtime. */
5666
292
    switch (e->kind) {
5667
181
    case Slice_kind:
5668
181
        if (e->v.Slice.lower && codegen_check_ann_expr(c, e->v.Slice.lower) < 0) {
5669
0
            return ERROR;
5670
0
        }
5671
181
        if (e->v.Slice.upper && codegen_check_ann_expr(c, e->v.Slice.upper) < 0) {
5672
0
            return ERROR;
5673
0
        }
5674
181
        if (e->v.Slice.step && codegen_check_ann_expr(c, e->v.Slice.step) < 0) {
5675
0
            return ERROR;
5676
0
        }
5677
181
        return SUCCESS;
5678
20
    case Tuple_kind: {
5679
        /* extended slice */
5680
20
        asdl_expr_seq *elts = e->v.Tuple.elts;
5681
20
        Py_ssize_t i, n = asdl_seq_LEN(elts);
5682
281
        for (i = 0; i < n; i++) {
5683
262
            RETURN_IF_ERROR(codegen_check_ann_subscr(c, asdl_seq_GET(elts, i)));
5684
262
        }
5685
19
        return SUCCESS;
5686
20
    }
5687
91
    default:
5688
91
        return codegen_check_ann_expr(c, e);
5689
292
    }
5690
292
}
5691
5692
static int
5693
codegen_annassign(compiler *c, stmt_ty s)
5694
12.1k
{
5695
12.1k
    location loc = LOC(s);
5696
12.1k
    expr_ty targ = s->v.AnnAssign.target;
5697
12.1k
    bool future_annotations = FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS;
5698
12.1k
    PyObject *mangled;
5699
5700
12.1k
    assert(s->kind == AnnAssign_kind);
5701
5702
    /* We perform the actual assignment first. */
5703
12.1k
    if (s->v.AnnAssign.value) {
5704
228
        VISIT(c, expr, s->v.AnnAssign.value);
5705
226
        VISIT(c, expr, targ);
5706
226
    }
5707
12.1k
    switch (targ->kind) {
5708
11.8k
    case Name_kind:
5709
        /* If we have a simple name in a module or class, store annotation. */
5710
11.8k
        if (s->v.AnnAssign.simple &&
5711
11.6k
            (SCOPE_TYPE(c) == COMPILE_SCOPE_MODULE ||
5712
10.0k
             SCOPE_TYPE(c) == COMPILE_SCOPE_CLASS)) {
5713
8.77k
            if (future_annotations) {
5714
1.13k
                VISIT(c, annexpr, s->v.AnnAssign.annotation);
5715
1.13k
                ADDOP_NAME(c, loc, LOAD_NAME, &_Py_ID(__annotations__), names);
5716
1.13k
                mangled = _PyCompile_MaybeMangle(c, targ->v.Name.id);
5717
1.13k
                ADDOP_LOAD_CONST_NEW(c, loc, mangled);
5718
1.13k
                ADDOP(c, loc, STORE_SUBSCR);
5719
1.13k
            }
5720
7.63k
            else {
5721
7.63k
                PyObject *conditional_annotation_index = NULL;
5722
7.63k
                RETURN_IF_ERROR(_PyCompile_AddDeferredAnnotation(
5723
7.63k
                    c, s, &conditional_annotation_index));
5724
7.63k
                if (conditional_annotation_index != NULL) {
5725
1.77k
                    if (SCOPE_TYPE(c) == COMPILE_SCOPE_CLASS) {
5726
897
                        ADDOP_NAME(c, loc, LOAD_DEREF, &_Py_ID(__conditional_annotations__), cellvars);
5727
897
                    }
5728
881
                    else {
5729
881
                        ADDOP_NAME(c, loc, LOAD_NAME, &_Py_ID(__conditional_annotations__), names);
5730
881
                    }
5731
1.77k
                    ADDOP_LOAD_CONST_NEW(c, loc, conditional_annotation_index);
5732
1.77k
                    ADDOP_I(c, loc, SET_ADD, 1);
5733
1.77k
                    ADDOP(c, loc, POP_TOP);
5734
1.77k
                }
5735
7.63k
            }
5736
8.77k
        }
5737
11.8k
        break;
5738
11.8k
    case Attribute_kind:
5739
217
        if (!s->v.AnnAssign.value &&
5740
202
            codegen_check_ann_expr(c, targ->v.Attribute.value) < 0) {
5741
0
            return ERROR;
5742
0
        }
5743
217
        break;
5744
217
    case Subscript_kind:
5745
33
        if (!s->v.AnnAssign.value &&
5746
30
            (codegen_check_ann_expr(c, targ->v.Subscript.value) < 0 ||
5747
30
             codegen_check_ann_subscr(c, targ->v.Subscript.slice) < 0)) {
5748
1
                return ERROR;
5749
1
        }
5750
32
        break;
5751
32
    default:
5752
0
        PyErr_Format(PyExc_SystemError,
5753
0
                     "invalid node type (%d) for annotated assignment",
5754
0
                     targ->kind);
5755
0
        return ERROR;
5756
12.1k
    }
5757
12.1k
    return SUCCESS;
5758
12.1k
}
5759
5760
static int
5761
codegen_subscript(compiler *c, expr_ty e)
5762
1.97k
{
5763
1.97k
    location loc = LOC(e);
5764
1.97k
    expr_context_ty ctx = e->v.Subscript.ctx;
5765
5766
1.97k
    if (ctx == Load) {
5767
1.95k
        RETURN_IF_ERROR(check_subscripter(c, e->v.Subscript.value));
5768
1.95k
        RETURN_IF_ERROR(check_index(c, e->v.Subscript.value, e->v.Subscript.slice));
5769
1.95k
    }
5770
5771
1.97k
    VISIT(c, expr, e->v.Subscript.value);
5772
1.97k
    if (should_apply_two_element_slice_optimization(e->v.Subscript.slice) &&
5773
17
        ctx != Del
5774
1.97k
    ) {
5775
17
        RETURN_IF_ERROR(codegen_slice_two_parts(c, e->v.Subscript.slice));
5776
17
        if (ctx == Load) {
5777
17
            ADDOP(c, loc, BINARY_SLICE);
5778
17
        }
5779
0
        else {
5780
0
            assert(ctx == Store);
5781
0
            ADDOP(c, loc, STORE_SLICE);
5782
0
        }
5783
17
    }
5784
1.95k
    else {
5785
1.95k
        VISIT(c, expr, e->v.Subscript.slice);
5786
1.95k
        switch (ctx) {
5787
1.93k
            case Load:
5788
1.93k
                ADDOP_I(c, loc, BINARY_OP, NB_SUBSCR);
5789
1.93k
                break;
5790
1.93k
            case Store:
5791
16
                ADDOP(c, loc, STORE_SUBSCR);
5792
16
                break;
5793
16
            case Del:
5794
2
                ADDOP(c, loc, DELETE_SUBSCR);
5795
2
                break;
5796
1.95k
        }
5797
1.95k
    }
5798
1.97k
    return SUCCESS;
5799
1.97k
}
5800
5801
static int
5802
codegen_slice_two_parts(compiler *c, expr_ty s)
5803
410
{
5804
410
    if (s->v.Slice.lower) {
5805
349
        VISIT(c, expr, s->v.Slice.lower);
5806
349
    }
5807
61
    else {
5808
61
        ADDOP_LOAD_CONST(c, LOC(s), Py_None);
5809
61
    }
5810
5811
408
    if (s->v.Slice.upper) {
5812
174
        VISIT(c, expr, s->v.Slice.upper);
5813
174
    }
5814
234
    else {
5815
234
        ADDOP_LOAD_CONST(c, LOC(s), Py_None);
5816
234
    }
5817
5818
408
    return 0;
5819
408
}
5820
5821
static int
5822
codegen_slice(compiler *c, expr_ty s)
5823
1.79k
{
5824
1.79k
    int n = 2;
5825
1.79k
    assert(s->kind == Slice_kind);
5826
5827
1.79k
    if (is_constant_slice(s)) {
5828
1.41k
        PyObject *start = NULL;
5829
1.41k
        if (s->v.Slice.lower) {
5830
1.22k
            start = s->v.Slice.lower->v.Constant.value;
5831
1.22k
        }
5832
1.41k
        PyObject *stop = NULL;
5833
1.41k
        if (s->v.Slice.upper) {
5834
121
            stop = s->v.Slice.upper->v.Constant.value;
5835
121
        }
5836
1.41k
        PyObject *step = NULL;
5837
1.41k
        if (s->v.Slice.step) {
5838
681
            step = s->v.Slice.step->v.Constant.value;
5839
681
        }
5840
1.41k
        PyObject *slice = PySlice_New(start, stop, step);
5841
1.41k
        if (slice == NULL) {
5842
0
            return ERROR;
5843
0
        }
5844
1.41k
        ADDOP_LOAD_CONST_NEW(c, LOC(s), slice);
5845
1.41k
        return SUCCESS;
5846
1.41k
    }
5847
5848
382
    RETURN_IF_ERROR(codegen_slice_two_parts(c, s));
5849
5850
380
    if (s->v.Slice.step) {
5851
132
        n++;
5852
132
        VISIT(c, expr, s->v.Slice.step);
5853
132
    }
5854
5855
380
    ADDOP_I(c, LOC(s), BUILD_SLICE, n);
5856
380
    return SUCCESS;
5857
380
}
5858
5859
5860
// PEP 634: Structural Pattern Matching
5861
5862
// To keep things simple, all codegen_pattern_* routines follow the convention
5863
// of consuming TOS (the subject for the given pattern) and calling
5864
// jump_to_fail_pop on failure (no match).
5865
5866
// When calling into these routines, it's important that pc->on_top be kept
5867
// updated to reflect the current number of items that we are using on the top
5868
// of the stack: they will be popped on failure, and any name captures will be
5869
// stored *underneath* them on success. This lets us defer all names stores
5870
// until the *entire* pattern matches.
5871
5872
#define WILDCARD_CHECK(N) \
5873
318
    ((N)->kind == MatchAs_kind && !(N)->v.MatchAs.name)
5874
5875
#define WILDCARD_STAR_CHECK(N) \
5876
8
    ((N)->kind == MatchStar_kind && !(N)->v.MatchStar.name)
5877
5878
// Limit permitted subexpressions, even if the parser & AST validator let them through
5879
#define MATCH_VALUE_EXPR(N) \
5880
21
    ((N)->kind == Constant_kind || (N)->kind == Attribute_kind)
5881
5882
// Allocate or resize pc->fail_pop to allow for n items to be popped on failure.
5883
static int
5884
ensure_fail_pop(compiler *c, pattern_context *pc, Py_ssize_t n)
5885
168
{
5886
168
    Py_ssize_t size = n + 1;
5887
168
    if (size <= pc->fail_pop_size) {
5888
85
        return SUCCESS;
5889
85
    }
5890
83
    Py_ssize_t needed = sizeof(jump_target_label) * size;
5891
83
    jump_target_label *resized = PyMem_Realloc(pc->fail_pop, needed);
5892
83
    if (resized == NULL) {
5893
0
        PyErr_NoMemory();
5894
0
        return ERROR;
5895
0
    }
5896
83
    pc->fail_pop = resized;
5897
267
    while (pc->fail_pop_size < size) {
5898
184
        NEW_JUMP_TARGET_LABEL(c, new_block);
5899
184
        pc->fail_pop[pc->fail_pop_size++] = new_block;
5900
184
    }
5901
83
    return SUCCESS;
5902
83
}
5903
5904
// Use op to jump to the correct fail_pop block.
5905
static int
5906
jump_to_fail_pop(compiler *c, location loc,
5907
                 pattern_context *pc, int op)
5908
167
{
5909
    // Pop any items on the top of the stack, plus any objects we were going to
5910
    // capture on success:
5911
167
    Py_ssize_t pops = pc->on_top + PyList_GET_SIZE(pc->stores);
5912
167
    RETURN_IF_ERROR(ensure_fail_pop(c, pc, pops));
5913
167
    ADDOP_JUMP(c, loc, op, pc->fail_pop[pops]);
5914
167
    return SUCCESS;
5915
167
}
5916
5917
// Build all of the fail_pop blocks and reset fail_pop.
5918
static int
5919
emit_and_reset_fail_pop(compiler *c, location loc,
5920
                        pattern_context *pc)
5921
54
{
5922
54
    if (!pc->fail_pop_size) {
5923
3
        assert(pc->fail_pop == NULL);
5924
3
        return SUCCESS;
5925
3
    }
5926
116
    while (--pc->fail_pop_size) {
5927
65
        USE_LABEL(c, pc->fail_pop[pc->fail_pop_size]);
5928
65
        if (codegen_addop_noarg(INSTR_SEQUENCE(c), POP_TOP, loc) < 0) {
5929
0
            pc->fail_pop_size = 0;
5930
0
            PyMem_Free(pc->fail_pop);
5931
0
            pc->fail_pop = NULL;
5932
0
            return ERROR;
5933
0
        }
5934
65
    }
5935
51
    USE_LABEL(c, pc->fail_pop[0]);
5936
51
    PyMem_Free(pc->fail_pop);
5937
51
    pc->fail_pop = NULL;
5938
51
    return SUCCESS;
5939
51
}
5940
5941
static int
5942
codegen_error_duplicate_store(compiler *c, location loc, identifier n)
5943
8
{
5944
8
    return _PyCompile_Error(c, loc,
5945
8
        "multiple assignments to name %R in pattern", n);
5946
8
}
5947
5948
// Duplicate the effect of 3.10's ROT_* instructions using SWAPs.
5949
static int
5950
codegen_pattern_helper_rotate(compiler *c, location loc, Py_ssize_t count)
5951
168
{
5952
712
    while (1 < count) {
5953
544
        ADDOP_I(c, loc, SWAP, count--);
5954
544
    }
5955
168
    return SUCCESS;
5956
168
}
5957
5958
static int
5959
codegen_pattern_helper_store_name(compiler *c, location loc,
5960
                                  identifier n, pattern_context *pc)
5961
179
{
5962
179
    if (n == NULL) {
5963
3
        ADDOP(c, loc, POP_TOP);
5964
3
        return SUCCESS;
5965
3
    }
5966
    // Can't assign to the same name twice:
5967
176
    int duplicate = PySequence_Contains(pc->stores, n);
5968
176
    RETURN_IF_ERROR(duplicate);
5969
176
    if (duplicate) {
5970
8
        return codegen_error_duplicate_store(c, loc, n);
5971
8
    }
5972
    // Rotate this object underneath any items we need to preserve:
5973
168
    Py_ssize_t rotations = pc->on_top + PyList_GET_SIZE(pc->stores) + 1;
5974
168
    RETURN_IF_ERROR(codegen_pattern_helper_rotate(c, loc, rotations));
5975
168
    RETURN_IF_ERROR(PyList_Append(pc->stores, n));
5976
168
    return SUCCESS;
5977
168
}
5978
5979
5980
static int
5981
codegen_pattern_unpack_helper(compiler *c, location loc,
5982
                              asdl_pattern_seq *elts)
5983
66
{
5984
66
    Py_ssize_t n = asdl_seq_LEN(elts);
5985
66
    int seen_star = 0;
5986
284
    for (Py_ssize_t i = 0; i < n; i++) {
5987
218
        pattern_ty elt = asdl_seq_GET(elts, i);
5988
218
        if (elt->kind == MatchStar_kind && !seen_star) {
5989
7
            if ((i >= (1 << 8)) ||
5990
7
                (n-i-1 >= (INT_MAX >> 8))) {
5991
0
                return _PyCompile_Error(c, loc,
5992
0
                    "too many expressions in "
5993
0
                    "star-unpacking sequence pattern");
5994
0
            }
5995
7
            ADDOP_I(c, loc, UNPACK_EX, (i + ((n-i-1) << 8)));
5996
7
            seen_star = 1;
5997
7
        }
5998
211
        else if (elt->kind == MatchStar_kind) {
5999
0
            return _PyCompile_Error(c, loc,
6000
0
                "multiple starred expressions in sequence pattern");
6001
0
        }
6002
218
    }
6003
66
    if (!seen_star) {
6004
59
        ADDOP_I(c, loc, UNPACK_SEQUENCE, n);
6005
59
    }
6006
66
    return SUCCESS;
6007
66
}
6008
6009
static int
6010
pattern_helper_sequence_unpack(compiler *c, location loc,
6011
                               asdl_pattern_seq *patterns, Py_ssize_t star,
6012
                               pattern_context *pc)
6013
66
{
6014
66
    RETURN_IF_ERROR(codegen_pattern_unpack_helper(c, loc, patterns));
6015
66
    Py_ssize_t size = asdl_seq_LEN(patterns);
6016
    // We've now got a bunch of new subjects on the stack. They need to remain
6017
    // there after each subpattern match:
6018
66
    pc->on_top += size;
6019
247
    for (Py_ssize_t i = 0; i < size; i++) {
6020
        // One less item to keep track of each time we loop through:
6021
196
        pc->on_top--;
6022
196
        pattern_ty pattern = asdl_seq_GET(patterns, i);
6023
196
        RETURN_IF_ERROR(codegen_pattern_subpattern(c, pattern, pc));
6024
196
    }
6025
51
    return SUCCESS;
6026
66
}
6027
6028
// Like pattern_helper_sequence_unpack, but uses BINARY_OP/NB_SUBSCR instead of
6029
// UNPACK_SEQUENCE / UNPACK_EX. This is more efficient for patterns with a
6030
// starred wildcard like [first, *_] / [first, *_, last] / [*_, last] / etc.
6031
static int
6032
pattern_helper_sequence_subscr(compiler *c, location loc,
6033
                               asdl_pattern_seq *patterns, Py_ssize_t star,
6034
                               pattern_context *pc)
6035
0
{
6036
    // We need to keep the subject around for extracting elements:
6037
0
    pc->on_top++;
6038
0
    Py_ssize_t size = asdl_seq_LEN(patterns);
6039
0
    for (Py_ssize_t i = 0; i < size; i++) {
6040
0
        pattern_ty pattern = asdl_seq_GET(patterns, i);
6041
0
        if (WILDCARD_CHECK(pattern)) {
6042
0
            continue;
6043
0
        }
6044
0
        if (i == star) {
6045
0
            assert(WILDCARD_STAR_CHECK(pattern));
6046
0
            continue;
6047
0
        }
6048
0
        ADDOP_I(c, loc, COPY, 1);
6049
0
        if (i < star) {
6050
0
            ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromSsize_t(i));
6051
0
        }
6052
0
        else {
6053
            // The subject may not support negative indexing! Compute a
6054
            // nonnegative index:
6055
0
            ADDOP(c, loc, GET_LEN);
6056
0
            ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromSsize_t(size - i));
6057
0
            ADDOP_BINARY(c, loc, Sub);
6058
0
        }
6059
0
        ADDOP_I(c, loc, BINARY_OP, NB_SUBSCR);
6060
0
        RETURN_IF_ERROR(codegen_pattern_subpattern(c, pattern, pc));
6061
0
    }
6062
    // Pop the subject, we're done with it:
6063
0
    pc->on_top--;
6064
0
    ADDOP(c, loc, POP_TOP);
6065
0
    return SUCCESS;
6066
0
}
6067
6068
// Like codegen_pattern, but turn off checks for irrefutability.
6069
static int
6070
codegen_pattern_subpattern(compiler *c,
6071
                            pattern_ty p, pattern_context *pc)
6072
208
{
6073
208
    int allow_irrefutable = pc->allow_irrefutable;
6074
208
    pc->allow_irrefutable = 1;
6075
208
    RETURN_IF_ERROR(codegen_pattern(c, p, pc));
6076
191
    pc->allow_irrefutable = allow_irrefutable;
6077
191
    return SUCCESS;
6078
208
}
6079
6080
static int
6081
codegen_pattern_as(compiler *c, pattern_ty p, pattern_context *pc)
6082
180
{
6083
180
    assert(p->kind == MatchAs_kind);
6084
180
    if (p->v.MatchAs.pattern == NULL) {
6085
        // An irrefutable match:
6086
172
        if (!pc->allow_irrefutable) {
6087
7
            if (p->v.MatchAs.name) {
6088
5
                const char *e = "name capture %R makes remaining patterns unreachable";
6089
5
                return _PyCompile_Error(c, LOC(p), e, p->v.MatchAs.name);
6090
5
            }
6091
2
            const char *e = "wildcard makes remaining patterns unreachable";
6092
2
            return _PyCompile_Error(c, LOC(p), e);
6093
7
        }
6094
165
        return codegen_pattern_helper_store_name(c, LOC(p), p->v.MatchAs.name, pc);
6095
172
    }
6096
    // Need to make a copy for (possibly) storing later:
6097
8
    pc->on_top++;
6098
8
    ADDOP_I(c, LOC(p), COPY, 1);
6099
8
    RETURN_IF_ERROR(codegen_pattern(c, p->v.MatchAs.pattern, pc));
6100
    // Success! Store it:
6101
7
    pc->on_top--;
6102
7
    RETURN_IF_ERROR(codegen_pattern_helper_store_name(c, LOC(p), p->v.MatchAs.name, pc));
6103
4
    return SUCCESS;
6104
7
}
6105
6106
static int
6107
codegen_pattern_star(compiler *c, pattern_ty p, pattern_context *pc)
6108
7
{
6109
7
    assert(p->kind == MatchStar_kind);
6110
7
    RETURN_IF_ERROR(
6111
7
        codegen_pattern_helper_store_name(c, LOC(p), p->v.MatchStar.name, pc));
6112
6
    return SUCCESS;
6113
7
}
6114
6115
static int
6116
validate_kwd_attrs(compiler *c, asdl_identifier_seq *attrs, asdl_pattern_seq* patterns)
6117
0
{
6118
    // Any errors will point to the pattern rather than the arg name as the
6119
    // parser is only supplying identifiers rather than Name or keyword nodes
6120
0
    Py_ssize_t nattrs = asdl_seq_LEN(attrs);
6121
0
    for (Py_ssize_t i = 0; i < nattrs; i++) {
6122
0
        identifier attr = ((identifier)asdl_seq_GET(attrs, i));
6123
0
        for (Py_ssize_t j = i + 1; j < nattrs; j++) {
6124
0
            identifier other = ((identifier)asdl_seq_GET(attrs, j));
6125
0
            if (!PyUnicode_Compare(attr, other)) {
6126
0
                location loc = LOC((pattern_ty) asdl_seq_GET(patterns, j));
6127
0
                return _PyCompile_Error(c, loc, "attribute name repeated "
6128
0
                                                "in class pattern: %U", attr);
6129
0
            }
6130
0
        }
6131
0
    }
6132
0
    return SUCCESS;
6133
0
}
6134
6135
static int
6136
codegen_pattern_class(compiler *c, pattern_ty p, pattern_context *pc)
6137
7
{
6138
7
    assert(p->kind == MatchClass_kind);
6139
7
    asdl_pattern_seq *patterns = p->v.MatchClass.patterns;
6140
7
    asdl_identifier_seq *kwd_attrs = p->v.MatchClass.kwd_attrs;
6141
7
    asdl_pattern_seq *kwd_patterns = p->v.MatchClass.kwd_patterns;
6142
7
    Py_ssize_t nargs = asdl_seq_LEN(patterns);
6143
7
    Py_ssize_t nattrs = asdl_seq_LEN(kwd_attrs);
6144
7
    Py_ssize_t nkwd_patterns = asdl_seq_LEN(kwd_patterns);
6145
7
    if (nattrs != nkwd_patterns) {
6146
        // AST validator shouldn't let this happen, but if it does,
6147
        // just fail, don't crash out of the interpreter
6148
0
        const char * e = "kwd_attrs (%d) / kwd_patterns (%d) length mismatch in class pattern";
6149
0
        return _PyCompile_Error(c, LOC(p), e, nattrs, nkwd_patterns);
6150
0
    }
6151
7
    if (INT_MAX < nargs || INT_MAX < nargs + nattrs - 1) {
6152
0
        const char *e = "too many sub-patterns in class pattern %R";
6153
0
        return _PyCompile_Error(c, LOC(p), e, p->v.MatchClass.cls);
6154
0
    }
6155
7
    if (nattrs) {
6156
0
        RETURN_IF_ERROR(validate_kwd_attrs(c, kwd_attrs, kwd_patterns));
6157
0
    }
6158
7
    VISIT(c, expr, p->v.MatchClass.cls);
6159
7
    PyObject *attr_names = PyTuple_New(nattrs);
6160
7
    if (attr_names == NULL) {
6161
0
        return ERROR;
6162
0
    }
6163
7
    Py_ssize_t i;
6164
7
    for (i = 0; i < nattrs; i++) {
6165
0
        PyObject *name = asdl_seq_GET(kwd_attrs, i);
6166
0
        PyTuple_SET_ITEM(attr_names, i, Py_NewRef(name));
6167
0
    }
6168
7
    ADDOP_LOAD_CONST_NEW(c, LOC(p), attr_names);
6169
7
    ADDOP_I(c, LOC(p), MATCH_CLASS, nargs);
6170
7
    ADDOP_I(c, LOC(p), COPY, 1);
6171
7
    ADDOP_LOAD_CONST(c, LOC(p), Py_None);
6172
7
    ADDOP_I(c, LOC(p), IS_OP, 1);
6173
    // TOS is now a tuple of (nargs + nattrs) attributes (or None):
6174
7
    pc->on_top++;
6175
7
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6176
7
    ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, nargs + nattrs);
6177
7
    pc->on_top += nargs + nattrs - 1;
6178
17
    for (i = 0; i < nargs + nattrs; i++) {
6179
12
        pc->on_top--;
6180
12
        pattern_ty pattern;
6181
12
        if (i < nargs) {
6182
            // Positional:
6183
12
            pattern = asdl_seq_GET(patterns, i);
6184
12
        }
6185
0
        else {
6186
            // Keyword:
6187
0
            pattern = asdl_seq_GET(kwd_patterns, i - nargs);
6188
0
        }
6189
12
        if (WILDCARD_CHECK(pattern)) {
6190
0
            ADDOP(c, LOC(p), POP_TOP);
6191
0
            continue;
6192
0
        }
6193
12
        RETURN_IF_ERROR(codegen_pattern_subpattern(c, pattern, pc));
6194
12
    }
6195
    // Success! Pop the tuple of attributes:
6196
5
    return SUCCESS;
6197
7
}
6198
6199
static int
6200
codegen_pattern_mapping_key(compiler *c, PyObject *seen, pattern_ty p, Py_ssize_t i)
6201
0
{
6202
0
    asdl_expr_seq *keys = p->v.MatchMapping.keys;
6203
0
    asdl_pattern_seq *patterns = p->v.MatchMapping.patterns;
6204
0
    expr_ty key = asdl_seq_GET(keys, i);
6205
0
    if (key == NULL) {
6206
0
        const char *e = "can't use NULL keys in MatchMapping "
6207
0
                        "(set 'rest' parameter instead)";
6208
0
        location loc = LOC((pattern_ty) asdl_seq_GET(patterns, i));
6209
0
        return _PyCompile_Error(c, loc, e);
6210
0
    }
6211
6212
0
    if (key->kind == Constant_kind) {
6213
0
        int in_seen = PySet_Contains(seen, key->v.Constant.value);
6214
0
        RETURN_IF_ERROR(in_seen);
6215
0
        if (in_seen) {
6216
0
            const char *e = "mapping pattern checks duplicate key (%R)";
6217
0
            return _PyCompile_Error(c, LOC(p), e, key->v.Constant.value);
6218
0
        }
6219
0
        RETURN_IF_ERROR(PySet_Add(seen, key->v.Constant.value));
6220
0
    }
6221
0
    else if (key->kind != Attribute_kind) {
6222
0
        const char *e = "mapping pattern keys may only match literals and attribute lookups";
6223
0
        return _PyCompile_Error(c, LOC(p), e);
6224
0
    }
6225
0
    VISIT(c, expr, key);
6226
0
    return SUCCESS;
6227
0
}
6228
6229
static int
6230
codegen_pattern_mapping(compiler *c, pattern_ty p,
6231
                        pattern_context *pc)
6232
0
{
6233
0
    assert(p->kind == MatchMapping_kind);
6234
0
    asdl_expr_seq *keys = p->v.MatchMapping.keys;
6235
0
    asdl_pattern_seq *patterns = p->v.MatchMapping.patterns;
6236
0
    Py_ssize_t size = asdl_seq_LEN(keys);
6237
0
    Py_ssize_t npatterns = asdl_seq_LEN(patterns);
6238
0
    if (size != npatterns) {
6239
        // AST validator shouldn't let this happen, but if it does,
6240
        // just fail, don't crash out of the interpreter
6241
0
        const char * e = "keys (%d) / patterns (%d) length mismatch in mapping pattern";
6242
0
        return _PyCompile_Error(c, LOC(p), e, size, npatterns);
6243
0
    }
6244
    // We have a double-star target if "rest" is set
6245
0
    PyObject *star_target = p->v.MatchMapping.rest;
6246
    // We need to keep the subject on top during the mapping and length checks:
6247
0
    pc->on_top++;
6248
0
    ADDOP(c, LOC(p), MATCH_MAPPING);
6249
0
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6250
0
    if (!size && !star_target) {
6251
        // If the pattern is just "{}", we're done! Pop the subject:
6252
0
        pc->on_top--;
6253
0
        ADDOP(c, LOC(p), POP_TOP);
6254
0
        return SUCCESS;
6255
0
    }
6256
0
    if (size) {
6257
        // If the pattern has any keys in it, perform a length check:
6258
0
        ADDOP(c, LOC(p), GET_LEN);
6259
0
        ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size));
6260
0
        ADDOP_COMPARE(c, LOC(p), GtE);
6261
0
        RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6262
0
    }
6263
0
    if (INT_MAX < size - 1) {
6264
0
        return _PyCompile_Error(c, LOC(p), "too many sub-patterns in mapping pattern");
6265
0
    }
6266
    // Collect all of the keys into a tuple for MATCH_KEYS and
6267
    // **rest. They can either be dotted names or literals:
6268
6269
    // Maintaining a set of Constant_kind kind keys allows us to raise a
6270
    // SyntaxError in the case of duplicates.
6271
0
    PyObject *seen = PySet_New(NULL);
6272
0
    if (seen == NULL) {
6273
0
        return ERROR;
6274
0
    }
6275
0
    for (Py_ssize_t i = 0; i < size; i++) {
6276
0
        if (codegen_pattern_mapping_key(c, seen, p, i) < 0) {
6277
0
            Py_DECREF(seen);
6278
0
            return ERROR;
6279
0
        }
6280
0
    }
6281
0
    Py_DECREF(seen);
6282
6283
    // all keys have been checked; there are no duplicates
6284
6285
0
    ADDOP_I(c, LOC(p), BUILD_TUPLE, size);
6286
0
    ADDOP(c, LOC(p), MATCH_KEYS);
6287
    // There's now a tuple of keys and a tuple of values on top of the subject:
6288
0
    pc->on_top += 2;
6289
0
    ADDOP_I(c, LOC(p), COPY, 1);
6290
0
    ADDOP_LOAD_CONST(c, LOC(p), Py_None);
6291
0
    ADDOP_I(c, LOC(p), IS_OP, 1);
6292
0
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6293
    // So far so good. Use that tuple of values on the stack to match
6294
    // sub-patterns against:
6295
0
    ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, size);
6296
0
    pc->on_top += size - 1;
6297
0
    for (Py_ssize_t i = 0; i < size; i++) {
6298
0
        pc->on_top--;
6299
0
        pattern_ty pattern = asdl_seq_GET(patterns, i);
6300
0
        RETURN_IF_ERROR(codegen_pattern_subpattern(c, pattern, pc));
6301
0
    }
6302
    // If we get this far, it's a match! Whatever happens next should consume
6303
    // the tuple of keys and the subject:
6304
0
    pc->on_top -= 2;
6305
0
    if (star_target) {
6306
        // If we have a starred name, bind a dict of remaining items to it (this may
6307
        // seem a bit inefficient, but keys is rarely big enough to actually impact
6308
        // runtime):
6309
        // rest = dict(TOS1)
6310
        // for key in TOS:
6311
        //     del rest[key]
6312
0
        ADDOP_I(c, LOC(p), BUILD_MAP, 0);           // [subject, keys, empty]
6313
0
        ADDOP_I(c, LOC(p), SWAP, 3);                // [empty, keys, subject]
6314
0
        ADDOP_I(c, LOC(p), DICT_UPDATE, 2);         // [copy, keys]
6315
0
        ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, size);  // [copy, keys...]
6316
0
        while (size) {
6317
0
            ADDOP_I(c, LOC(p), COPY, 1 + size--);   // [copy, keys..., copy]
6318
0
            ADDOP_I(c, LOC(p), SWAP, 2);            // [copy, keys..., copy, key]
6319
0
            ADDOP(c, LOC(p), DELETE_SUBSCR);        // [copy, keys...]
6320
0
        }
6321
0
        RETURN_IF_ERROR(codegen_pattern_helper_store_name(c, LOC(p), star_target, pc));
6322
0
    }
6323
0
    else {
6324
0
        ADDOP(c, LOC(p), POP_TOP);  // Tuple of keys.
6325
0
        ADDOP(c, LOC(p), POP_TOP);  // Subject.
6326
0
    }
6327
0
    return SUCCESS;
6328
0
}
6329
6330
static int
6331
codegen_pattern_or(compiler *c, pattern_ty p, pattern_context *pc)
6332
6
{
6333
6
    assert(p->kind == MatchOr_kind);
6334
6
    NEW_JUMP_TARGET_LABEL(c, end);
6335
6
    Py_ssize_t size = asdl_seq_LEN(p->v.MatchOr.patterns);
6336
6
    assert(size > 1);
6337
    // We're going to be messing with pc. Keep the original info handy:
6338
6
    pattern_context old_pc = *pc;
6339
6
    Py_INCREF(pc->stores);
6340
    // control is the list of names bound by the first alternative. It is used
6341
    // for checking different name bindings in alternatives, and for correcting
6342
    // the order in which extracted elements are placed on the stack.
6343
6
    PyObject *control = NULL;
6344
    // NOTE: We can't use returning macros anymore! goto error on error.
6345
7
    for (Py_ssize_t i = 0; i < size; i++) {
6346
7
        pattern_ty alt = asdl_seq_GET(p->v.MatchOr.patterns, i);
6347
7
        PyObject *pc_stores = PyList_New(0);
6348
7
        if (pc_stores == NULL) {
6349
0
            goto error;
6350
0
        }
6351
7
        Py_SETREF(pc->stores, pc_stores);
6352
        // An irrefutable sub-pattern must be last, if it is allowed at all:
6353
7
        pc->allow_irrefutable = (i == size - 1) && old_pc.allow_irrefutable;
6354
7
        pc->fail_pop = NULL;
6355
7
        pc->fail_pop_size = 0;
6356
7
        pc->on_top = 0;
6357
7
        if (codegen_addop_i(INSTR_SEQUENCE(c), COPY, 1, LOC(alt)) < 0 ||
6358
7
            codegen_pattern(c, alt, pc) < 0) {
6359
5
            goto error;
6360
5
        }
6361
        // Success!
6362
2
        Py_ssize_t nstores = PyList_GET_SIZE(pc->stores);
6363
2
        if (!i) {
6364
            // This is the first alternative, so save its stores as a "control"
6365
            // for the others (they can't bind a different set of names, and
6366
            // might need to be reordered):
6367
1
            assert(control == NULL);
6368
1
            control = Py_NewRef(pc->stores);
6369
1
        }
6370
1
        else if (nstores != PyList_GET_SIZE(control)) {
6371
1
            goto diff;
6372
1
        }
6373
0
        else if (nstores) {
6374
            // There were captures. Check to see if we differ from control:
6375
0
            Py_ssize_t icontrol = nstores;
6376
0
            while (icontrol--) {
6377
0
                PyObject *name = PyList_GET_ITEM(control, icontrol);
6378
0
                Py_ssize_t istores = PySequence_Index(pc->stores, name);
6379
0
                if (istores < 0) {
6380
0
                    PyErr_Clear();
6381
0
                    goto diff;
6382
0
                }
6383
0
                if (icontrol != istores) {
6384
                    // Reorder the names on the stack to match the order of the
6385
                    // names in control. There's probably a better way of doing
6386
                    // this; the current solution is potentially very
6387
                    // inefficient when each alternative subpattern binds lots
6388
                    // of names in different orders. It's fine for reasonable
6389
                    // cases, though, and the peephole optimizer will ensure
6390
                    // that the final code is as efficient as possible.
6391
0
                    assert(istores < icontrol);
6392
0
                    Py_ssize_t rotations = istores + 1;
6393
                    // Perform the same rotation on pc->stores:
6394
0
                    PyObject *rotated = PyList_GetSlice(pc->stores, 0,
6395
0
                                                        rotations);
6396
0
                    if (rotated == NULL ||
6397
0
                        PyList_SetSlice(pc->stores, 0, rotations, NULL) ||
6398
0
                        PyList_SetSlice(pc->stores, icontrol - istores,
6399
0
                                        icontrol - istores, rotated))
6400
0
                    {
6401
0
                        Py_XDECREF(rotated);
6402
0
                        goto error;
6403
0
                    }
6404
0
                    Py_DECREF(rotated);
6405
                    // That just did:
6406
                    // rotated = pc_stores[:rotations]
6407
                    // del pc_stores[:rotations]
6408
                    // pc_stores[icontrol-istores:icontrol-istores] = rotated
6409
                    // Do the same thing to the stack, using several
6410
                    // rotations:
6411
0
                    while (rotations--) {
6412
0
                        if (codegen_pattern_helper_rotate(c, LOC(alt), icontrol + 1) < 0) {
6413
0
                            goto error;
6414
0
                        }
6415
0
                    }
6416
0
                }
6417
0
            }
6418
0
        }
6419
2
        assert(control);
6420
1
        if (codegen_addop_j(INSTR_SEQUENCE(c), LOC(alt), JUMP, end) < 0 ||
6421
1
            emit_and_reset_fail_pop(c, LOC(alt), pc) < 0)
6422
0
        {
6423
0
            goto error;
6424
0
        }
6425
1
    }
6426
0
    Py_DECREF(pc->stores);
6427
0
    *pc = old_pc;
6428
0
    Py_INCREF(pc->stores);
6429
    // Need to NULL this for the PyMem_Free call in the error block.
6430
0
    old_pc.fail_pop = NULL;
6431
    // No match. Pop the remaining copy of the subject and fail:
6432
0
    if (codegen_addop_noarg(INSTR_SEQUENCE(c), POP_TOP, LOC(p)) < 0 ||
6433
0
        jump_to_fail_pop(c, LOC(p), pc, JUMP) < 0) {
6434
0
        goto error;
6435
0
    }
6436
6437
0
    USE_LABEL(c, end);
6438
0
    Py_ssize_t nstores = PyList_GET_SIZE(control);
6439
    // There's a bunch of stuff on the stack between where the new stores
6440
    // are and where they need to be:
6441
    // - The other stores.
6442
    // - A copy of the subject.
6443
    // - Anything else that may be on top of the stack.
6444
    // - Any previous stores we've already stashed away on the stack.
6445
0
    Py_ssize_t nrots = nstores + 1 + pc->on_top + PyList_GET_SIZE(pc->stores);
6446
0
    for (Py_ssize_t i = 0; i < nstores; i++) {
6447
        // Rotate this capture to its proper place on the stack:
6448
0
        if (codegen_pattern_helper_rotate(c, LOC(p), nrots) < 0) {
6449
0
            goto error;
6450
0
        }
6451
        // Update the list of previous stores with this new name, checking for
6452
        // duplicates:
6453
0
        PyObject *name = PyList_GET_ITEM(control, i);
6454
0
        int dupe = PySequence_Contains(pc->stores, name);
6455
0
        if (dupe < 0) {
6456
0
            goto error;
6457
0
        }
6458
0
        if (dupe) {
6459
0
            codegen_error_duplicate_store(c, LOC(p), name);
6460
0
            goto error;
6461
0
        }
6462
0
        if (PyList_Append(pc->stores, name)) {
6463
0
            goto error;
6464
0
        }
6465
0
    }
6466
0
    Py_DECREF(old_pc.stores);
6467
0
    Py_DECREF(control);
6468
    // NOTE: Returning macros are safe again.
6469
    // Pop the copy of the subject:
6470
0
    ADDOP(c, LOC(p), POP_TOP);
6471
0
    return SUCCESS;
6472
1
diff:
6473
1
    _PyCompile_Error(c, LOC(p), "alternative patterns bind different names");
6474
6
error:
6475
6
    PyMem_Free(old_pc.fail_pop);
6476
6
    Py_DECREF(old_pc.stores);
6477
6
    Py_XDECREF(control);
6478
6
    return ERROR;
6479
1
}
6480
6481
6482
static int
6483
codegen_pattern_sequence(compiler *c, pattern_ty p,
6484
                         pattern_context *pc)
6485
67
{
6486
67
    assert(p->kind == MatchSequence_kind);
6487
67
    asdl_pattern_seq *patterns = p->v.MatchSequence.patterns;
6488
67
    Py_ssize_t size = asdl_seq_LEN(patterns);
6489
67
    Py_ssize_t star = -1;
6490
67
    int only_wildcard = 1;
6491
67
    int star_wildcard = 0;
6492
    // Find a starred name, if it exists. There may be at most one:
6493
289
    for (Py_ssize_t i = 0; i < size; i++) {
6494
223
        pattern_ty pattern = asdl_seq_GET(patterns, i);
6495
223
        if (pattern->kind == MatchStar_kind) {
6496
9
            if (star >= 0) {
6497
1
                const char *e = "multiple starred names in sequence pattern";
6498
1
                return _PyCompile_Error(c, LOC(p), e);
6499
1
            }
6500
8
            star_wildcard = WILDCARD_STAR_CHECK(pattern);
6501
8
            only_wildcard &= star_wildcard;
6502
8
            star = i;
6503
8
            continue;
6504
9
        }
6505
214
        only_wildcard &= WILDCARD_CHECK(pattern);
6506
214
    }
6507
    // We need to keep the subject on top during the sequence and length checks:
6508
66
    pc->on_top++;
6509
66
    ADDOP(c, LOC(p), MATCH_SEQUENCE);
6510
66
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6511
66
    if (star < 0) {
6512
        // No star: len(subject) == size
6513
59
        ADDOP(c, LOC(p), GET_LEN);
6514
59
        ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size));
6515
59
        ADDOP_COMPARE(c, LOC(p), Eq);
6516
59
        RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6517
59
    }
6518
7
    else if (size > 1) {
6519
        // Star: len(subject) >= size - 1
6520
7
        ADDOP(c, LOC(p), GET_LEN);
6521
7
        ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size - 1));
6522
7
        ADDOP_COMPARE(c, LOC(p), GtE);
6523
7
        RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6524
7
    }
6525
    // Whatever comes next should consume the subject:
6526
66
    pc->on_top--;
6527
66
    if (only_wildcard) {
6528
        // Patterns like: [] / [_] / [_, _] / [*_] / [_, *_] / [_, _, *_] / etc.
6529
0
        ADDOP(c, LOC(p), POP_TOP);
6530
0
    }
6531
66
    else if (star_wildcard) {
6532
0
        RETURN_IF_ERROR(pattern_helper_sequence_subscr(c, LOC(p), patterns, star, pc));
6533
0
    }
6534
66
    else {
6535
66
        RETURN_IF_ERROR(pattern_helper_sequence_unpack(c, LOC(p), patterns, star, pc));
6536
66
    }
6537
51
    return SUCCESS;
6538
66
}
6539
6540
static int
6541
codegen_pattern_value(compiler *c, pattern_ty p, pattern_context *pc)
6542
21
{
6543
21
    assert(p->kind == MatchValue_kind);
6544
21
    expr_ty value = p->v.MatchValue.value;
6545
21
    if (!MATCH_VALUE_EXPR(value)) {
6546
1
        const char *e = "patterns may only match literals and attribute lookups";
6547
1
        return _PyCompile_Error(c, LOC(p), e);
6548
1
    }
6549
20
    VISIT(c, expr, value);
6550
20
    ADDOP_COMPARE(c, LOC(p), Eq);
6551
20
    ADDOP(c, LOC(p), TO_BOOL);
6552
20
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6553
20
    return SUCCESS;
6554
20
}
6555
6556
static int
6557
codegen_pattern_singleton(compiler *c, pattern_ty p, pattern_context *pc)
6558
8
{
6559
8
    assert(p->kind == MatchSingleton_kind);
6560
8
    ADDOP_LOAD_CONST(c, LOC(p), p->v.MatchSingleton.value);
6561
8
    ADDOP_COMPARE(c, LOC(p), Is);
6562
8
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6563
8
    return SUCCESS;
6564
8
}
6565
6566
static int
6567
codegen_pattern(compiler *c, pattern_ty p, pattern_context *pc)
6568
296
{
6569
296
    switch (p->kind) {
6570
21
        case MatchValue_kind:
6571
21
            return codegen_pattern_value(c, p, pc);
6572
8
        case MatchSingleton_kind:
6573
8
            return codegen_pattern_singleton(c, p, pc);
6574
67
        case MatchSequence_kind:
6575
67
            return codegen_pattern_sequence(c, p, pc);
6576
0
        case MatchMapping_kind:
6577
0
            return codegen_pattern_mapping(c, p, pc);
6578
7
        case MatchClass_kind:
6579
7
            return codegen_pattern_class(c, p, pc);
6580
7
        case MatchStar_kind:
6581
7
            return codegen_pattern_star(c, p, pc);
6582
180
        case MatchAs_kind:
6583
180
            return codegen_pattern_as(c, p, pc);
6584
6
        case MatchOr_kind:
6585
6
            return codegen_pattern_or(c, p, pc);
6586
296
    }
6587
    // AST validator shouldn't let this happen, but if it does,
6588
    // just fail, don't crash out of the interpreter
6589
0
    const char *e = "invalid match pattern node in AST (kind=%d)";
6590
0
    return _PyCompile_Error(c, LOC(p), e, p->kind);
6591
296
}
6592
6593
static int
6594
codegen_match_inner(compiler *c, stmt_ty s, pattern_context *pc)
6595
46
{
6596
46
    VISIT(c, expr, s->v.Match.subject);
6597
46
    NEW_JUMP_TARGET_LABEL(c, end);
6598
46
    Py_ssize_t cases = asdl_seq_LEN(s->v.Match.cases);
6599
46
    assert(cases > 0);
6600
46
    match_case_ty m = asdl_seq_GET(s->v.Match.cases, cases - 1);
6601
46
    int has_default = WILDCARD_CHECK(m->pattern) && 1 < cases;
6602
99
    for (Py_ssize_t i = 0; i < cases - has_default; i++) {
6603
73
        m = asdl_seq_GET(s->v.Match.cases, i);
6604
        // Only copy the subject if we're *not* on the last case:
6605
73
        if (i != cases - has_default - 1) {
6606
37
            ADDOP_I(c, LOC(m->pattern), COPY, 1);
6607
37
        }
6608
73
        pc->stores = PyList_New(0);
6609
73
        if (pc->stores == NULL) {
6610
0
            return ERROR;
6611
0
        }
6612
        // Irrefutable cases must be either guarded, last, or both:
6613
73
        pc->allow_irrefutable = m->guard != NULL || i == cases - 1;
6614
73
        pc->fail_pop = NULL;
6615
73
        pc->fail_pop_size = 0;
6616
73
        pc->on_top = 0;
6617
        // NOTE: Can't use returning macros here (they'll leak pc->stores)!
6618
73
        if (codegen_pattern(c, m->pattern, pc) < 0) {
6619
18
            Py_DECREF(pc->stores);
6620
18
            return ERROR;
6621
18
        }
6622
73
        assert(!pc->on_top);
6623
        // It's a match! Store all of the captured names (they're on the stack).
6624
55
        Py_ssize_t nstores = PyList_GET_SIZE(pc->stores);
6625
178
        for (Py_ssize_t n = 0; n < nstores; n++) {
6626
123
            PyObject *name = PyList_GET_ITEM(pc->stores, n);
6627
123
            if (codegen_nameop(c, LOC(m->pattern), name, Store) < 0) {
6628
0
                Py_DECREF(pc->stores);
6629
0
                return ERROR;
6630
0
            }
6631
123
        }
6632
55
        Py_DECREF(pc->stores);
6633
        // NOTE: Returning macros are safe again.
6634
55
        if (m->guard) {
6635
1
            RETURN_IF_ERROR(ensure_fail_pop(c, pc, 0));
6636
1
            RETURN_IF_ERROR(codegen_jump_if(c, LOC(m->pattern), m->guard, pc->fail_pop[0], 0));
6637
1
        }
6638
        // Success! Pop the subject off, we're done with it:
6639
55
        if (i != cases - has_default - 1) {
6640
            /* Use the next location to give better locations for branch events */
6641
27
            ADDOP(c, NEXT_LOCATION, POP_TOP);
6642
27
        }
6643
55
        VISIT_SEQ(c, stmt, m->body);
6644
53
        ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
6645
        // If the pattern fails to match, we want the line number of the
6646
        // cleanup to be associated with the failed pattern, not the last line
6647
        // of the body
6648
53
        RETURN_IF_ERROR(emit_and_reset_fail_pop(c, LOC(m->pattern), pc));
6649
53
    }
6650
26
    if (has_default) {
6651
        // A trailing "case _" is common, and lets us save a bit of redundant
6652
        // pushing and popping in the loop above:
6653
1
        m = asdl_seq_GET(s->v.Match.cases, cases - 1);
6654
1
        if (cases == 1) {
6655
            // No matches. Done with the subject:
6656
0
            ADDOP(c, LOC(m->pattern), POP_TOP);
6657
0
        }
6658
1
        else {
6659
            // Show line coverage for default case (it doesn't create bytecode)
6660
1
            ADDOP(c, LOC(m->pattern), NOP);
6661
1
        }
6662
1
        if (m->guard) {
6663
0
            RETURN_IF_ERROR(codegen_jump_if(c, LOC(m->pattern), m->guard, end, 0));
6664
0
        }
6665
1
        VISIT_SEQ(c, stmt, m->body);
6666
1
    }
6667
26
    USE_LABEL(c, end);
6668
26
    return SUCCESS;
6669
26
}
6670
6671
static int
6672
codegen_match(compiler *c, stmt_ty s)
6673
46
{
6674
46
    pattern_context pc;
6675
46
    pc.fail_pop = NULL;
6676
46
    int result = codegen_match_inner(c, s, &pc);
6677
46
    PyMem_Free(pc.fail_pop);
6678
46
    return result;
6679
46
}
6680
6681
#undef WILDCARD_CHECK
6682
#undef WILDCARD_STAR_CHECK
6683
6684
6685
int
6686
_PyCodegen_AddReturnAtEnd(compiler *c, int addNone)
6687
21.0k
{
6688
    /* Make sure every instruction stream that falls off the end returns None.
6689
     * This also ensures that no jump target offsets are out of bounds.
6690
     */
6691
21.0k
    if (addNone) {
6692
17.6k
        ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
6693
17.6k
    }
6694
21.0k
    ADDOP(c, NO_LOCATION, RETURN_VALUE);
6695
21.0k
    return SUCCESS;
6696
21.0k
}