Coverage Report

Created: 2025-12-14 07:07

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