Coverage Report

Created: 2025-11-24 06:34

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
9.43k
#define COMP_GENEXP   0
41
4.43k
#define COMP_LISTCOMP 1
42
3.43k
#define COMP_SETCOMP  2
43
1.74k
#define COMP_DICTCOMP 3
44
45
#undef SUCCESS
46
#undef ERROR
47
15.9M
#define SUCCESS 0
48
5.19k
#define ERROR -1
49
50
#define RETURN_IF_ERROR(X)  \
51
9.17M
    do {                    \
52
9.17M
        if ((X) == -1) {    \
53
4.15k
            return ERROR;   \
54
4.15k
        }                   \
55
9.17M
    } while (0)
56
57
#define RETURN_IF_ERROR_IN_SCOPE(C, CALL)   \
58
124k
    do {                                    \
59
124k
        if ((CALL) < 0) {                   \
60
92
            _PyCompile_ExitScope((C));      \
61
92
            return ERROR;                   \
62
92
        }                                   \
63
124k
    } while (0)
64
65
struct _PyCompiler;
66
typedef struct _PyCompiler compiler;
67
68
224k
#define INSTR_SEQUENCE(C) _PyCompile_InstrSequence(C)
69
53.9k
#define FUTURE_FEATURES(C) _PyCompile_FutureFeatures(C)
70
6.46k
#define SYMTABLE(C) _PyCompile_Symtable(C)
71
776k
#define SYMTABLE_ENTRY(C) _PyCompile_SymtableEntry(C)
72
2.56k
#define OPTIMIZATION_LEVEL(C) _PyCompile_OptimizationLevel(C)
73
97.1k
#define IS_INTERACTIVE_TOP_LEVEL(C) _PyCompile_IsInteractiveTopLevel(C)
74
31.5k
#define SCOPE_TYPE(C) _PyCompile_ScopeType(C)
75
#define QUALNAME(C) _PyCompile_Qualname(C)
76
107k
#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
50.4k
    ((const _Py_SourceLocation){(LNO), (END_LNO), (COL), (END_COL)})
87
88
2.35M
#define LOC(x) SRC_LOCATION_FROM_AST(x)
89
90
#define NEW_JUMP_TARGET_LABEL(C, NAME) \
91
213k
    jump_target_label NAME = _PyInstructionSequence_NewLabel(INSTR_SEQUENCE(C)); \
92
213k
    if (!IS_JUMP_TARGET_LABEL(NAME)) { \
93
0
        return ERROR; \
94
0
    }
95
96
#define USE_LABEL(C, LBL) \
97
208k
    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
12.8k
_Py_CArray_Init(_Py_c_array_t* array, int item_size, int initial_num_entries) {
111
12.8k
    memset(array, 0, sizeof(_Py_c_array_t));
112
12.8k
    array->item_size = item_size;
113
12.8k
    array->initial_num_entries = initial_num_entries;
114
12.8k
    return 0;
115
12.8k
}
116
117
void
118
_Py_CArray_Fini(_Py_c_array_t* array)
119
12.8k
{
120
12.8k
    if (array->array) {
121
2.20k
        PyMem_Free(array->array);
122
2.20k
        array->allocated_entries = 0;
123
2.20k
    }
124
12.8k
}
125
126
int
127
_Py_CArray_EnsureCapacity(_Py_c_array_t *c_array, int idx)
128
11.3M
{
129
11.3M
    void *arr = c_array->array;
130
11.3M
    int alloc = c_array->allocated_entries;
131
11.3M
    if (arr == NULL) {
132
499k
        int new_alloc = c_array->initial_num_entries;
133
499k
        if (idx >= new_alloc) {
134
66
            new_alloc = idx + c_array->initial_num_entries;
135
66
        }
136
499k
        arr = PyMem_Calloc(new_alloc, c_array->item_size);
137
499k
        if (arr == NULL) {
138
0
            PyErr_NoMemory();
139
0
            return ERROR;
140
0
        }
141
499k
        alloc = new_alloc;
142
499k
    }
143
10.8M
    else if (idx >= alloc) {
144
73.3k
        size_t oldsize = alloc * c_array->item_size;
145
73.3k
        int new_alloc = alloc << 1;
146
73.3k
        if (idx >= new_alloc) {
147
1
            new_alloc = idx + c_array->initial_num_entries;
148
1
        }
149
73.3k
        size_t newsize = new_alloc * c_array->item_size;
150
151
73.3k
        if (oldsize > (SIZE_MAX >> 1)) {
152
0
            PyErr_NoMemory();
153
0
            return ERROR;
154
0
        }
155
156
73.3k
        assert(newsize > 0);
157
73.3k
        void *tmp = PyMem_Realloc(arr, newsize);
158
73.3k
        if (tmp == NULL) {
159
0
            PyErr_NoMemory();
160
0
            return ERROR;
161
0
        }
162
73.3k
        alloc = new_alloc;
163
73.3k
        arr = tmp;
164
73.3k
        memset((char *)arr + oldsize, 0, newsize - oldsize);
165
73.3k
    }
166
167
11.3M
    c_array->array = arr;
168
11.3M
    c_array->allocated_entries = alloc;
169
11.3M
    return SUCCESS;
170
11.3M
}
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
2.96M
{
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
2.96M
    int oparg_ = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int);
265
2.96M
    assert(!IS_ASSEMBLER_OPCODE(opcode));
266
2.96M
    return _PyInstructionSequence_Addop(seq, opcode, oparg_, loc);
267
2.96M
}
268
269
#define ADDOP_I(C, LOC, OP, O) \
270
2.95M
    RETURN_IF_ERROR(codegen_addop_i(INSTR_SEQUENCE(C), (OP), (O), (LOC)))
271
272
#define ADDOP_I_IN_SCOPE(C, LOC, OP, O) \
273
4.77k
    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
759k
{
278
759k
    assert(!OPCODE_HAS_ARG(opcode));
279
759k
    assert(!IS_ASSEMBLER_OPCODE(opcode));
280
759k
    return _PyInstructionSequence_Addop(seq, opcode, 0, loc);
281
759k
}
282
283
#define ADDOP(C, LOC, OP) \
284
734k
    RETURN_IF_ERROR(codegen_addop_noarg(INSTR_SEQUENCE(C), (OP), (LOC)))
285
286
#define ADDOP_IN_SCOPE(C, LOC, OP) \
287
17.4k
    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
946k
{
292
946k
    Py_ssize_t arg = _PyCompile_AddConst(c, o);
293
946k
    if (arg < 0) {
294
0
        return ERROR;
295
0
    }
296
946k
    ADDOP_I(c, loc, LOAD_CONST, arg);
297
946k
    return SUCCESS;
298
946k
}
299
300
#define ADDOP_LOAD_CONST(C, LOC, O) \
301
864k
    RETURN_IF_ERROR(codegen_addop_load_const((C), (LOC), (O)))
302
303
#define ADDOP_LOAD_CONST_IN_SCOPE(C, LOC, O) \
304
1.04k
    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
81.0k
    do {                                                                \
309
81.0k
        PyObject *__new_const = (O);                                    \
310
81.0k
        if (__new_const == NULL) {                                      \
311
0
            return ERROR;                                               \
312
0
        }                                                               \
313
81.0k
        if (codegen_addop_load_const((C), (LOC), __new_const) < 0) {    \
314
0
            Py_DECREF(__new_const);                                     \
315
0
            return ERROR;                                               \
316
0
        }                                                               \
317
81.0k
        Py_DECREF(__new_const);                                         \
318
81.0k
    } while (0)
319
320
static int
321
codegen_addop_o(compiler *c, location loc,
322
                int opcode, PyObject *dict, PyObject *o)
323
107k
{
324
107k
    Py_ssize_t arg = _PyCompile_DictAddObj(dict, o);
325
107k
    RETURN_IF_ERROR(arg);
326
107k
    ADDOP_I(c, loc, opcode, arg);
327
107k
    return SUCCESS;
328
107k
}
329
330
#define ADDOP_N(C, LOC, OP, O, TYPE)                                    \
331
105k
    do {                                                                \
332
105k
        assert(!OPCODE_HAS_CONST(OP)); /* use ADDOP_LOAD_CONST_NEW */   \
333
105k
        int ret = codegen_addop_o((C), (LOC), (OP),                     \
334
105k
                                  METADATA(C)->u_ ## TYPE, (O));        \
335
105k
        Py_DECREF((O));                                                 \
336
105k
        RETURN_IF_ERROR(ret);                                           \
337
105k
    } while (0)
338
339
#define ADDOP_N_IN_SCOPE(C, LOC, OP, O, TYPE)                           \
340
1.71k
    do {                                                                \
341
1.71k
        assert(!OPCODE_HAS_CONST(OP)); /* use ADDOP_LOAD_CONST_NEW */   \
342
1.71k
        int ret = codegen_addop_o((C), (LOC), (OP),                     \
343
1.71k
                                  METADATA(C)->u_ ## TYPE, (O));        \
344
1.71k
        Py_DECREF((O));                                                 \
345
1.71k
        RETURN_IF_ERROR_IN_SCOPE((C), ret);                             \
346
1.71k
    } while (0)
347
348
85.4k
#define LOAD_METHOD -1
349
85.4k
#define LOAD_SUPER_METHOD -2
350
85.4k
#define LOAD_ZERO_SUPER_ATTR -3
351
85.4k
#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
85.4k
{
357
85.4k
    PyObject *mangled = _PyCompile_MaybeMangle(c, o);
358
85.4k
    if (!mangled) {
359
0
        return ERROR;
360
0
    }
361
85.4k
    Py_ssize_t arg = _PyCompile_DictAddObj(dict, mangled);
362
85.4k
    Py_DECREF(mangled);
363
85.4k
    if (arg < 0) {
364
0
        return ERROR;
365
0
    }
366
85.4k
    if (opcode == LOAD_ATTR) {
367
14.5k
        arg <<= 1;
368
14.5k
    }
369
85.4k
    if (opcode == LOAD_METHOD) {
370
984
        opcode = LOAD_ATTR;
371
984
        arg <<= 1;
372
984
        arg |= 1;
373
984
    }
374
85.4k
    if (opcode == LOAD_SUPER_ATTR) {
375
443
        arg <<= 2;
376
443
        arg |= 2;
377
443
    }
378
85.4k
    if (opcode == LOAD_SUPER_METHOD) {
379
1
        opcode = LOAD_SUPER_ATTR;
380
1
        arg <<= 2;
381
1
        arg |= 3;
382
1
    }
383
85.4k
    if (opcode == LOAD_ZERO_SUPER_ATTR) {
384
0
        opcode = LOAD_SUPER_ATTR;
385
0
        arg <<= 2;
386
0
    }
387
85.4k
    if (opcode == LOAD_ZERO_SUPER_METHOD) {
388
0
        opcode = LOAD_SUPER_ATTR;
389
0
        arg <<= 2;
390
0
        arg |= 1;
391
0
    }
392
85.4k
    ADDOP_I(c, loc, opcode, arg);
393
85.4k
    return SUCCESS;
394
85.4k
}
395
396
#define ADDOP_NAME(C, LOC, OP, O, TYPE) \
397
85.4k
    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
231k
{
403
231k
    assert(IS_JUMP_TARGET_LABEL(target));
404
231k
    assert(HAS_TARGET(opcode));
405
231k
    assert(!IS_ASSEMBLER_OPCODE(opcode));
406
231k
    return _PyInstructionSequence_Addop(seq, opcode, target.id, loc);
407
231k
}
408
409
#define ADDOP_JUMP(C, LOC, OP, O) \
410
229k
    RETURN_IF_ERROR(codegen_addop_j(INSTR_SEQUENCE(C), (LOC), (OP), (O)))
411
412
#define ADDOP_COMPARE(C, LOC, CMP) \
413
78.2k
    RETURN_IF_ERROR(codegen_addcompare((C), (LOC), (cmpop_ty)(CMP)))
414
415
#define ADDOP_BINARY(C, LOC, BINOP) \
416
535k
    RETURN_IF_ERROR(addop_binary((C), (LOC), (BINOP), false))
417
418
#define ADDOP_INPLACE(C, LOC, BINOP) \
419
2.53k
    RETURN_IF_ERROR(addop_binary((C), (LOC), (BINOP), true))
420
421
#define ADD_YIELD_FROM(C, LOC, await) \
422
16.0k
    RETURN_IF_ERROR(codegen_add_yield_from((C), (LOC), (await)))
423
424
#define POP_EXCEPT_AND_RERAISE(C, LOC) \
425
10.3k
    RETURN_IF_ERROR(codegen_pop_except_and_reraise((C), (LOC)))
426
427
#define ADDOP_YIELD(C, LOC) \
428
1.80k
    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.99M
    RETURN_IF_ERROR(codegen_visit_ ## TYPE((C), (V)))
436
437
#define VISIT_IN_SCOPE(C, TYPE, V) \
438
24.7k
    RETURN_IF_ERROR_IN_SCOPE((C), codegen_visit_ ## TYPE((C), (V)))
439
440
#define VISIT_SEQ(C, TYPE, SEQ)                                             \
441
23.7k
    do {                                                                    \
442
23.7k
        asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */    \
443
99.7k
        for (int _i = 0; _i < asdl_seq_LEN(seq); _i++) {                    \
444
76.1k
            TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i);           \
445
76.1k
            RETURN_IF_ERROR(codegen_visit_ ## TYPE((C), elt));              \
446
76.1k
        }                                                                   \
447
23.7k
    } 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
9.28k
{
464
9.28k
    ADDOP_LOAD_CONST(c, loc, Py_None);
465
9.28k
    ADDOP_LOAD_CONST(c, loc, Py_None);
466
9.28k
    ADDOP_LOAD_CONST(c, loc, Py_None);
467
9.28k
    ADDOP_I(c, loc, CALL, 3);
468
9.28k
    return SUCCESS;
469
9.28k
}
470
471
static int
472
codegen_add_yield_from(compiler *c, location loc, int await)
473
16.0k
{
474
16.0k
    NEW_JUMP_TARGET_LABEL(c, send);
475
16.0k
    NEW_JUMP_TARGET_LABEL(c, fail);
476
16.0k
    NEW_JUMP_TARGET_LABEL(c, exit);
477
478
16.0k
    USE_LABEL(c, send);
479
16.0k
    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
16.0k
    ADDOP_JUMP(c, loc, SETUP_FINALLY, fail);
483
16.0k
    ADDOP_I(c, loc, YIELD_VALUE, 1);
484
16.0k
    ADDOP(c, NO_LOCATION, POP_BLOCK);
485
16.0k
    ADDOP_I(c, loc, RESUME, await ? RESUME_AFTER_AWAIT : RESUME_AFTER_YIELD_FROM);
486
16.0k
    ADDOP_JUMP(c, loc, JUMP_NO_INTERRUPT, send);
487
488
16.0k
    USE_LABEL(c, fail);
489
16.0k
    ADDOP(c, loc, CLEANUP_THROW);
490
491
16.0k
    USE_LABEL(c, exit);
492
16.0k
    ADDOP(c, loc, END_SEND);
493
16.0k
    return SUCCESS;
494
16.0k
}
495
496
static int
497
codegen_pop_except_and_reraise(compiler *c, location loc)
498
10.3k
{
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
10.3k
    ADDOP_I(c, loc, COPY, 3);
507
10.3k
    ADDOP(c, loc, POP_EXCEPT);
508
10.3k
    ADDOP_I(c, loc, RERAISE, 1);
509
10.3k
    return SUCCESS;
510
10.3k
}
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
1.72k
{
521
1.72k
    switch (info->fb_type) {
522
19
        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
283
        case COMPILE_FBLOCK_STOP_ITERATION:
527
283
            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
3
        case COMPILE_FBLOCK_FINALLY_TRY:
551
            /* This POP_BLOCK gets the line number of the unwinding statement */
552
3
            ADDOP(c, *ploc, POP_BLOCK);
553
3
            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
3
            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
75
        case COMPILE_FBLOCK_WITH:
582
1.43k
        case COMPILE_FBLOCK_ASYNC_WITH:
583
1.43k
            *ploc = info->fb_loc;
584
1.43k
            ADDOP(c, *ploc, POP_BLOCK);
585
1.43k
            if (preserve_tos) {
586
111
                ADDOP_I(c, *ploc, SWAP, 3);
587
111
                ADDOP_I(c, *ploc, SWAP, 2);
588
111
            }
589
1.43k
            RETURN_IF_ERROR(codegen_call_exit_with_nones(c, *ploc));
590
1.43k
            if (info->fb_type == COMPILE_FBLOCK_ASYNC_WITH) {
591
1.36k
                ADDOP_I(c, *ploc, GET_AWAITABLE, 2);
592
1.36k
                ADDOP_LOAD_CONST(c, *ploc, Py_None);
593
1.36k
                ADD_YIELD_FROM(c, *ploc, 1);
594
1.36k
            }
595
1.43k
            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.43k
            *ploc = NO_LOCATION;
600
1.43k
            return SUCCESS;
601
602
4
        case COMPILE_FBLOCK_HANDLER_CLEANUP: {
603
4
            if (info->fb_datum) {
604
0
                ADDOP(c, *ploc, POP_BLOCK);
605
0
            }
606
4
            if (preserve_tos) {
607
0
                ADDOP_I(c, *ploc, SWAP, 2);
608
0
            }
609
4
            ADDOP(c, *ploc, POP_BLOCK);
610
4
            ADDOP(c, *ploc, POP_EXCEPT);
611
4
            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
4
            return SUCCESS;
617
4
        }
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
1.72k
    }
626
1.72k
    Py_UNREACHABLE();
627
1.72k
}
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.10k
{
634
2.10k
    fblockinfo *top = _PyCompile_TopFBlock(c);
635
2.10k
    if (top == NULL) {
636
321
        return SUCCESS;
637
321
    }
638
1.78k
    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
1.78k
    if (loop != NULL && (top->fb_type == COMPILE_FBLOCK_WHILE_LOOP ||
643
11
                         top->fb_type == COMPILE_FBLOCK_FOR_LOOP ||
644
62
                         top->fb_type == COMPILE_FBLOCK_ASYNC_FOR_LOOP)) {
645
62
        *loop = top;
646
62
        return SUCCESS;
647
62
    }
648
1.72k
    fblockinfo copy = *top;
649
1.72k
    _PyCompile_PopFBlock(c, top->fb_type, top->fb_block);
650
1.72k
    RETURN_IF_ERROR(codegen_unwind_fblock(c, ploc, &copy, preserve_tos));
651
1.72k
    RETURN_IF_ERROR(codegen_unwind_fblock_stack(c, ploc, preserve_tos, loop));
652
1.72k
    _PyCompile_PushFBlock(c, copy.fb_loc, copy.fb_type, copy.fb_block,
653
1.72k
                          copy.fb_exit, copy.fb_datum);
654
1.72k
    return SUCCESS;
655
1.72k
}
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
42.5k
{
662
42.5k
    RETURN_IF_ERROR(
663
42.5k
        _PyCompile_EnterScope(c, name, scope_type, key, lineno, private, umd));
664
42.5k
    location loc = LOCATION(lineno, lineno, 0, 0);
665
42.5k
    if (scope_type == COMPILE_SCOPE_MODULE) {
666
12.5k
        loc.lineno = 0;
667
12.5k
    }
668
42.5k
    ADDOP_I(c, loc, RESUME, RESUME_AT_FUNC_START);
669
42.5k
    if (scope_type == COMPILE_SCOPE_MODULE) {
670
12.5k
        ADDOP(c, loc, ANNOTATIONS_PLACEHOLDER);
671
12.5k
    }
672
42.5k
    return SUCCESS;
673
42.5k
}
674
675
static int
676
codegen_setup_annotations_scope(compiler *c, location loc,
677
                                void *key, PyObject *name)
678
6.06k
{
679
6.06k
    _PyCompile_CodeUnitMetadata umd = {
680
6.06k
        .u_posonlyargcount = 1,
681
6.06k
    };
682
6.06k
    RETURN_IF_ERROR(
683
6.06k
        codegen_enter_scope(c, name, COMPILE_SCOPE_ANNOTATIONS,
684
6.06k
                            key, loc.lineno, NULL, &umd));
685
686
    // if .format > VALUE_WITH_FAKE_GLOBALS: raise NotImplementedError
687
6.06k
    PyObject *value_with_fake_globals = PyLong_FromLong(_Py_ANNOTATE_FORMAT_VALUE_WITH_FAKE_GLOBALS);
688
6.06k
    assert(!SYMTABLE_ENTRY(c)->ste_has_docstring);
689
6.06k
    _Py_DECLARE_STR(format, ".format");
690
6.06k
    ADDOP_I(c, loc, LOAD_FAST, 0);
691
6.06k
    ADDOP_LOAD_CONST(c, loc, value_with_fake_globals);
692
6.06k
    ADDOP_I(c, loc, COMPARE_OP, (Py_GT << 5) | compare_masks[Py_GT]);
693
6.06k
    NEW_JUMP_TARGET_LABEL(c, body);
694
6.06k
    ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, body);
695
6.06k
    ADDOP_I(c, loc, LOAD_COMMON_CONSTANT, CONSTANT_NOTIMPLEMENTEDERROR);
696
6.06k
    ADDOP_I(c, loc, RAISE_VARARGS, 1);
697
6.06k
    USE_LABEL(c, body);
698
6.06k
    return SUCCESS;
699
6.06k
}
700
701
static int
702
codegen_leave_annotations_scope(compiler *c, location loc)
703
3.70k
{
704
3.70k
    ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
705
3.70k
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
706
3.70k
    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
3.70k
    const Py_ssize_t size = PyObject_Size(co->co_localsplusnames);
717
3.70k
    if (size == -1) {
718
0
        Py_DECREF(co);
719
0
        return ERROR;
720
0
    }
721
3.70k
    PyObject *new_names = PyTuple_New(size);
722
3.70k
    if (new_names == NULL) {
723
0
        Py_DECREF(co);
724
0
        return ERROR;
725
0
    }
726
3.70k
    PyTuple_SET_ITEM(new_names, 0, Py_NewRef(&_Py_ID(format)));
727
5.59k
    for (int i = 1; i < size; i++) {
728
1.89k
        PyObject *item = PyTuple_GetItem(co->co_localsplusnames, i);
729
1.89k
        if (item == NULL) {
730
0
            Py_DECREF(co);
731
0
            Py_DECREF(new_names);
732
0
            return ERROR;
733
0
        }
734
1.89k
        Py_INCREF(item);
735
1.89k
        PyTuple_SET_ITEM(new_names, i, item);
736
1.89k
    }
737
3.70k
    Py_SETREF(co->co_localsplusnames, new_names);
738
739
3.70k
    _PyCompile_ExitScope(c);
740
3.70k
    int ret = codegen_make_closure(c, loc, co, 0);
741
3.70k
    Py_DECREF(co);
742
3.70k
    RETURN_IF_ERROR(ret);
743
3.70k
    return SUCCESS;
744
3.70k
}
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.70k
{
750
1.70k
    Py_ssize_t annotations_len = PyList_GET_SIZE(deferred_anno);
751
752
1.70k
    assert(PyList_CheckExact(conditional_annotation_indices));
753
1.70k
    assert(annotations_len == PyList_Size(conditional_annotation_indices));
754
755
1.70k
    ADDOP_I(c, loc, BUILD_MAP, 0); // stack now contains <annos>
756
757
14.3k
    for (Py_ssize_t i = 0; i < annotations_len; i++) {
758
12.6k
        PyObject *ptr = PyList_GET_ITEM(deferred_anno, i);
759
0
        stmt_ty st = (stmt_ty)PyLong_AsVoidPtr(ptr);
760
12.6k
        if (st == NULL) {
761
0
            return ERROR;
762
0
        }
763
12.6k
        PyObject *mangled = _PyCompile_Mangle(c, st->v.AnnAssign.target->v.Name.id);
764
12.6k
        if (!mangled) {
765
0
            return ERROR;
766
0
        }
767
12.6k
        PyObject *cond_index = PyList_GET_ITEM(conditional_annotation_indices, i);
768
12.6k
        assert(PyLong_CheckExact(cond_index));
769
12.6k
        long idx = PyLong_AS_LONG(cond_index);
770
12.6k
        NEW_JUMP_TARGET_LABEL(c, not_set);
771
772
12.6k
        if (idx != -1) {
773
9.82k
            ADDOP_LOAD_CONST(c, LOC(st), cond_index);
774
9.82k
            if (scope_type == COMPILE_SCOPE_CLASS) {
775
185
                ADDOP_NAME(
776
185
                    c, LOC(st), LOAD_DEREF, &_Py_ID(__conditional_annotations__), freevars);
777
185
            }
778
9.63k
            else {
779
9.63k
                ADDOP_NAME(
780
9.63k
                    c, LOC(st), LOAD_GLOBAL, &_Py_ID(__conditional_annotations__), names);
781
9.63k
            }
782
783
9.82k
            ADDOP_I(c, LOC(st), CONTAINS_OP, 0);
784
9.82k
            ADDOP_JUMP(c, LOC(st), POP_JUMP_IF_FALSE, not_set);
785
9.82k
        }
786
787
12.6k
        VISIT(c, expr, st->v.AnnAssign.annotation);
788
12.6k
        ADDOP_I(c, LOC(st), COPY, 2);
789
12.6k
        ADDOP_LOAD_CONST_NEW(c, LOC(st), mangled);
790
        // stack now contains <annos> <name> <annos> <value>
791
12.6k
        ADDOP(c, loc, STORE_SUBSCR);
792
        // stack now contains <annos>
793
794
12.6k
        USE_LABEL(c, not_set);
795
12.6k
    }
796
1.69k
    return SUCCESS;
797
1.70k
}
798
799
static int
800
codegen_process_deferred_annotations(compiler *c, location loc)
801
15.5k
{
802
15.5k
    PyObject *deferred_anno = NULL;
803
15.5k
    PyObject *conditional_annotation_indices = NULL;
804
15.5k
    _PyCompile_DeferredAnnotations(c, &deferred_anno, &conditional_annotation_indices);
805
15.5k
    if (deferred_anno == NULL) {
806
13.8k
        assert(conditional_annotation_indices == NULL);
807
13.8k
        return SUCCESS;
808
13.8k
    }
809
810
1.70k
    int scope_type = SCOPE_TYPE(c);
811
1.70k
    bool need_separate_block = scope_type == COMPILE_SCOPE_MODULE;
812
1.70k
    if (need_separate_block) {
813
648
        if (_PyCompile_StartAnnotationSetup(c) == ERROR) {
814
0
            goto error;
815
0
        }
816
648
    }
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.70k
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
824
1.70k
    assert(ste->ste_annotation_block != NULL);
825
1.70k
    void *key = (void *)((uintptr_t)ste->ste_id + 1);
826
1.70k
    if (codegen_setup_annotations_scope(c, loc, key,
827
1.70k
                                        ste->ste_annotation_block->ste_name) < 0) {
828
0
        goto error;
829
0
    }
830
1.70k
    if (codegen_deferred_annotations_body(c, loc, deferred_anno,
831
1.70k
                                          conditional_annotation_indices, scope_type) < 0) {
832
19
        _PyCompile_ExitScope(c);
833
19
        goto error;
834
19
    }
835
836
1.69k
    Py_DECREF(deferred_anno);
837
1.69k
    Py_DECREF(conditional_annotation_indices);
838
839
1.69k
    RETURN_IF_ERROR(codegen_leave_annotations_scope(c, loc));
840
1.69k
    RETURN_IF_ERROR(codegen_nameop(
841
1.69k
        c, loc,
842
1.69k
        ste->ste_type == ClassBlock ? &_Py_ID(__annotate_func__) : &_Py_ID(__annotate__),
843
1.69k
        Store));
844
845
1.69k
    if (need_separate_block) {
846
629
        RETURN_IF_ERROR(_PyCompile_EndAnnotationSetup(c));
847
629
    }
848
849
1.69k
    return SUCCESS;
850
19
error:
851
19
    Py_XDECREF(deferred_anno);
852
19
    Py_XDECREF(conditional_annotation_indices);
853
19
    return ERROR;
854
1.69k
}
855
856
/* Compile an expression */
857
int
858
_PyCodegen_Expression(compiler *c, expr_ty e)
859
1.92k
{
860
1.92k
    VISIT(c, expr, e);
861
1.87k
    return SUCCESS;
862
1.92k
}
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
10.5k
{
870
10.5k
    if (SYMTABLE_ENTRY(c)->ste_has_conditional_annotations) {
871
2.10k
        ADDOP_I(c, loc, BUILD_SET, 0);
872
2.10k
        ADDOP_N(c, loc, STORE_NAME, &_Py_ID(__conditional_annotations__), names);
873
2.10k
    }
874
10.5k
    return codegen_body(c, loc, stmts, is_interactive);
875
10.5k
}
876
877
int
878
codegen_body(compiler *c, location loc, asdl_stmt_seq *stmts, bool is_interactive)
879
17.8k
{
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
17.8k
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
884
17.8k
    if ((FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS) && ste->ste_annotations_used) {
885
1.46k
        ADDOP(c, loc, SETUP_ANNOTATIONS);
886
1.46k
    }
887
17.8k
    if (!asdl_seq_LEN(stmts)) {
888
272
        return SUCCESS;
889
272
    }
890
17.5k
    Py_ssize_t first_instr = 0;
891
17.5k
    if (!is_interactive) { /* A string literal on REPL prompt is not a docstring */
892
14.5k
        if (ste->ste_has_docstring) {
893
1.13k
            PyObject *docstring = _PyAST_GetDocString(stmts);
894
1.13k
            assert(docstring);
895
1.13k
            first_instr = 1;
896
            /* set docstring */
897
1.13k
            assert(OPTIMIZATION_LEVEL(c) < 2);
898
1.13k
            PyObject *cleandoc = _PyCompile_CleanDoc(docstring);
899
1.13k
            if (cleandoc == NULL) {
900
4
                return ERROR;
901
4
            }
902
1.13k
            stmt_ty st = (stmt_ty)asdl_seq_GET(stmts, 0);
903
1.13k
            assert(st->kind == Expr_kind);
904
1.13k
            location loc = LOC(st->v.Expr.value);
905
1.13k
            ADDOP_LOAD_CONST(c, loc, cleandoc);
906
1.13k
            Py_DECREF(cleandoc);
907
1.13k
            RETURN_IF_ERROR(codegen_nameop(c, NO_LOCATION, &_Py_ID(__doc__), Store));
908
1.13k
        }
909
14.5k
    }
910
93.4k
    for (Py_ssize_t i = first_instr; i < asdl_seq_LEN(stmts); i++) {
911
76.2k
        VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i));
912
76.2k
    }
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
17.2k
    if (!(FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS)) {
917
15.5k
        RETURN_IF_ERROR(codegen_process_deferred_annotations(c, loc));
918
15.5k
    }
919
17.2k
    return SUCCESS;
920
17.2k
}
921
922
int
923
_PyCodegen_EnterAnonymousScope(compiler* c, mod_ty mod)
924
12.5k
{
925
12.5k
    _Py_DECLARE_STR(anon_module, "<module>");
926
12.5k
    RETURN_IF_ERROR(
927
12.5k
        codegen_enter_scope(c, &_Py_STR(anon_module), COMPILE_SCOPE_MODULE,
928
12.5k
                            mod, 1, NULL, NULL));
929
12.5k
    return SUCCESS;
930
12.5k
}
931
932
static int
933
codegen_make_closure(compiler *c, location loc,
934
                     PyCodeObject *co, Py_ssize_t flags)
935
29.9k
{
936
29.9k
    if (co->co_nfreevars) {
937
7.69k
        int i = PyUnstable_Code_GetFirstFree(co);
938
17.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
9.54k
            PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
943
0
            int arg = _PyCompile_LookupArg(c, co, name);
944
9.54k
            RETURN_IF_ERROR(arg);
945
9.54k
            ADDOP_I(c, loc, LOAD_CLOSURE, arg);
946
9.54k
        }
947
7.69k
        flags |= MAKE_FUNCTION_CLOSURE;
948
7.69k
        ADDOP_I(c, loc, BUILD_TUPLE, co->co_nfreevars);
949
7.69k
    }
950
29.9k
    ADDOP_LOAD_CONST(c, loc, (PyObject*)co);
951
952
29.9k
    ADDOP(c, loc, MAKE_FUNCTION);
953
954
29.9k
    if (flags & MAKE_FUNCTION_CLOSURE) {
955
7.69k
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_CLOSURE);
956
7.69k
    }
957
29.9k
    if (flags & MAKE_FUNCTION_ANNOTATIONS) {
958
0
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_ANNOTATIONS);
959
0
    }
960
29.9k
    if (flags & MAKE_FUNCTION_ANNOTATE) {
961
2.00k
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_ANNOTATE);
962
2.00k
    }
963
29.9k
    if (flags & MAKE_FUNCTION_KWDEFAULTS) {
964
952
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_KWDEFAULTS);
965
952
    }
966
29.9k
    if (flags & MAKE_FUNCTION_DEFAULTS) {
967
3.59k
        ADDOP_I(c, loc, SET_FUNCTION_ATTRIBUTE, MAKE_FUNCTION_DEFAULTS);
968
3.59k
    }
969
29.9k
    return SUCCESS;
970
29.9k
}
971
972
static int
973
codegen_decorators(compiler *c, asdl_expr_seq* decos)
974
13.8k
{
975
13.8k
    if (!decos) {
976
12.3k
        return SUCCESS;
977
12.3k
    }
978
979
4.91k
    for (Py_ssize_t i = 0; i < asdl_seq_LEN(decos); i++) {
980
3.35k
        VISIT(c, expr, (expr_ty)asdl_seq_GET(decos, i));
981
3.35k
    }
982
1.56k
    return SUCCESS;
983
1.56k
}
984
985
static int
986
codegen_apply_decorators(compiler *c, asdl_expr_seq* decos)
987
13.7k
{
988
13.7k
    if (!decos) {
989
12.2k
        return SUCCESS;
990
12.2k
    }
991
992
4.91k
    for (Py_ssize_t i = asdl_seq_LEN(decos) - 1; i > -1; i--) {
993
3.35k
        location loc = LOC((expr_ty)asdl_seq_GET(decos, i));
994
3.35k
        ADDOP_I(c, loc, CALL, 0);
995
3.35k
    }
996
1.56k
    return SUCCESS;
997
1.56k
}
998
999
static int
1000
codegen_kwonlydefaults(compiler *c, location loc,
1001
                       asdl_arg_seq *kwonlyargs, asdl_expr_seq *kw_defaults)
1002
10.7k
{
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
10.7k
    int default_count = 0;
1008
13.3k
    for (int i = 0; i < asdl_seq_LEN(kwonlyargs); i++) {
1009
2.61k
        arg_ty arg = asdl_seq_GET(kwonlyargs, i);
1010
2.61k
        expr_ty default_ = asdl_seq_GET(kw_defaults, i);
1011
2.61k
        if (default_) {
1012
1.14k
            default_count++;
1013
1.14k
            PyObject *mangled = _PyCompile_MaybeMangle(c, arg->arg);
1014
1.14k
            if (!mangled) {
1015
0
                return ERROR;
1016
0
            }
1017
1.14k
            ADDOP_LOAD_CONST_NEW(c, loc, mangled);
1018
1.14k
            VISIT(c, expr, default_);
1019
1.14k
        }
1020
2.61k
    }
1021
10.7k
    if (default_count) {
1022
952
        ADDOP_I(c, loc, BUILD_MAP, default_count);
1023
952
        return 1;
1024
952
    }
1025
9.77k
    else {
1026
9.77k
        return 0;
1027
9.77k
    }
1028
10.7k
}
1029
1030
static int
1031
codegen_visit_annexpr(compiler *c, expr_ty annotation)
1032
2.55k
{
1033
2.55k
    location loc = LOC(annotation);
1034
2.55k
    ADDOP_LOAD_CONST_NEW(c, loc, _PyAST_ExprAsUnicode(annotation));
1035
2.55k
    return SUCCESS;
1036
2.55k
}
1037
1038
static int
1039
codegen_argannotation(compiler *c, identifier id,
1040
    expr_ty annotation, Py_ssize_t *annotations_len, location loc)
1041
4.55k
{
1042
4.55k
    if (!annotation) {
1043
2.45k
        return SUCCESS;
1044
2.45k
    }
1045
2.10k
    PyObject *mangled = _PyCompile_MaybeMangle(c, id);
1046
2.10k
    if (!mangled) {
1047
0
        return ERROR;
1048
0
    }
1049
2.10k
    ADDOP_LOAD_CONST(c, loc, mangled);
1050
2.10k
    Py_DECREF(mangled);
1051
1052
2.10k
    if (FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS) {
1053
325
        VISIT(c, annexpr, annotation);
1054
325
    }
1055
1.77k
    else {
1056
1.77k
        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
90
            VISIT(c, expr, annotation->v.Starred.value);
1062
90
            ADDOP_I(c, loc, UNPACK_SEQUENCE, (Py_ssize_t) 1);
1063
90
        }
1064
1.68k
        else {
1065
1.68k
            VISIT(c, expr, annotation);
1066
1.68k
        }
1067
1.77k
    }
1068
2.10k
    *annotations_len += 1;
1069
2.10k
    return SUCCESS;
1070
2.10k
}
1071
1072
static int
1073
codegen_argannotations(compiler *c, asdl_arg_seq* args,
1074
                       Py_ssize_t *annotations_len, location loc)
1075
6.03k
{
1076
6.03k
    int i;
1077
8.33k
    for (i = 0; i < asdl_seq_LEN(args); i++) {
1078
2.30k
        arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
1079
2.30k
        RETURN_IF_ERROR(
1080
2.30k
            codegen_argannotation(
1081
2.30k
                        c,
1082
2.30k
                        arg->arg,
1083
2.30k
                        arg->annotation,
1084
2.30k
                        annotations_len,
1085
2.30k
                        loc));
1086
2.30k
    }
1087
6.03k
    return SUCCESS;
1088
6.03k
}
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.01k
{
1095
2.01k
    RETURN_IF_ERROR(
1096
2.01k
        codegen_argannotations(c, args->args, annotations_len, loc));
1097
1098
2.01k
    RETURN_IF_ERROR(
1099
2.01k
        codegen_argannotations(c, args->posonlyargs, annotations_len, loc));
1100
1101
2.01k
    if (args->vararg && args->vararg->annotation) {
1102
92
        RETURN_IF_ERROR(
1103
92
            codegen_argannotation(c, args->vararg->arg,
1104
92
                                     args->vararg->annotation, annotations_len, loc));
1105
92
    }
1106
1107
2.01k
    RETURN_IF_ERROR(
1108
2.01k
        codegen_argannotations(c, args->kwonlyargs, annotations_len, loc));
1109
1110
2.01k
    if (args->kwarg && args->kwarg->annotation) {
1111
153
        RETURN_IF_ERROR(
1112
153
            codegen_argannotation(c, args->kwarg->arg,
1113
153
                                     args->kwarg->annotation, annotations_len, loc));
1114
153
    }
1115
1116
2.01k
    RETURN_IF_ERROR(
1117
2.01k
        codegen_argannotation(c, &_Py_ID(return), returns, annotations_len, loc));
1118
1119
2.01k
    return 0;
1120
2.01k
}
1121
1122
static int
1123
codegen_function_annotations(compiler *c, location loc,
1124
                             arguments_ty args, expr_ty returns)
1125
6.58k
{
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.58k
    Py_ssize_t annotations_len = 0;
1132
1133
6.58k
    PySTEntryObject *ste;
1134
6.58k
    RETURN_IF_ERROR(_PySymtable_LookupOptional(SYMTABLE(c), args, &ste));
1135
6.58k
    assert(ste != NULL);
1136
1137
6.58k
    if (ste->ste_annotations_used) {
1138
2.01k
        int err = codegen_setup_annotations_scope(c, loc, (void *)args, ste->ste_name);
1139
2.01k
        Py_DECREF(ste);
1140
2.01k
        RETURN_IF_ERROR(err);
1141
2.01k
        RETURN_IF_ERROR_IN_SCOPE(
1142
2.01k
            c, codegen_annotations_in_scope(c, loc, args, returns, &annotations_len)
1143
2.01k
        );
1144
2.01k
        ADDOP_I(c, loc, BUILD_MAP, annotations_len);
1145
2.01k
        RETURN_IF_ERROR(codegen_leave_annotations_scope(c, loc));
1146
2.01k
        return MAKE_FUNCTION_ANNOTATE;
1147
2.01k
    }
1148
4.57k
    else {
1149
4.57k
        Py_DECREF(ste);
1150
4.57k
    }
1151
1152
4.57k
    return 0;
1153
6.58k
}
1154
1155
static int
1156
codegen_defaults(compiler *c, arguments_ty args,
1157
                        location loc)
1158
1.24k
{
1159
1.24k
    VISIT_SEQ(c, expr, args->defaults);
1160
1.24k
    ADDOP_I(c, loc, BUILD_TUPLE, asdl_seq_LEN(args->defaults));
1161
1.24k
    return SUCCESS;
1162
1.24k
}
1163
1164
static Py_ssize_t
1165
codegen_default_arguments(compiler *c, location loc,
1166
                          arguments_ty args)
1167
10.7k
{
1168
10.7k
    Py_ssize_t funcflags = 0;
1169
10.7k
    if (args->defaults && asdl_seq_LEN(args->defaults) > 0) {
1170
1.24k
        RETURN_IF_ERROR(codegen_defaults(c, args, loc));
1171
1.24k
        funcflags |= MAKE_FUNCTION_DEFAULTS;
1172
1.24k
    }
1173
10.7k
    if (args->kwonlyargs) {
1174
10.7k
        int res = codegen_kwonlydefaults(c, loc,
1175
10.7k
                                         args->kwonlyargs,
1176
10.7k
                                         args->kw_defaults);
1177
10.7k
        RETURN_IF_ERROR(res);
1178
10.7k
        if (res > 0) {
1179
952
            funcflags |= MAKE_FUNCTION_KWDEFAULTS;
1180
952
        }
1181
10.7k
    }
1182
10.7k
    return funcflags;
1183
10.7k
}
1184
1185
static int
1186
codegen_wrap_in_stopiteration_handler(compiler *c)
1187
3.32k
{
1188
3.32k
    NEW_JUMP_TARGET_LABEL(c, handler);
1189
1190
    /* Insert SETUP_CLEANUP at start */
1191
3.32k
    RETURN_IF_ERROR(
1192
3.32k
        _PyInstructionSequence_InsertInstruction(
1193
3.32k
            INSTR_SEQUENCE(c), 0,
1194
3.32k
            SETUP_CLEANUP, handler.id, NO_LOCATION));
1195
1196
3.32k
    ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
1197
3.32k
    ADDOP(c, NO_LOCATION, RETURN_VALUE);
1198
3.32k
    USE_LABEL(c, handler);
1199
3.32k
    ADDOP_I(c, NO_LOCATION, CALL_INTRINSIC_1, INTRINSIC_STOPITERATION_ERROR);
1200
3.32k
    ADDOP_I(c, NO_LOCATION, RERAISE, 1);
1201
3.32k
    return SUCCESS;
1202
3.32k
}
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.28k
{
1209
1.28k
    PyObject *defaults = PyTuple_Pack(1, _PyLong_GetOne());
1210
1.28k
    ADDOP_LOAD_CONST_NEW(c, LOC(e), defaults);
1211
1.28k
    RETURN_IF_ERROR(codegen_setup_annotations_scope(c, LOC(e), key, name));
1212
1.28k
    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.28k
    else {
1217
1.28k
        VISIT(c, expr, e);
1218
1.28k
    }
1219
1.28k
    ADDOP_IN_SCOPE(c, LOC(e), RETURN_VALUE);
1220
1.28k
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
1221
1.28k
    _PyCompile_ExitScope(c);
1222
1.28k
    if (co == NULL) {
1223
0
        return ERROR;
1224
0
    }
1225
1.28k
    int ret = codegen_make_closure(c, LOC(e), co, MAKE_FUNCTION_DEFAULTS);
1226
1.28k
    Py_DECREF(co);
1227
1.28k
    RETURN_IF_ERROR(ret);
1228
1.28k
    return SUCCESS;
1229
1.28k
}
1230
1231
static int
1232
codegen_type_params(compiler *c, asdl_type_param_seq *type_params)
1233
4.73k
{
1234
4.73k
    if (!type_params) {
1235
0
        return SUCCESS;
1236
0
    }
1237
4.73k
    Py_ssize_t n = asdl_seq_LEN(type_params);
1238
4.73k
    bool seen_default = false;
1239
1240
15.0k
    for (Py_ssize_t i = 0; i < n; i++) {
1241
10.2k
        type_param_ty typeparam = asdl_seq_GET(type_params, i);
1242
10.2k
        location loc = LOC(typeparam);
1243
10.2k
        switch(typeparam->kind) {
1244
9.72k
        case TypeVar_kind:
1245
9.72k
            ADDOP_LOAD_CONST(c, loc, typeparam->v.TypeVar.name);
1246
9.72k
            if (typeparam->v.TypeVar.bound) {
1247
1.09k
                expr_ty bound = typeparam->v.TypeVar.bound;
1248
1.09k
                RETURN_IF_ERROR(
1249
1.09k
                    codegen_type_param_bound_or_default(c, bound, typeparam->v.TypeVar.name,
1250
1.09k
                                                        (void *)typeparam, false));
1251
1252
1.09k
                int intrinsic = bound->kind == Tuple_kind
1253
1.09k
                    ? INTRINSIC_TYPEVAR_WITH_CONSTRAINTS
1254
1.09k
                    : INTRINSIC_TYPEVAR_WITH_BOUND;
1255
1.09k
                ADDOP_I(c, loc, CALL_INTRINSIC_2, intrinsic);
1256
1.09k
            }
1257
8.62k
            else {
1258
8.62k
                ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_TYPEVAR);
1259
8.62k
            }
1260
9.72k
            if (typeparam->v.TypeVar.default_value) {
1261
167
                seen_default = true;
1262
167
                expr_ty default_ = typeparam->v.TypeVar.default_value;
1263
167
                RETURN_IF_ERROR(
1264
167
                    codegen_type_param_bound_or_default(c, default_, typeparam->v.TypeVar.name,
1265
167
                                                        (void *)((uintptr_t)typeparam + 1), false));
1266
167
                ADDOP_I(c, loc, CALL_INTRINSIC_2, INTRINSIC_SET_TYPEPARAM_DEFAULT);
1267
167
            }
1268
9.55k
            else if (seen_default) {
1269
13
                return _PyCompile_Error(c, loc, "non-default type parameter '%U' "
1270
13
                                        "follows default type parameter",
1271
13
                                        typeparam->v.TypeVar.name);
1272
13
            }
1273
9.71k
            ADDOP_I(c, loc, COPY, 1);
1274
9.71k
            RETURN_IF_ERROR(codegen_nameop(c, loc, typeparam->v.TypeVar.name, Store));
1275
9.71k
            break;
1276
9.71k
        case TypeVarTuple_kind:
1277
280
            ADDOP_LOAD_CONST(c, loc, typeparam->v.TypeVarTuple.name);
1278
280
            ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_TYPEVARTUPLE);
1279
280
            if (typeparam->v.TypeVarTuple.default_value) {
1280
10
                expr_ty default_ = typeparam->v.TypeVarTuple.default_value;
1281
10
                RETURN_IF_ERROR(
1282
10
                    codegen_type_param_bound_or_default(c, default_, typeparam->v.TypeVarTuple.name,
1283
10
                                                        (void *)typeparam, true));
1284
10
                ADDOP_I(c, loc, CALL_INTRINSIC_2, INTRINSIC_SET_TYPEPARAM_DEFAULT);
1285
10
                seen_default = true;
1286
10
            }
1287
270
            else if (seen_default) {
1288
2
                return _PyCompile_Error(c, loc, "non-default type parameter '%U' "
1289
2
                                        "follows default type parameter",
1290
2
                                        typeparam->v.TypeVarTuple.name);
1291
2
            }
1292
278
            ADDOP_I(c, loc, COPY, 1);
1293
278
            RETURN_IF_ERROR(codegen_nameop(c, loc, typeparam->v.TypeVarTuple.name, Store));
1294
278
            break;
1295
287
        case ParamSpec_kind:
1296
287
            ADDOP_LOAD_CONST(c, loc, typeparam->v.ParamSpec.name);
1297
287
            ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_PARAMSPEC);
1298
287
            if (typeparam->v.ParamSpec.default_value) {
1299
13
                expr_ty default_ = typeparam->v.ParamSpec.default_value;
1300
13
                RETURN_IF_ERROR(
1301
13
                    codegen_type_param_bound_or_default(c, default_, typeparam->v.ParamSpec.name,
1302
13
                                                        (void *)typeparam, false));
1303
13
                ADDOP_I(c, loc, CALL_INTRINSIC_2, INTRINSIC_SET_TYPEPARAM_DEFAULT);
1304
13
                seen_default = true;
1305
13
            }
1306
274
            else if (seen_default) {
1307
5
                return _PyCompile_Error(c, loc, "non-default type parameter '%U' "
1308
5
                                        "follows default type parameter",
1309
5
                                        typeparam->v.ParamSpec.name);
1310
5
            }
1311
282
            ADDOP_I(c, loc, COPY, 1);
1312
282
            RETURN_IF_ERROR(codegen_nameop(c, loc, typeparam->v.ParamSpec.name, Store));
1313
282
            break;
1314
10.2k
        }
1315
10.2k
    }
1316
4.71k
    ADDOP_I(c, LOC(asdl_seq_GET(type_params, 0)), BUILD_TUPLE, n);
1317
4.71k
    return SUCCESS;
1318
4.71k
}
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.58k
{
1324
6.58k
    arguments_ty args;
1325
6.58k
    identifier name;
1326
6.58k
    asdl_stmt_seq *body;
1327
6.58k
    int scope_type;
1328
1329
6.58k
    if (is_async) {
1330
1.82k
        assert(s->kind == AsyncFunctionDef_kind);
1331
1332
1.82k
        args = s->v.AsyncFunctionDef.args;
1333
1.82k
        name = s->v.AsyncFunctionDef.name;
1334
1.82k
        body = s->v.AsyncFunctionDef.body;
1335
1336
1.82k
        scope_type = COMPILE_SCOPE_ASYNC_FUNCTION;
1337
4.75k
    } else {
1338
4.75k
        assert(s->kind == FunctionDef_kind);
1339
1340
4.75k
        args = s->v.FunctionDef.args;
1341
4.75k
        name = s->v.FunctionDef.name;
1342
4.75k
        body = s->v.FunctionDef.body;
1343
1344
4.75k
        scope_type = COMPILE_SCOPE_FUNCTION;
1345
4.75k
    }
1346
1347
6.58k
    _PyCompile_CodeUnitMetadata umd = {
1348
6.58k
        .u_argcount = asdl_seq_LEN(args->args),
1349
6.58k
        .u_posonlyargcount = asdl_seq_LEN(args->posonlyargs),
1350
6.58k
        .u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs),
1351
6.58k
    };
1352
6.58k
    RETURN_IF_ERROR(
1353
6.58k
        codegen_enter_scope(c, name, scope_type, (void *)s, firstlineno, NULL, &umd));
1354
1355
6.58k
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
1356
6.58k
    Py_ssize_t first_instr = 0;
1357
6.58k
    if (ste->ste_has_docstring) {
1358
311
        PyObject *docstring = _PyAST_GetDocString(body);
1359
311
        assert(docstring);
1360
311
        first_instr = 1;
1361
311
        docstring = _PyCompile_CleanDoc(docstring);
1362
311
        if (docstring == NULL) {
1363
0
            _PyCompile_ExitScope(c);
1364
0
            return ERROR;
1365
0
        }
1366
311
        Py_ssize_t idx = _PyCompile_AddConst(c, docstring);
1367
311
        Py_DECREF(docstring);
1368
311
        RETURN_IF_ERROR_IN_SCOPE(c, idx < 0 ? ERROR : SUCCESS);
1369
311
    }
1370
1371
6.58k
    NEW_JUMP_TARGET_LABEL(c, start);
1372
6.58k
    USE_LABEL(c, start);
1373
6.58k
    bool add_stopiteration_handler = ste->ste_coroutine || ste->ste_generator;
1374
6.58k
    if (add_stopiteration_handler) {
1375
        /* codegen_wrap_in_stopiteration_handler will push a block, so we need to account for that */
1376
2.12k
        RETURN_IF_ERROR(
1377
2.12k
            _PyCompile_PushFBlock(c, NO_LOCATION, COMPILE_FBLOCK_STOP_ITERATION,
1378
2.12k
                                  start, NO_LABEL, NULL));
1379
2.12k
    }
1380
1381
26.0k
    for (Py_ssize_t i = first_instr; i < asdl_seq_LEN(body); i++) {
1382
19.5k
        VISIT_IN_SCOPE(c, stmt, (stmt_ty)asdl_seq_GET(body, i));
1383
19.5k
    }
1384
6.55k
    if (add_stopiteration_handler) {
1385
2.11k
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_wrap_in_stopiteration_handler(c));
1386
2.11k
        _PyCompile_PopFBlock(c, COMPILE_FBLOCK_STOP_ITERATION, start);
1387
2.11k
    }
1388
6.55k
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
1389
6.55k
    _PyCompile_ExitScope(c);
1390
6.55k
    if (co == NULL) {
1391
0
        Py_XDECREF(co);
1392
0
        return ERROR;
1393
0
    }
1394
6.55k
    int ret = codegen_make_closure(c, LOC(s), co, funcflags);
1395
6.55k
    Py_DECREF(co);
1396
6.55k
    return ret;
1397
6.55k
}
1398
1399
static int
1400
codegen_function(compiler *c, stmt_ty s, int is_async)
1401
6.58k
{
1402
6.58k
    arguments_ty args;
1403
6.58k
    expr_ty returns;
1404
6.58k
    identifier name;
1405
6.58k
    asdl_expr_seq *decos;
1406
6.58k
    asdl_type_param_seq *type_params;
1407
6.58k
    Py_ssize_t funcflags;
1408
6.58k
    int firstlineno;
1409
1410
6.58k
    if (is_async) {
1411
1.83k
        assert(s->kind == AsyncFunctionDef_kind);
1412
1413
1.83k
        args = s->v.AsyncFunctionDef.args;
1414
1.83k
        returns = s->v.AsyncFunctionDef.returns;
1415
1.83k
        decos = s->v.AsyncFunctionDef.decorator_list;
1416
1.83k
        name = s->v.AsyncFunctionDef.name;
1417
1.83k
        type_params = s->v.AsyncFunctionDef.type_params;
1418
4.75k
    } else {
1419
4.75k
        assert(s->kind == FunctionDef_kind);
1420
1421
4.75k
        args = s->v.FunctionDef.args;
1422
4.75k
        returns = s->v.FunctionDef.returns;
1423
4.75k
        decos = s->v.FunctionDef.decorator_list;
1424
4.75k
        name = s->v.FunctionDef.name;
1425
4.75k
        type_params = s->v.FunctionDef.type_params;
1426
4.75k
    }
1427
1428
6.58k
    RETURN_IF_ERROR(codegen_decorators(c, decos));
1429
1430
6.58k
    firstlineno = s->lineno;
1431
6.58k
    if (asdl_seq_LEN(decos)) {
1432
813
        firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
1433
813
    }
1434
1435
6.58k
    location loc = LOC(s);
1436
1437
6.58k
    int is_generic = asdl_seq_LEN(type_params) > 0;
1438
1439
6.58k
    funcflags = codegen_default_arguments(c, loc, args);
1440
6.58k
    RETURN_IF_ERROR(funcflags);
1441
1442
6.58k
    int num_typeparam_args = 0;
1443
1444
6.58k
    if (is_generic) {
1445
912
        if (funcflags & MAKE_FUNCTION_DEFAULTS) {
1446
107
            num_typeparam_args += 1;
1447
107
        }
1448
912
        if (funcflags & MAKE_FUNCTION_KWDEFAULTS) {
1449
103
            num_typeparam_args += 1;
1450
103
        }
1451
912
        if (num_typeparam_args == 2) {
1452
39
            ADDOP_I(c, loc, SWAP, 2);
1453
39
        }
1454
912
        PyObject *type_params_name = PyUnicode_FromFormat("<generic parameters of %U>", name);
1455
912
        if (!type_params_name) {
1456
0
            return ERROR;
1457
0
        }
1458
912
        _PyCompile_CodeUnitMetadata umd = {
1459
912
            .u_argcount = num_typeparam_args,
1460
912
        };
1461
912
        int ret = codegen_enter_scope(c, type_params_name, COMPILE_SCOPE_ANNOTATIONS,
1462
912
                                      (void *)type_params, firstlineno, NULL, &umd);
1463
912
        Py_DECREF(type_params_name);
1464
912
        RETURN_IF_ERROR(ret);
1465
912
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_type_params(c, type_params));
1466
1.11k
        for (int i = 0; i < num_typeparam_args; i++) {
1467
210
            ADDOP_I_IN_SCOPE(c, loc, LOAD_FAST, i);
1468
210
        }
1469
906
    }
1470
1471
6.58k
    int annotations_flag = codegen_function_annotations(c, loc, args, returns);
1472
6.58k
    if (annotations_flag < 0) {
1473
0
        if (is_generic) {
1474
0
            _PyCompile_ExitScope(c);
1475
0
        }
1476
0
        return ERROR;
1477
0
    }
1478
6.58k
    funcflags |= annotations_flag;
1479
1480
6.58k
    int ret = codegen_function_body(c, s, is_async, funcflags, firstlineno);
1481
6.58k
    if (is_generic) {
1482
906
        RETURN_IF_ERROR_IN_SCOPE(c, ret);
1483
906
    }
1484
5.67k
    else {
1485
5.67k
        RETURN_IF_ERROR(ret);
1486
5.67k
    }
1487
1488
6.55k
    if (is_generic) {
1489
898
        ADDOP_I_IN_SCOPE(c, loc, SWAP, 2);
1490
898
        ADDOP_I_IN_SCOPE(c, loc, CALL_INTRINSIC_2, INTRINSIC_SET_FUNCTION_TYPE_PARAMS);
1491
1492
898
        PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 0);
1493
898
        _PyCompile_ExitScope(c);
1494
898
        if (co == NULL) {
1495
0
            return ERROR;
1496
0
        }
1497
898
        int ret = codegen_make_closure(c, loc, co, 0);
1498
898
        Py_DECREF(co);
1499
898
        RETURN_IF_ERROR(ret);
1500
898
        if (num_typeparam_args > 0) {
1501
171
            ADDOP_I(c, loc, SWAP, num_typeparam_args + 1);
1502
171
            ADDOP_I(c, loc, CALL, num_typeparam_args - 1);
1503
171
        }
1504
727
        else {
1505
727
            ADDOP(c, loc, PUSH_NULL);
1506
727
            ADDOP_I(c, loc, CALL, 0);
1507
727
        }
1508
898
    }
1509
1510
6.55k
    RETURN_IF_ERROR(codegen_apply_decorators(c, decos));
1511
6.55k
    return codegen_nameop(c, loc, name, Store);
1512
6.55k
}
1513
1514
static int
1515
codegen_set_type_params_in_class(compiler *c, location loc)
1516
2.76k
{
1517
2.76k
    _Py_DECLARE_STR(type_params, ".type_params");
1518
2.76k
    RETURN_IF_ERROR(codegen_nameop(c, loc, &_Py_STR(type_params), Load));
1519
2.76k
    RETURN_IF_ERROR(codegen_nameop(c, loc, &_Py_ID(__type_params__), Store));
1520
2.76k
    return SUCCESS;
1521
2.76k
}
1522
1523
1524
static int
1525
codegen_class_body(compiler *c, stmt_ty s, int firstlineno)
1526
7.26k
{
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.26k
    RETURN_IF_ERROR(
1540
7.26k
        codegen_enter_scope(c, s->v.ClassDef.name, COMPILE_SCOPE_CLASS,
1541
7.26k
                            (void *)s, firstlineno, s->v.ClassDef.name, NULL));
1542
1543
7.26k
    location loc = LOCATION(firstlineno, firstlineno, 0, 0);
1544
    /* load (global) __name__ ... */
1545
7.26k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__name__), Load));
1546
    /* ... and store it as __module__ */
1547
7.26k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__module__), Store));
1548
7.26k
    ADDOP_LOAD_CONST(c, loc, QUALNAME(c));
1549
7.26k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__qualname__), Store));
1550
7.26k
    ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromLong(METADATA(c)->u_firstlineno));
1551
7.26k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_ID(__firstlineno__), Store));
1552
7.26k
    asdl_type_param_seq *type_params = s->v.ClassDef.type_params;
1553
7.26k
    if (asdl_seq_LEN(type_params) > 0) {
1554
2.76k
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_set_type_params_in_class(c, loc));
1555
2.76k
    }
1556
7.26k
    if (SYMTABLE_ENTRY(c)->ste_needs_classdict) {
1557
1.60k
        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.60k
        ADDOP_N_IN_SCOPE(c, loc, STORE_DEREF, &_Py_ID(__classdict__), cellvars);
1563
1.60k
    }
1564
7.26k
    if (SYMTABLE_ENTRY(c)->ste_has_conditional_annotations) {
1565
114
        ADDOP_I(c, loc, BUILD_SET, 0);
1566
114
        ADDOP_N_IN_SCOPE(c, loc, STORE_DEREF, &_Py_ID(__conditional_annotations__), cellvars);
1567
114
    }
1568
    /* compile the body proper */
1569
7.26k
    RETURN_IF_ERROR_IN_SCOPE(c, codegen_body(c, loc, s->v.ClassDef.body, false));
1570
7.24k
    PyObject *static_attributes = _PyCompile_StaticAttributesAsTuple(c);
1571
7.24k
    if (static_attributes == NULL) {
1572
0
        _PyCompile_ExitScope(c);
1573
0
        return ERROR;
1574
0
    }
1575
7.24k
    ADDOP_LOAD_CONST(c, NO_LOCATION, static_attributes);
1576
7.24k
    Py_CLEAR(static_attributes);
1577
7.24k
    RETURN_IF_ERROR_IN_SCOPE(
1578
7.24k
        c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__static_attributes__), Store));
1579
    /* The following code is artificial */
1580
    /* Set __classdictcell__ if necessary */
1581
7.24k
    if (SYMTABLE_ENTRY(c)->ste_needs_classdict) {
1582
        /* Store __classdictcell__ into class namespace */
1583
1.59k
        int i = _PyCompile_LookupCellvar(c, &_Py_ID(__classdict__));
1584
1.59k
        RETURN_IF_ERROR_IN_SCOPE(c, i);
1585
1.59k
        ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
1586
1.59k
        RETURN_IF_ERROR_IN_SCOPE(
1587
1.59k
            c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__classdictcell__), Store));
1588
1.59k
    }
1589
    /* Return __classcell__ if it is referenced, otherwise return None */
1590
7.24k
    if (SYMTABLE_ENTRY(c)->ste_needs_class_closure) {
1591
        /* Store __classcell__ into class namespace & return it */
1592
4
        int i = _PyCompile_LookupCellvar(c, &_Py_ID(__class__));
1593
4
        RETURN_IF_ERROR_IN_SCOPE(c, i);
1594
4
        ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
1595
4
        ADDOP_I(c, NO_LOCATION, COPY, 1);
1596
4
        RETURN_IF_ERROR_IN_SCOPE(
1597
4
            c, codegen_nameop(c, NO_LOCATION, &_Py_ID(__classcell__), Store));
1598
4
    }
1599
7.24k
    else {
1600
        /* No methods referenced __class__, so just return None */
1601
7.24k
        ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
1602
7.24k
    }
1603
7.24k
    ADDOP_IN_SCOPE(c, NO_LOCATION, RETURN_VALUE);
1604
    /* create the code object */
1605
7.24k
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 1);
1606
1607
    /* leave the new scope */
1608
7.24k
    _PyCompile_ExitScope(c);
1609
7.24k
    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.24k
    loc = LOC(s);
1618
7.24k
    ADDOP(c, loc, LOAD_BUILD_CLASS);
1619
7.24k
    ADDOP(c, loc, PUSH_NULL);
1620
1621
    /* 3. load a function (or closure) made from the code object */
1622
7.24k
    int ret = codegen_make_closure(c, loc, co, 0);
1623
7.24k
    Py_DECREF(co);
1624
7.24k
    RETURN_IF_ERROR(ret);
1625
1626
    /* 4. load class name */
1627
7.24k
    ADDOP_LOAD_CONST(c, loc, s->v.ClassDef.name);
1628
1629
7.24k
    return SUCCESS;
1630
7.24k
}
1631
1632
static int
1633
codegen_class(compiler *c, stmt_ty s)
1634
7.28k
{
1635
7.28k
    asdl_expr_seq *decos = s->v.ClassDef.decorator_list;
1636
1637
7.28k
    RETURN_IF_ERROR(codegen_decorators(c, decos));
1638
1639
7.28k
    int firstlineno = s->lineno;
1640
7.28k
    if (asdl_seq_LEN(decos)) {
1641
753
        firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
1642
753
    }
1643
7.28k
    location loc = LOC(s);
1644
1645
7.28k
    asdl_type_param_seq *type_params = s->v.ClassDef.type_params;
1646
7.28k
    int is_generic = asdl_seq_LEN(type_params) > 0;
1647
7.28k
    if (is_generic) {
1648
2.78k
        PyObject *type_params_name = PyUnicode_FromFormat("<generic parameters of %U>",
1649
2.78k
                                                         s->v.ClassDef.name);
1650
2.78k
        if (!type_params_name) {
1651
0
            return ERROR;
1652
0
        }
1653
2.78k
        int ret = codegen_enter_scope(c, type_params_name, COMPILE_SCOPE_ANNOTATIONS,
1654
2.78k
                                      (void *)type_params, firstlineno, s->v.ClassDef.name, NULL);
1655
2.78k
        Py_DECREF(type_params_name);
1656
2.78k
        RETURN_IF_ERROR(ret);
1657
2.78k
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_type_params(c, type_params));
1658
2.76k
        _Py_DECLARE_STR(type_params, ".type_params");
1659
2.76k
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_STR(type_params), Store));
1660
2.76k
    }
1661
1662
7.26k
    int ret = codegen_class_body(c, s, firstlineno);
1663
7.26k
    if (is_generic) {
1664
2.76k
        RETURN_IF_ERROR_IN_SCOPE(c, ret);
1665
2.76k
    }
1666
4.50k
    else {
1667
4.50k
        RETURN_IF_ERROR(ret);
1668
4.50k
    }
1669
1670
    /* generate the rest of the code for the call */
1671
1672
7.24k
    if (is_generic) {
1673
2.76k
        _Py_DECLARE_STR(type_params, ".type_params");
1674
2.76k
        _Py_DECLARE_STR(generic_base, ".generic_base");
1675
2.76k
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_STR(type_params), Load));
1676
2.76k
        ADDOP_I_IN_SCOPE(c, loc, CALL_INTRINSIC_1, INTRINSIC_SUBSCRIPT_GENERIC);
1677
2.76k
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_nameop(c, loc, &_Py_STR(generic_base), Store));
1678
1679
2.76k
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_call_helper_impl(c, loc, 2,
1680
2.76k
                                                             s->v.ClassDef.bases,
1681
2.76k
                                                             &_Py_STR(generic_base),
1682
2.76k
                                                             s->v.ClassDef.keywords));
1683
1684
2.76k
        PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 0);
1685
1686
2.76k
        _PyCompile_ExitScope(c);
1687
2.76k
        if (co == NULL) {
1688
0
            return ERROR;
1689
0
        }
1690
2.76k
        int ret = codegen_make_closure(c, loc, co, 0);
1691
2.76k
        Py_DECREF(co);
1692
2.76k
        RETURN_IF_ERROR(ret);
1693
2.76k
        ADDOP(c, loc, PUSH_NULL);
1694
2.76k
        ADDOP_I(c, loc, CALL, 0);
1695
4.48k
    } else {
1696
4.48k
        RETURN_IF_ERROR(codegen_call_helper(c, loc, 2,
1697
4.48k
                                            s->v.ClassDef.bases,
1698
4.48k
                                            s->v.ClassDef.keywords));
1699
4.48k
    }
1700
1701
    /* 6. apply decorators */
1702
7.24k
    RETURN_IF_ERROR(codegen_apply_decorators(c, decos));
1703
1704
    /* 7. store into <name> */
1705
7.24k
    RETURN_IF_ERROR(codegen_nameop(c, loc, s->v.ClassDef.name, Store));
1706
7.24k
    return SUCCESS;
1707
7.24k
}
1708
1709
static int
1710
codegen_typealias_body(compiler *c, stmt_ty s)
1711
1.06k
{
1712
1.06k
    location loc = LOC(s);
1713
1.06k
    PyObject *name = s->v.TypeAlias.name->v.Name.id;
1714
1.06k
    PyObject *defaults = PyTuple_Pack(1, _PyLong_GetOne());
1715
1.06k
    ADDOP_LOAD_CONST_NEW(c, loc, defaults);
1716
1.06k
    RETURN_IF_ERROR(
1717
1.06k
        codegen_setup_annotations_scope(c, LOC(s), s, name));
1718
1719
1.06k
    assert(!SYMTABLE_ENTRY(c)->ste_has_docstring);
1720
1.06k
    VISIT_IN_SCOPE(c, expr, s->v.TypeAlias.value);
1721
1.06k
    ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
1722
1.06k
    PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 0);
1723
1.06k
    _PyCompile_ExitScope(c);
1724
1.06k
    if (co == NULL) {
1725
0
        return ERROR;
1726
0
    }
1727
1.06k
    int ret = codegen_make_closure(c, loc, co, MAKE_FUNCTION_DEFAULTS);
1728
1.06k
    Py_DECREF(co);
1729
1.06k
    RETURN_IF_ERROR(ret);
1730
1731
1.06k
    ADDOP_I(c, loc, BUILD_TUPLE, 3);
1732
1.06k
    ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_TYPEALIAS);
1733
1.06k
    return SUCCESS;
1734
1.06k
}
1735
1736
static int
1737
codegen_typealias(compiler *c, stmt_ty s)
1738
1.06k
{
1739
1.06k
    location loc = LOC(s);
1740
1.06k
    asdl_type_param_seq *type_params = s->v.TypeAlias.type_params;
1741
1.06k
    int is_generic = asdl_seq_LEN(type_params) > 0;
1742
1.06k
    PyObject *name = s->v.TypeAlias.name->v.Name.id;
1743
1.06k
    if (is_generic) {
1744
1.04k
        PyObject *type_params_name = PyUnicode_FromFormat("<generic parameters of %U>",
1745
1.04k
                                                         name);
1746
1.04k
        if (!type_params_name) {
1747
0
            return ERROR;
1748
0
        }
1749
1.04k
        int ret = codegen_enter_scope(c, type_params_name, COMPILE_SCOPE_ANNOTATIONS,
1750
1.04k
                                      (void *)type_params, loc.lineno, NULL, NULL);
1751
1.04k
        Py_DECREF(type_params_name);
1752
1.04k
        RETURN_IF_ERROR(ret);
1753
1.04k
        ADDOP_LOAD_CONST_IN_SCOPE(c, loc, name);
1754
1.04k
        RETURN_IF_ERROR_IN_SCOPE(c, codegen_type_params(c, type_params));
1755
1.04k
    }
1756
24
    else {
1757
24
        ADDOP_LOAD_CONST(c, loc, name);
1758
24
        ADDOP_LOAD_CONST(c, loc, Py_None);
1759
24
    }
1760
1761
1.06k
    int ret = codegen_typealias_body(c, s);
1762
1.06k
    if (is_generic) {
1763
1.03k
        RETURN_IF_ERROR_IN_SCOPE(c, ret);
1764
1.03k
    }
1765
24
    else {
1766
24
        RETURN_IF_ERROR(ret);
1767
24
    }
1768
1769
1.06k
    if (is_generic) {
1770
1.03k
        PyCodeObject *co = _PyCompile_OptimizeAndAssemble(c, 0);
1771
1.03k
        _PyCompile_ExitScope(c);
1772
1.03k
        if (co == NULL) {
1773
0
            return ERROR;
1774
0
        }
1775
1.03k
        int ret = codegen_make_closure(c, loc, co, 0);
1776
1.03k
        Py_DECREF(co);
1777
1.03k
        RETURN_IF_ERROR(ret);
1778
1.03k
        ADDOP(c, loc, PUSH_NULL);
1779
1.03k
        ADDOP_I(c, loc, CALL, 0);
1780
1.03k
    }
1781
1.06k
    RETURN_IF_ERROR(codegen_nameop(c, loc, name, Store));
1782
1.06k
    return SUCCESS;
1783
1.06k
}
1784
1785
static bool
1786
is_const_tuple(asdl_expr_seq *elts)
1787
468
{
1788
555
    for (Py_ssize_t i = 0; i < asdl_seq_LEN(elts); i++) {
1789
129
        expr_ty e = (expr_ty)asdl_seq_GET(elts, i);
1790
129
        if (e->kind != Constant_kind) {
1791
42
            return false;
1792
42
        }
1793
129
    }
1794
426
    return true;
1795
468
}
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
63.7k
{
1802
63.7k
    if (e->kind == Tuple_kind) {
1803
468
        return !is_const_tuple(e->v.Tuple.elts);
1804
468
    }
1805
63.2k
    if (e->kind != Constant_kind) {
1806
49.5k
        return true;
1807
49.5k
    }
1808
13.7k
    PyObject *value = e->v.Constant.value;
1809
13.7k
    return (value == Py_None
1810
13.7k
         || value == Py_False
1811
13.7k
         || value == Py_True
1812
11.7k
         || value == Py_Ellipsis);
1813
63.2k
}
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
16.4k
{
1823
16.4k
    Py_ssize_t i, n;
1824
16.4k
    bool left = check_is_arg(e->v.Compare.left);
1825
16.4k
    expr_ty left_expr = e->v.Compare.left;
1826
16.4k
    n = asdl_seq_LEN(e->v.Compare.ops);
1827
61.6k
    for (i = 0; i < n; i++) {
1828
47.2k
        cmpop_ty op = (cmpop_ty)asdl_seq_GET(e->v.Compare.ops, i);
1829
47.2k
        expr_ty right_expr = (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i);
1830
47.2k
        bool right = check_is_arg(right_expr);
1831
47.2k
        if (op == Is || op == IsNot) {
1832
3.72k
            if (!right || !left) {
1833
2.07k
                const char *msg = (op == Is)
1834
2.07k
                        ? "\"is\" with '%.200s' literal. Did you mean \"==\"?"
1835
2.07k
                        : "\"is not\" with '%.200s' literal. Did you mean \"!=\"?";
1836
2.07k
                expr_ty literal = !left ? left_expr : right_expr;
1837
2.07k
                return _PyCompile_Warn(
1838
2.07k
                    c, LOC(e), msg, infer_type(literal)->tp_name
1839
2.07k
                );
1840
2.07k
            }
1841
3.72k
        }
1842
45.1k
        left = right;
1843
45.1k
        left_expr = right_expr;
1844
45.1k
    }
1845
14.4k
    return SUCCESS;
1846
16.4k
}
1847
1848
static int
1849
codegen_addcompare(compiler *c, location loc, cmpop_ty op)
1850
78.2k
{
1851
78.2k
    int cmp;
1852
78.2k
    switch (op) {
1853
30.4k
    case Eq:
1854
30.4k
        cmp = Py_EQ;
1855
30.4k
        break;
1856
1.17k
    case NotEq:
1857
1.17k
        cmp = Py_NE;
1858
1.17k
        break;
1859
14.4k
    case Lt:
1860
14.4k
        cmp = Py_LT;
1861
14.4k
        break;
1862
1.99k
    case LtE:
1863
1.99k
        cmp = Py_LE;
1864
1.99k
        break;
1865
20.4k
    case Gt:
1866
20.4k
        cmp = Py_GT;
1867
20.4k
        break;
1868
3.02k
    case GtE:
1869
3.02k
        cmp = Py_GE;
1870
3.02k
        break;
1871
4.84k
    case Is:
1872
4.84k
        ADDOP_I(c, loc, IS_OP, 0);
1873
4.84k
        return SUCCESS;
1874
48
    case IsNot:
1875
48
        ADDOP_I(c, loc, IS_OP, 1);
1876
48
        return SUCCESS;
1877
1.82k
    case In:
1878
1.82k
        ADDOP_I(c, loc, CONTAINS_OP, 0);
1879
1.82k
        return SUCCESS;
1880
37
    case NotIn:
1881
37
        ADDOP_I(c, loc, CONTAINS_OP, 1);
1882
37
        return SUCCESS;
1883
0
    default:
1884
0
        Py_UNREACHABLE();
1885
78.2k
    }
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
71.5k
    ADDOP_I(c, loc, COMPARE_OP, (cmp << 5) | compare_masks[cmp]);
1891
71.5k
    return SUCCESS;
1892
71.5k
}
1893
1894
static int
1895
codegen_jump_if(compiler *c, location loc,
1896
                expr_ty e, jump_target_label next, int cond)
1897
11.1k
{
1898
11.1k
    switch (e->kind) {
1899
539
    case UnaryOp_kind:
1900
539
        if (e->v.UnaryOp.op == Not) {
1901
13
            return codegen_jump_if(c, loc, e->v.UnaryOp.operand, next, !cond);
1902
13
        }
1903
        /* fallback to general implementation */
1904
526
        break;
1905
526
    case BoolOp_kind: {
1906
343
        asdl_expr_seq *s = e->v.BoolOp.values;
1907
343
        Py_ssize_t i, n = asdl_seq_LEN(s) - 1;
1908
343
        assert(n >= 0);
1909
343
        int cond2 = e->v.BoolOp.op == Or;
1910
343
        jump_target_label next2 = next;
1911
343
        if (!cond2 != !cond) {
1912
262
            NEW_JUMP_TARGET_LABEL(c, new_next2);
1913
262
            next2 = new_next2;
1914
262
        }
1915
2.69k
        for (i = 0; i < n; ++i) {
1916
2.35k
            RETURN_IF_ERROR(
1917
2.35k
                codegen_jump_if(c, loc, (expr_ty)asdl_seq_GET(s, i), next2, cond2));
1918
2.35k
        }
1919
335
        RETURN_IF_ERROR(
1920
335
            codegen_jump_if(c, loc, (expr_ty)asdl_seq_GET(s, n), next, cond));
1921
325
        if (!SAME_JUMP_TARGET_LABEL(next2, next)) {
1922
245
            USE_LABEL(c, next2);
1923
245
        }
1924
325
        return SUCCESS;
1925
325
    }
1926
84
    case IfExp_kind: {
1927
84
        NEW_JUMP_TARGET_LABEL(c, end);
1928
84
        NEW_JUMP_TARGET_LABEL(c, next2);
1929
84
        RETURN_IF_ERROR(
1930
84
            codegen_jump_if(c, loc, e->v.IfExp.test, next2, 0));
1931
84
        RETURN_IF_ERROR(
1932
84
            codegen_jump_if(c, loc, e->v.IfExp.body, next, cond));
1933
84
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
1934
1935
84
        USE_LABEL(c, next2);
1936
84
        RETURN_IF_ERROR(
1937
84
            codegen_jump_if(c, loc, e->v.IfExp.orelse, next, cond));
1938
1939
77
        USE_LABEL(c, end);
1940
77
        return SUCCESS;
1941
77
    }
1942
2.39k
    case Compare_kind: {
1943
2.39k
        Py_ssize_t n = asdl_seq_LEN(e->v.Compare.ops) - 1;
1944
2.39k
        if (n > 0) {
1945
1.28k
            RETURN_IF_ERROR(codegen_check_compare(c, e));
1946
1.28k
            NEW_JUMP_TARGET_LABEL(c, cleanup);
1947
1.28k
            VISIT(c, expr, e->v.Compare.left);
1948
4.73k
            for (Py_ssize_t i = 0; i < n; i++) {
1949
3.49k
                VISIT(c, expr,
1950
3.46k
                    (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
1951
3.46k
                ADDOP_I(c, LOC(e), SWAP, 2);
1952
3.46k
                ADDOP_I(c, LOC(e), COPY, 2);
1953
3.46k
                ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, i));
1954
3.46k
                ADDOP(c, LOC(e), TO_BOOL);
1955
3.46k
                ADDOP_JUMP(c, LOC(e), POP_JUMP_IF_FALSE, cleanup);
1956
3.46k
            }
1957
1.23k
            VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
1958
1.23k
            ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, n));
1959
1.23k
            ADDOP(c, LOC(e), TO_BOOL);
1960
1.23k
            ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
1961
1.23k
            NEW_JUMP_TARGET_LABEL(c, end);
1962
1.23k
            ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
1963
1964
1.23k
            USE_LABEL(c, cleanup);
1965
1.23k
            ADDOP(c, LOC(e), POP_TOP);
1966
1.23k
            if (!cond) {
1967
1.09k
                ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, next);
1968
1.09k
            }
1969
1970
1.23k
            USE_LABEL(c, end);
1971
1.23k
            return SUCCESS;
1972
1.23k
        }
1973
        /* fallback to general implementation */
1974
1.10k
        break;
1975
2.39k
    }
1976
7.80k
    default:
1977
        /* fallback to general implementation */
1978
7.80k
        break;
1979
11.1k
    }
1980
1981
    /* general implementation */
1982
9.43k
    VISIT(c, expr, e);
1983
9.42k
    ADDOP(c, LOC(e), TO_BOOL);
1984
9.42k
    ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
1985
9.42k
    return SUCCESS;
1986
9.42k
}
1987
1988
static int
1989
codegen_ifexp(compiler *c, expr_ty e)
1990
971
{
1991
971
    assert(e->kind == IfExp_kind);
1992
971
    NEW_JUMP_TARGET_LABEL(c, end);
1993
971
    NEW_JUMP_TARGET_LABEL(c, next);
1994
1995
971
    RETURN_IF_ERROR(
1996
971
        codegen_jump_if(c, LOC(e), e->v.IfExp.test, next, 0));
1997
1998
970
    VISIT(c, expr, e->v.IfExp.body);
1999
970
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2000
2001
970
    USE_LABEL(c, next);
2002
970
    VISIT(c, expr, e->v.IfExp.orelse);
2003
2004
884
    USE_LABEL(c, end);
2005
884
    return SUCCESS;
2006
884
}
2007
2008
static int
2009
codegen_lambda(compiler *c, expr_ty e)
2010
4.13k
{
2011
4.13k
    PyCodeObject *co;
2012
4.13k
    Py_ssize_t funcflags;
2013
4.13k
    arguments_ty args = e->v.Lambda.args;
2014
4.13k
    assert(e->kind == Lambda_kind);
2015
2016
4.13k
    location loc = LOC(e);
2017
4.13k
    funcflags = codegen_default_arguments(c, loc, args);
2018
4.13k
    RETURN_IF_ERROR(funcflags);
2019
2020
4.13k
    _PyCompile_CodeUnitMetadata umd = {
2021
4.13k
        .u_argcount = asdl_seq_LEN(args->args),
2022
4.13k
        .u_posonlyargcount = asdl_seq_LEN(args->posonlyargs),
2023
4.13k
        .u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs),
2024
4.13k
    };
2025
4.13k
    _Py_DECLARE_STR(anon_lambda, "<lambda>");
2026
4.13k
    RETURN_IF_ERROR(
2027
4.13k
        codegen_enter_scope(c, &_Py_STR(anon_lambda), COMPILE_SCOPE_LAMBDA,
2028
4.13k
                            (void *)e, e->lineno, NULL, &umd));
2029
2030
4.13k
    assert(!SYMTABLE_ENTRY(c)->ste_has_docstring);
2031
2032
4.13k
    VISIT_IN_SCOPE(c, expr, e->v.Lambda.body);
2033
4.13k
    if (SYMTABLE_ENTRY(c)->ste_generator) {
2034
0
        co = _PyCompile_OptimizeAndAssemble(c, 0);
2035
0
    }
2036
4.13k
    else {
2037
4.13k
        location loc = LOC(e->v.Lambda.body);
2038
4.13k
        ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
2039
4.13k
        co = _PyCompile_OptimizeAndAssemble(c, 1);
2040
4.13k
    }
2041
4.13k
    _PyCompile_ExitScope(c);
2042
4.13k
    if (co == NULL) {
2043
0
        return ERROR;
2044
0
    }
2045
2046
4.13k
    int ret = codegen_make_closure(c, loc, co, funcflags);
2047
4.13k
    Py_DECREF(co);
2048
4.13k
    RETURN_IF_ERROR(ret);
2049
4.13k
    return SUCCESS;
2050
4.13k
}
2051
2052
static int
2053
codegen_if(compiler *c, stmt_ty s)
2054
1.77k
{
2055
1.77k
    jump_target_label next;
2056
1.77k
    assert(s->kind == If_kind);
2057
1.77k
    NEW_JUMP_TARGET_LABEL(c, end);
2058
1.77k
    if (asdl_seq_LEN(s->v.If.orelse)) {
2059
507
        NEW_JUMP_TARGET_LABEL(c, orelse);
2060
507
        next = orelse;
2061
507
    }
2062
1.27k
    else {
2063
1.27k
        next = end;
2064
1.27k
    }
2065
1.77k
    RETURN_IF_ERROR(
2066
1.77k
        codegen_jump_if(c, LOC(s), s->v.If.test, next, 0));
2067
2068
1.77k
    VISIT_SEQ(c, stmt, s->v.If.body);
2069
1.77k
    if (asdl_seq_LEN(s->v.If.orelse)) {
2070
507
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2071
2072
507
        USE_LABEL(c, next);
2073
507
        VISIT_SEQ(c, stmt, s->v.If.orelse);
2074
507
    }
2075
2076
1.73k
    USE_LABEL(c, end);
2077
1.73k
    return SUCCESS;
2078
1.73k
}
2079
2080
static int
2081
codegen_for(compiler *c, stmt_ty s)
2082
84
{
2083
84
    location loc = LOC(s);
2084
84
    NEW_JUMP_TARGET_LABEL(c, start);
2085
84
    NEW_JUMP_TARGET_LABEL(c, body);
2086
84
    NEW_JUMP_TARGET_LABEL(c, cleanup);
2087
84
    NEW_JUMP_TARGET_LABEL(c, end);
2088
2089
84
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FOR_LOOP, start, end, NULL));
2090
2091
84
    VISIT(c, expr, s->v.For.iter);
2092
2093
83
    loc = LOC(s->v.For.iter);
2094
83
    ADDOP(c, loc, GET_ITER);
2095
2096
83
    USE_LABEL(c, start);
2097
83
    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
83
    ADDOP(c, LOC(s->v.For.target), NOP);
2103
2104
83
    USE_LABEL(c, body);
2105
83
    VISIT(c, expr, s->v.For.target);
2106
82
    VISIT_SEQ(c, stmt, s->v.For.body);
2107
    /* Mark jump as artificial */
2108
81
    ADDOP_JUMP(c, NO_LOCATION, JUMP, start);
2109
2110
81
    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
81
    ADDOP(c, NO_LOCATION, END_FOR);
2116
81
    ADDOP(c, NO_LOCATION, POP_ITER);
2117
2118
81
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_FOR_LOOP, start);
2119
2120
81
    VISIT_SEQ(c, stmt, s->v.For.orelse);
2121
2122
78
    USE_LABEL(c, end);
2123
78
    return SUCCESS;
2124
78
}
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
901
{
2177
901
    NEW_JUMP_TARGET_LABEL(c, loop);
2178
901
    NEW_JUMP_TARGET_LABEL(c, end);
2179
901
    NEW_JUMP_TARGET_LABEL(c, anchor);
2180
2181
901
    USE_LABEL(c, loop);
2182
2183
901
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, LOC(s), COMPILE_FBLOCK_WHILE_LOOP, loop, end, NULL));
2184
901
    RETURN_IF_ERROR(codegen_jump_if(c, LOC(s), s->v.While.test, anchor, 0));
2185
2186
901
    VISIT_SEQ(c, stmt, s->v.While.body);
2187
894
    ADDOP_JUMP(c, NO_LOCATION, JUMP, loop);
2188
2189
894
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_WHILE_LOOP, loop);
2190
2191
894
    USE_LABEL(c, anchor);
2192
894
    if (s->v.While.orelse) {
2193
40
        VISIT_SEQ(c, stmt, s->v.While.orelse);
2194
40
    }
2195
2196
893
    USE_LABEL(c, end);
2197
893
    return SUCCESS;
2198
893
}
2199
2200
static int
2201
codegen_return(compiler *c, stmt_ty s)
2202
307
{
2203
307
    location loc = LOC(s);
2204
307
    int preserve_tos = ((s->v.Return.value != NULL) &&
2205
127
                        (s->v.Return.value->kind != Constant_kind));
2206
2207
307
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
2208
307
    if (!_PyST_IsFunctionLike(ste)) {
2209
10
        return _PyCompile_Error(c, loc, "'return' outside function");
2210
10
    }
2211
297
    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
296
    if (preserve_tos) {
2216
53
        VISIT(c, expr, s->v.Return.value);
2217
243
    } else {
2218
        /* Emit instruction with line number for return value */
2219
243
        if (s->v.Return.value != NULL) {
2220
71
            loc = LOC(s->v.Return.value);
2221
71
            ADDOP(c, loc, NOP);
2222
71
        }
2223
243
    }
2224
295
    if (s->v.Return.value == NULL || s->v.Return.value->lineno != s->lineno) {
2225
172
        loc = LOC(s);
2226
172
        ADDOP(c, loc, NOP);
2227
172
    }
2228
2229
295
    RETURN_IF_ERROR(codegen_unwind_fblock_stack(c, &loc, preserve_tos, NULL));
2230
295
    if (s->v.Return.value == NULL) {
2231
172
        ADDOP_LOAD_CONST(c, loc, Py_None);
2232
172
    }
2233
123
    else if (!preserve_tos) {
2234
71
        ADDOP_LOAD_CONST(c, loc, s->v.Return.value->v.Constant.value);
2235
71
    }
2236
295
    ADDOP(c, loc, RETURN_VALUE);
2237
2238
295
    return SUCCESS;
2239
295
}
2240
2241
static int
2242
codegen_break(compiler *c, location loc)
2243
17
{
2244
17
    fblockinfo *loop = NULL;
2245
17
    location origin_loc = loc;
2246
    /* Emit instruction with line number */
2247
17
    ADDOP(c, loc, NOP);
2248
17
    RETURN_IF_ERROR(codegen_unwind_fblock_stack(c, &loc, 0, &loop));
2249
16
    if (loop == NULL) {
2250
15
        return _PyCompile_Error(c, origin_loc, "'break' outside loop");
2251
15
    }
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
73
{
2260
73
    fblockinfo *loop = NULL;
2261
73
    location origin_loc = loc;
2262
    /* Emit instruction with line number */
2263
73
    ADDOP(c, loc, NOP);
2264
73
    RETURN_IF_ERROR(codegen_unwind_fblock_stack(c, &loc, 0, &loop));
2265
72
    if (loop == NULL) {
2266
11
        return _PyCompile_Error(c, origin_loc, "'continue' not properly in loop");
2267
11
    }
2268
61
    ADDOP_JUMP(c, loc, JUMP, loop->fb_block);
2269
61
    return SUCCESS;
2270
61
}
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.09k
{
2305
1.09k
    location loc = LOC(s);
2306
2307
1.09k
    NEW_JUMP_TARGET_LABEL(c, body);
2308
1.09k
    NEW_JUMP_TARGET_LABEL(c, end);
2309
1.09k
    NEW_JUMP_TARGET_LABEL(c, exit);
2310
1.09k
    NEW_JUMP_TARGET_LABEL(c, cleanup);
2311
2312
    /* `try` block */
2313
1.09k
    ADDOP_JUMP(c, loc, SETUP_FINALLY, end);
2314
2315
1.09k
    USE_LABEL(c, body);
2316
1.09k
    RETURN_IF_ERROR(
2317
1.09k
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FINALLY_TRY, body, end,
2318
1.09k
                              s->v.Try.finalbody));
2319
2320
1.09k
    if (s->v.Try.handlers && asdl_seq_LEN(s->v.Try.handlers)) {
2321
351
        RETURN_IF_ERROR(codegen_try_except(c, s));
2322
351
    }
2323
743
    else {
2324
743
        VISIT_SEQ(c, stmt, s->v.Try.body);
2325
743
    }
2326
1.09k
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2327
1.09k
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_FINALLY_TRY, body);
2328
1.09k
    VISIT_SEQ(c, stmt, s->v.Try.finalbody);
2329
2330
1.08k
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, exit);
2331
    /* `finally` block */
2332
2333
1.08k
    USE_LABEL(c, end);
2334
2335
1.08k
    loc = NO_LOCATION;
2336
1.08k
    ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
2337
1.08k
    ADDOP(c, loc, PUSH_EXC_INFO);
2338
1.08k
    RETURN_IF_ERROR(
2339
1.08k
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FINALLY_END, end, NO_LABEL, NULL));
2340
1.08k
    VISIT_SEQ(c, stmt, s->v.Try.finalbody);
2341
1.08k
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_FINALLY_END, end);
2342
2343
1.08k
    loc = NO_LOCATION;
2344
1.08k
    ADDOP_I(c, loc, RERAISE, 0);
2345
2346
1.08k
    USE_LABEL(c, cleanup);
2347
1.08k
    POP_EXCEPT_AND_RERAISE(c, loc);
2348
2349
1.08k
    USE_LABEL(c, exit);
2350
1.08k
    return SUCCESS;
2351
1.08k
}
2352
2353
static int
2354
codegen_try_star_finally(compiler *c, stmt_ty s)
2355
39
{
2356
39
    location loc = LOC(s);
2357
2358
39
    NEW_JUMP_TARGET_LABEL(c, body);
2359
39
    NEW_JUMP_TARGET_LABEL(c, end);
2360
39
    NEW_JUMP_TARGET_LABEL(c, exit);
2361
39
    NEW_JUMP_TARGET_LABEL(c, cleanup);
2362
    /* `try` block */
2363
39
    ADDOP_JUMP(c, loc, SETUP_FINALLY, end);
2364
2365
39
    USE_LABEL(c, body);
2366
39
    RETURN_IF_ERROR(
2367
39
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FINALLY_TRY, body, end,
2368
39
                              s->v.TryStar.finalbody));
2369
2370
39
    if (s->v.TryStar.handlers && asdl_seq_LEN(s->v.TryStar.handlers)) {
2371
39
        RETURN_IF_ERROR(codegen_try_star_except(c, s));
2372
39
    }
2373
0
    else {
2374
0
        VISIT_SEQ(c, stmt, s->v.TryStar.body);
2375
0
    }
2376
38
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2377
38
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_FINALLY_TRY, body);
2378
38
    VISIT_SEQ(c, stmt, s->v.TryStar.finalbody);
2379
2380
37
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, exit);
2381
2382
    /* `finally` block */
2383
37
    USE_LABEL(c, end);
2384
2385
37
    loc = NO_LOCATION;
2386
37
    ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
2387
37
    ADDOP(c, loc, PUSH_EXC_INFO);
2388
37
    RETURN_IF_ERROR(
2389
37
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_FINALLY_END, end, NO_LABEL, NULL));
2390
2391
37
    VISIT_SEQ(c, stmt, s->v.TryStar.finalbody);
2392
2393
37
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_FINALLY_END, end);
2394
37
    loc = NO_LOCATION;
2395
37
    ADDOP_I(c, loc, RERAISE, 0);
2396
2397
37
    USE_LABEL(c, cleanup);
2398
37
    POP_EXCEPT_AND_RERAISE(c, loc);
2399
2400
37
    USE_LABEL(c, exit);
2401
37
    return SUCCESS;
2402
37
}
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
596
{
2436
596
    location loc = LOC(s);
2437
596
    Py_ssize_t i, n;
2438
2439
596
    NEW_JUMP_TARGET_LABEL(c, body);
2440
596
    NEW_JUMP_TARGET_LABEL(c, except);
2441
596
    NEW_JUMP_TARGET_LABEL(c, end);
2442
596
    NEW_JUMP_TARGET_LABEL(c, cleanup);
2443
2444
596
    ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
2445
2446
596
    USE_LABEL(c, body);
2447
596
    RETURN_IF_ERROR(
2448
596
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_TRY_EXCEPT, body, NO_LABEL, NULL));
2449
596
    VISIT_SEQ(c, stmt, s->v.Try.body);
2450
595
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_TRY_EXCEPT, body);
2451
595
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2452
595
    if (s->v.Try.orelse && asdl_seq_LEN(s->v.Try.orelse)) {
2453
28
        VISIT_SEQ(c, stmt, s->v.Try.orelse);
2454
28
    }
2455
594
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2456
594
    n = asdl_seq_LEN(s->v.Try.handlers);
2457
2458
594
    USE_LABEL(c, except);
2459
2460
594
    ADDOP_JUMP(c, NO_LOCATION, SETUP_CLEANUP, cleanup);
2461
594
    ADDOP(c, NO_LOCATION, PUSH_EXC_INFO);
2462
2463
    /* Runtime will push a block here, so we need to account for that */
2464
594
    RETURN_IF_ERROR(
2465
594
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_EXCEPTION_HANDLER,
2466
594
                              NO_LABEL, NO_LABEL, NULL));
2467
2468
1.23k
    for (i = 0; i < n; i++) {
2469
656
        excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
2470
656
            s->v.Try.handlers, i);
2471
656
        location loc = LOC(handler);
2472
656
        if (!handler->v.ExceptHandler.type && i < n-1) {
2473
8
            return _PyCompile_Error(c, loc, "default 'except:' must be last");
2474
8
        }
2475
648
        NEW_JUMP_TARGET_LABEL(c, next_except);
2476
648
        except = next_except;
2477
648
        if (handler->v.ExceptHandler.type) {
2478
263
            VISIT(c, expr, handler->v.ExceptHandler.type);
2479
263
            ADDOP(c, loc, CHECK_EXC_MATCH);
2480
263
            ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, except);
2481
263
        }
2482
648
        if (handler->v.ExceptHandler.name) {
2483
6
            NEW_JUMP_TARGET_LABEL(c, cleanup_end);
2484
6
            NEW_JUMP_TARGET_LABEL(c, cleanup_body);
2485
2486
6
            RETURN_IF_ERROR(
2487
6
                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
6
            ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup_end);
2502
2503
6
            USE_LABEL(c, cleanup_body);
2504
6
            RETURN_IF_ERROR(
2505
6
                _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body,
2506
6
                                      NO_LABEL, handler->v.ExceptHandler.name));
2507
2508
            /* second # body */
2509
6
            VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
2510
6
            _PyCompile_PopFBlock(c, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body);
2511
            /* name = None; del name; # Mark as artificial */
2512
6
            ADDOP(c, NO_LOCATION, POP_BLOCK);
2513
6
            ADDOP(c, NO_LOCATION, POP_BLOCK);
2514
6
            ADDOP(c, NO_LOCATION, POP_EXCEPT);
2515
6
            ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
2516
6
            RETURN_IF_ERROR(
2517
6
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
2518
6
            RETURN_IF_ERROR(
2519
6
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
2520
6
            ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2521
2522
            /* except: */
2523
6
            USE_LABEL(c, cleanup_end);
2524
2525
            /* name = None; del name; # artificial */
2526
6
            ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
2527
6
            RETURN_IF_ERROR(
2528
6
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
2529
6
            RETURN_IF_ERROR(
2530
6
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
2531
2532
6
            ADDOP_I(c, NO_LOCATION, RERAISE, 1);
2533
6
        }
2534
642
        else {
2535
642
            NEW_JUMP_TARGET_LABEL(c, cleanup_body);
2536
2537
642
            ADDOP(c, loc, POP_TOP); /* exc_value */
2538
2539
642
            USE_LABEL(c, cleanup_body);
2540
642
            RETURN_IF_ERROR(
2541
642
                _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body,
2542
642
                                      NO_LABEL, NULL));
2543
2544
642
            VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
2545
638
            _PyCompile_PopFBlock(c, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body);
2546
638
            ADDOP(c, NO_LOCATION, POP_BLOCK);
2547
638
            ADDOP(c, NO_LOCATION, POP_EXCEPT);
2548
638
            ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2549
638
        }
2550
2551
644
        USE_LABEL(c, except);
2552
644
    }
2553
    /* artificial */
2554
582
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_EXCEPTION_HANDLER, NO_LABEL);
2555
582
    ADDOP_I(c, NO_LOCATION, RERAISE, 0);
2556
2557
582
    USE_LABEL(c, cleanup);
2558
582
    POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
2559
2560
582
    USE_LABEL(c, end);
2561
582
    return SUCCESS;
2562
582
}
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
829
{
2619
829
    location loc = LOC(s);
2620
2621
829
    NEW_JUMP_TARGET_LABEL(c, body);
2622
829
    NEW_JUMP_TARGET_LABEL(c, except);
2623
829
    NEW_JUMP_TARGET_LABEL(c, orelse);
2624
829
    NEW_JUMP_TARGET_LABEL(c, end);
2625
829
    NEW_JUMP_TARGET_LABEL(c, cleanup);
2626
829
    NEW_JUMP_TARGET_LABEL(c, reraise_star);
2627
2628
829
    ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
2629
2630
829
    USE_LABEL(c, body);
2631
829
    RETURN_IF_ERROR(
2632
829
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_TRY_EXCEPT, body, NO_LABEL, NULL));
2633
829
    VISIT_SEQ(c, stmt, s->v.TryStar.body);
2634
828
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_TRY_EXCEPT, body);
2635
828
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2636
828
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, orelse);
2637
828
    Py_ssize_t n = asdl_seq_LEN(s->v.TryStar.handlers);
2638
2639
828
    USE_LABEL(c, except);
2640
2641
828
    ADDOP_JUMP(c, NO_LOCATION, SETUP_CLEANUP, cleanup);
2642
828
    ADDOP(c, NO_LOCATION, PUSH_EXC_INFO);
2643
2644
    /* Runtime will push a block here, so we need to account for that */
2645
828
    RETURN_IF_ERROR(
2646
828
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_EXCEPTION_GROUP_HANDLER,
2647
828
                              NO_LABEL, NO_LABEL, "except handler"));
2648
2649
2.45k
    for (Py_ssize_t i = 0; i < n; i++) {
2650
1.63k
        excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
2651
1.63k
            s->v.TryStar.handlers, i);
2652
1.63k
        location loc = LOC(handler);
2653
1.63k
        NEW_JUMP_TARGET_LABEL(c, next_except);
2654
1.63k
        except = next_except;
2655
1.63k
        NEW_JUMP_TARGET_LABEL(c, except_with_error);
2656
1.63k
        NEW_JUMP_TARGET_LABEL(c, no_match);
2657
1.63k
        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
828
            ADDOP_I(c, loc, BUILD_LIST, 0);
2668
828
            ADDOP_I(c, loc, COPY, 2);
2669
828
        }
2670
1.63k
        if (handler->v.ExceptHandler.type) {
2671
1.63k
            VISIT(c, expr, handler->v.ExceptHandler.type);
2672
1.63k
            ADDOP(c, loc, CHECK_EG_MATCH);
2673
1.63k
            ADDOP_I(c, loc, COPY, 1);
2674
1.63k
            ADDOP_JUMP(c, loc, POP_JUMP_IF_NONE, no_match);
2675
1.63k
        }
2676
2677
1.63k
        NEW_JUMP_TARGET_LABEL(c, cleanup_end);
2678
1.63k
        NEW_JUMP_TARGET_LABEL(c, cleanup_body);
2679
2680
1.63k
        if (handler->v.ExceptHandler.name) {
2681
291
            RETURN_IF_ERROR(
2682
291
                codegen_nameop(c, loc, handler->v.ExceptHandler.name, Store));
2683
291
        }
2684
1.34k
        else {
2685
1.34k
            ADDOP(c, loc, POP_TOP);  // match
2686
1.34k
        }
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.63k
        ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup_end);
2700
2701
1.63k
        USE_LABEL(c, cleanup_body);
2702
1.63k
        RETURN_IF_ERROR(
2703
1.63k
            _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body,
2704
1.63k
                                  NO_LABEL, handler->v.ExceptHandler.name));
2705
2706
        /* second # body */
2707
1.63k
        VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
2708
1.62k
        _PyCompile_PopFBlock(c, COMPILE_FBLOCK_HANDLER_CLEANUP, cleanup_body);
2709
        /* name = None; del name; # artificial */
2710
1.62k
        ADDOP(c, NO_LOCATION, POP_BLOCK);
2711
1.62k
        if (handler->v.ExceptHandler.name) {
2712
291
            ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
2713
291
            RETURN_IF_ERROR(
2714
291
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
2715
291
            RETURN_IF_ERROR(
2716
291
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
2717
291
        }
2718
1.62k
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, except);
2719
2720
        /* except: */
2721
1.62k
        USE_LABEL(c, cleanup_end);
2722
2723
        /* name = None; del name; # artificial */
2724
1.62k
        if (handler->v.ExceptHandler.name) {
2725
291
            ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
2726
291
            RETURN_IF_ERROR(
2727
291
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
2728
291
            RETURN_IF_ERROR(
2729
291
                codegen_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
2730
291
        }
2731
2732
        /* add exception raised to the res list */
2733
1.62k
        ADDOP_I(c, NO_LOCATION, LIST_APPEND, 3); // exc
2734
1.62k
        ADDOP(c, NO_LOCATION, POP_TOP); // lasti
2735
1.62k
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, except_with_error);
2736
2737
1.62k
        USE_LABEL(c, except);
2738
1.62k
        ADDOP(c, NO_LOCATION, NOP);  // to hold a propagated location info
2739
1.62k
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, except_with_error);
2740
2741
1.62k
        USE_LABEL(c, no_match);
2742
1.62k
        ADDOP(c, loc, POP_TOP);  // match (None)
2743
2744
1.62k
        USE_LABEL(c, except_with_error);
2745
2746
1.62k
        if (i == n - 1) {
2747
            /* Add exc to the list (if not None it's the unhandled part of the EG) */
2748
824
            ADDOP_I(c, NO_LOCATION, LIST_APPEND, 1);
2749
824
            ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, reraise_star);
2750
824
        }
2751
1.62k
    }
2752
    /* artificial */
2753
824
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_EXCEPTION_GROUP_HANDLER, NO_LABEL);
2754
824
    NEW_JUMP_TARGET_LABEL(c, reraise);
2755
2756
824
    USE_LABEL(c, reraise_star);
2757
824
    ADDOP_I(c, NO_LOCATION, CALL_INTRINSIC_2, INTRINSIC_PREP_RERAISE_STAR);
2758
824
    ADDOP_I(c, NO_LOCATION, COPY, 1);
2759
824
    ADDOP_JUMP(c, NO_LOCATION, POP_JUMP_IF_NOT_NONE, reraise);
2760
2761
    /* Nothing to reraise */
2762
824
    ADDOP(c, NO_LOCATION, POP_TOP);
2763
824
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2764
824
    ADDOP(c, NO_LOCATION, POP_EXCEPT);
2765
824
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
2766
2767
824
    USE_LABEL(c, reraise);
2768
824
    ADDOP(c, NO_LOCATION, POP_BLOCK);
2769
824
    ADDOP_I(c, NO_LOCATION, SWAP, 2);
2770
824
    ADDOP(c, NO_LOCATION, POP_EXCEPT);
2771
824
    ADDOP_I(c, NO_LOCATION, RERAISE, 0);
2772
2773
824
    USE_LABEL(c, cleanup);
2774
824
    POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
2775
2776
824
    USE_LABEL(c, orelse);
2777
824
    VISIT_SEQ(c, stmt, s->v.TryStar.orelse);
2778
2779
823
    USE_LABEL(c, end);
2780
823
    return SUCCESS;
2781
823
}
2782
2783
static int
2784
1.33k
codegen_try(compiler *c, stmt_ty s) {
2785
1.33k
    if (s->v.Try.finalbody && asdl_seq_LEN(s->v.Try.finalbody))
2786
1.09k
        return codegen_try_finally(c, s);
2787
245
    else
2788
245
        return codegen_try_except(c, s);
2789
1.33k
}
2790
2791
static int
2792
codegen_try_star(compiler *c, stmt_ty s)
2793
829
{
2794
829
    if (s->v.TryStar.finalbody && asdl_seq_LEN(s->v.TryStar.finalbody)) {
2795
39
        return codegen_try_star_finally(c, s);
2796
39
    }
2797
790
    else {
2798
790
        return codegen_try_star_except(c, s);
2799
790
    }
2800
829
}
2801
2802
static int
2803
codegen_import_as(compiler *c, location loc,
2804
                  identifier name, identifier asname)
2805
215
{
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
215
    Py_ssize_t len = PyUnicode_GET_LENGTH(name);
2813
215
    Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0, len, 1);
2814
215
    if (dot == -2) {
2815
0
        return ERROR;
2816
0
    }
2817
215
    if (dot != -1) {
2818
        /* Consume the base module name to get the first attribute */
2819
2.35k
        while (1) {
2820
2.35k
            Py_ssize_t pos = dot + 1;
2821
2.35k
            PyObject *attr;
2822
2.35k
            dot = PyUnicode_FindChar(name, '.', pos, len, 1);
2823
2.35k
            if (dot == -2) {
2824
0
                return ERROR;
2825
0
            }
2826
2.35k
            attr = PyUnicode_Substring(name, pos, (dot != -1) ? dot : len);
2827
2.35k
            if (!attr) {
2828
0
                return ERROR;
2829
0
            }
2830
2.35k
            ADDOP_N(c, loc, IMPORT_FROM, attr, names);
2831
2.35k
            if (dot == -1) {
2832
141
                break;
2833
141
            }
2834
2.21k
            ADDOP_I(c, loc, SWAP, 2);
2835
2.21k
            ADDOP(c, loc, POP_TOP);
2836
2.21k
        }
2837
141
        RETURN_IF_ERROR(codegen_nameop(c, loc, asname, Store));
2838
141
        ADDOP(c, loc, POP_TOP);
2839
141
        return SUCCESS;
2840
141
    }
2841
74
    return codegen_nameop(c, loc, asname, Store);
2842
215
}
2843
2844
static int
2845
codegen_import(compiler *c, stmt_ty s)
2846
623
{
2847
623
    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
623
    Py_ssize_t i, n = asdl_seq_LEN(s->v.Import.names);
2856
2857
623
    PyObject *zero = _PyLong_GetZero();  // borrowed reference
2858
4.17k
    for (i = 0; i < n; i++) {
2859
3.55k
        alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i);
2860
3.55k
        int r;
2861
2862
3.55k
        ADDOP_LOAD_CONST(c, loc, zero);
2863
3.55k
        ADDOP_LOAD_CONST(c, loc, Py_None);
2864
3.55k
        ADDOP_NAME(c, loc, IMPORT_NAME, alias->name, names);
2865
2866
3.55k
        if (alias->asname) {
2867
215
            r = codegen_import_as(c, loc, alias->name, alias->asname);
2868
215
            RETURN_IF_ERROR(r);
2869
215
        }
2870
3.33k
        else {
2871
3.33k
            identifier tmp = alias->name;
2872
3.33k
            Py_ssize_t dot = PyUnicode_FindChar(
2873
3.33k
                alias->name, '.', 0, PyUnicode_GET_LENGTH(alias->name), 1);
2874
3.33k
            if (dot != -1) {
2875
1.49k
                tmp = PyUnicode_Substring(alias->name, 0, dot);
2876
1.49k
                if (tmp == NULL) {
2877
0
                    return ERROR;
2878
0
                }
2879
1.49k
            }
2880
3.33k
            r = codegen_nameop(c, loc, tmp, Store);
2881
3.33k
            if (dot != -1) {
2882
1.49k
                Py_DECREF(tmp);
2883
1.49k
            }
2884
3.33k
            RETURN_IF_ERROR(r);
2885
3.33k
        }
2886
3.55k
    }
2887
623
    return SUCCESS;
2888
623
}
2889
2890
static int
2891
codegen_from_import(compiler *c, stmt_ty s)
2892
2.98k
{
2893
2.98k
    Py_ssize_t n = asdl_seq_LEN(s->v.ImportFrom.names);
2894
2895
2.98k
    ADDOP_LOAD_CONST_NEW(c, LOC(s), PyLong_FromLong(s->v.ImportFrom.level));
2896
2897
2.98k
    PyObject *names = PyTuple_New(n);
2898
2.98k
    if (!names) {
2899
0
        return ERROR;
2900
0
    }
2901
2902
    /* build up the names */
2903
7.06k
    for (Py_ssize_t i = 0; i < n; i++) {
2904
4.07k
        alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
2905
4.07k
        PyTuple_SET_ITEM(names, i, Py_NewRef(alias->name));
2906
4.07k
    }
2907
2908
2.98k
    ADDOP_LOAD_CONST_NEW(c, LOC(s), names);
2909
2910
2.98k
    if (s->v.ImportFrom.module) {
2911
2.49k
        ADDOP_NAME(c, LOC(s), IMPORT_NAME, s->v.ImportFrom.module, names);
2912
2.49k
    }
2913
491
    else {
2914
491
        _Py_DECLARE_STR(empty, "");
2915
491
        ADDOP_NAME(c, LOC(s), IMPORT_NAME, &_Py_STR(empty), names);
2916
491
    }
2917
6.79k
    for (Py_ssize_t i = 0; i < n; i++) {
2918
4.07k
        alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
2919
4.07k
        identifier store_name;
2920
2921
4.07k
        if (i == 0 && PyUnicode_READ_CHAR(alias->name, 0) == '*') {
2922
264
            assert(n == 1);
2923
264
            ADDOP_I(c, LOC(s), CALL_INTRINSIC_1, INTRINSIC_IMPORT_STAR);
2924
264
            ADDOP(c, NO_LOCATION, POP_TOP);
2925
264
            return SUCCESS;
2926
264
        }
2927
2928
3.81k
        ADDOP_NAME(c, LOC(s), IMPORT_FROM, alias->name, names);
2929
3.81k
        store_name = alias->name;
2930
3.81k
        if (alias->asname) {
2931
115
            store_name = alias->asname;
2932
115
        }
2933
2934
3.81k
        RETURN_IF_ERROR(codegen_nameop(c, LOC(s), store_name, Store));
2935
3.81k
    }
2936
    /* remove imported module */
2937
2.72k
    ADDOP(c, LOC(s), POP_TOP);
2938
2.72k
    return SUCCESS;
2939
2.72k
}
2940
2941
static int
2942
codegen_assert(compiler *c, stmt_ty s)
2943
2.56k
{
2944
    /* Always emit a warning if the test is a non-zero length tuple */
2945
2.56k
    if ((s->v.Assert.test->kind == Tuple_kind &&
2946
125
        asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) ||
2947
2.44k
        (s->v.Assert.test->kind == Constant_kind &&
2948
2.44k
         PyTuple_Check(s->v.Assert.test->v.Constant.value) &&
2949
0
         PyTuple_Size(s->v.Assert.test->v.Constant.value) > 0))
2950
115
    {
2951
115
        RETURN_IF_ERROR(
2952
115
            _PyCompile_Warn(c, LOC(s), "assertion is always true, "
2953
115
                                       "perhaps remove parentheses?"));
2954
115
    }
2955
2.56k
    if (OPTIMIZATION_LEVEL(c)) {
2956
158
        return SUCCESS;
2957
158
    }
2958
2.40k
    NEW_JUMP_TARGET_LABEL(c, end);
2959
2.40k
    RETURN_IF_ERROR(codegen_jump_if(c, LOC(s), s->v.Assert.test, end, 1));
2960
2.40k
    ADDOP_I(c, LOC(s), LOAD_COMMON_CONSTANT, CONSTANT_ASSERTIONERROR);
2961
2.40k
    if (s->v.Assert.msg) {
2962
973
        VISIT(c, expr, s->v.Assert.msg);
2963
972
        ADDOP_I(c, LOC(s), CALL, 0);
2964
972
    }
2965
2.40k
    ADDOP_I(c, LOC(s->v.Assert.test), RAISE_VARARGS, 1);
2966
2967
2.40k
    USE_LABEL(c, end);
2968
2.40k
    return SUCCESS;
2969
2.40k
}
2970
2971
static int
2972
codegen_stmt_expr(compiler *c, location loc, expr_ty value)
2973
97.1k
{
2974
97.1k
    if (IS_INTERACTIVE_TOP_LEVEL(c)) {
2975
8.67k
        VISIT(c, expr, value);
2976
8.62k
        ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_PRINT);
2977
8.62k
        ADDOP(c, NO_LOCATION, POP_TOP);
2978
8.62k
        return SUCCESS;
2979
8.62k
    }
2980
2981
88.4k
    if (value->kind == Constant_kind) {
2982
        /* ignore constant statement */
2983
5.11k
        ADDOP(c, loc, NOP);
2984
5.11k
        return SUCCESS;
2985
5.11k
    }
2986
2987
83.3k
    VISIT(c, expr, value);
2988
83.2k
    ADDOP(c, NO_LOCATION, POP_TOP); /* artificial */
2989
83.2k
    return SUCCESS;
2990
83.2k
}
2991
2992
#define CODEGEN_COND_BLOCK(FUNC, C, S) \
2993
7.03k
    do { \
2994
7.03k
        _PyCompile_EnterConditionalBlock((C)); \
2995
7.03k
        int result = FUNC((C), (S)); \
2996
7.03k
        _PyCompile_LeaveConditionalBlock((C)); \
2997
7.03k
        return result; \
2998
7.03k
    } while(0)
2999
3000
static int
3001
codegen_visit_stmt(compiler *c, stmt_ty s)
3002
154k
{
3003
3004
154k
    switch (s->kind) {
3005
4.75k
    case FunctionDef_kind:
3006
4.75k
        return codegen_function(c, s, 0);
3007
7.28k
    case ClassDef_kind:
3008
7.28k
        return codegen_class(c, s);
3009
1.06k
    case TypeAlias_kind:
3010
1.06k
        return codegen_typealias(c, s);
3011
307
    case Return_kind:
3012
307
        return codegen_return(c, s);
3013
1.50k
    case Delete_kind:
3014
1.50k
        VISIT_SEQ(c, expr, s->v.Delete.targets);
3015
1.50k
        break;
3016
6.57k
    case Assign_kind:
3017
6.57k
    {
3018
6.57k
        Py_ssize_t n = asdl_seq_LEN(s->v.Assign.targets);
3019
6.57k
        VISIT(c, expr, s->v.Assign.value);
3020
43.9k
        for (Py_ssize_t i = 0; i < n; i++) {
3021
37.4k
            if (i < n - 1) {
3022
30.8k
                ADDOP_I(c, LOC(s), COPY, 1);
3023
30.8k
            }
3024
37.4k
            VISIT(c, expr,
3025
37.4k
                  (expr_ty)asdl_seq_GET(s->v.Assign.targets, i));
3026
37.4k
        }
3027
6.56k
        break;
3028
6.56k
    }
3029
6.56k
    case AugAssign_kind:
3030
2.54k
        return codegen_augassign(c, s);
3031
16.7k
    case AnnAssign_kind:
3032
16.7k
        return codegen_annassign(c, s);
3033
84
    case For_kind:
3034
84
        CODEGEN_COND_BLOCK(codegen_for, c, s);
3035
0
        break;
3036
901
    case While_kind:
3037
901
        CODEGEN_COND_BLOCK(codegen_while, c, s);
3038
0
        break;
3039
1.77k
    case If_kind:
3040
1.77k
        CODEGEN_COND_BLOCK(codegen_if, c, s);
3041
0
        break;
3042
272
    case Match_kind:
3043
272
        CODEGEN_COND_BLOCK(codegen_match, c, s);
3044
0
        break;
3045
1.30k
    case Raise_kind:
3046
1.30k
    {
3047
1.30k
        Py_ssize_t n = 0;
3048
1.30k
        if (s->v.Raise.exc) {
3049
818
            VISIT(c, expr, s->v.Raise.exc);
3050
818
            n++;
3051
818
            if (s->v.Raise.cause) {
3052
40
                VISIT(c, expr, s->v.Raise.cause);
3053
40
                n++;
3054
40
            }
3055
818
        }
3056
1.30k
        ADDOP_I(c, LOC(s), RAISE_VARARGS, (int)n);
3057
1.30k
        break;
3058
1.30k
    }
3059
1.33k
    case Try_kind:
3060
1.33k
        CODEGEN_COND_BLOCK(codegen_try, c, s);
3061
0
        break;
3062
829
    case TryStar_kind:
3063
829
        CODEGEN_COND_BLOCK(codegen_try_star, c, s);
3064
0
        break;
3065
2.56k
    case Assert_kind:
3066
2.56k
        return codegen_assert(c, s);
3067
623
    case Import_kind:
3068
623
        return codegen_import(c, s);
3069
2.98k
    case ImportFrom_kind:
3070
2.98k
        return codegen_from_import(c, s);
3071
238
    case Global_kind:
3072
238
    case Nonlocal_kind:
3073
238
        break;
3074
97.1k
    case Expr_kind:
3075
97.1k
    {
3076
97.1k
        return codegen_stmt_expr(c, LOC(s), s->v.Expr.value);
3077
238
    }
3078
331
    case Pass_kind:
3079
331
    {
3080
331
        ADDOP(c, LOC(s), NOP);
3081
331
        break;
3082
331
    }
3083
331
    case Break_kind:
3084
17
    {
3085
17
        return codegen_break(c, LOC(s));
3086
331
    }
3087
73
    case Continue_kind:
3088
73
    {
3089
73
        return codegen_continue(c, LOC(s));
3090
331
    }
3091
1.02k
    case With_kind:
3092
1.02k
        CODEGEN_COND_BLOCK(codegen_with, c, s);
3093
0
        break;
3094
1.83k
    case AsyncFunctionDef_kind:
3095
1.83k
        return codegen_function(c, s, 1);
3096
813
    case AsyncWith_kind:
3097
813
        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
154k
    }
3103
3104
9.94k
    return SUCCESS;
3105
154k
}
3106
3107
static int
3108
unaryop(unaryop_ty op)
3109
124k
{
3110
124k
    switch (op) {
3111
14.9k
    case Invert:
3112
14.9k
        return UNARY_INVERT;
3113
109k
    case USub:
3114
109k
        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
124k
    }
3120
124k
}
3121
3122
static int
3123
addop_binary(compiler *c, location loc, operator_ty binop,
3124
             bool inplace)
3125
538k
{
3126
538k
    int oparg;
3127
538k
    switch (binop) {
3128
79.1k
        case Add:
3129
79.1k
            oparg = inplace ? NB_INPLACE_ADD : NB_ADD;
3130
79.1k
            break;
3131
97.9k
        case Sub:
3132
97.9k
            oparg = inplace ? NB_INPLACE_SUBTRACT : NB_SUBTRACT;
3133
97.9k
            break;
3134
105k
        case Mult:
3135
105k
            oparg = inplace ? NB_INPLACE_MULTIPLY : NB_MULTIPLY;
3136
105k
            break;
3137
1.83k
        case MatMult:
3138
1.83k
            oparg = inplace ? NB_INPLACE_MATRIX_MULTIPLY : NB_MATRIX_MULTIPLY;
3139
1.83k
            break;
3140
75.5k
        case Div:
3141
75.5k
            oparg = inplace ? NB_INPLACE_TRUE_DIVIDE : NB_TRUE_DIVIDE;
3142
75.5k
            break;
3143
38.8k
        case Mod:
3144
38.8k
            oparg = inplace ? NB_INPLACE_REMAINDER : NB_REMAINDER;
3145
38.8k
            break;
3146
63.7k
        case Pow:
3147
63.7k
            oparg = inplace ? NB_INPLACE_POWER : NB_POWER;
3148
63.7k
            break;
3149
8.01k
        case LShift:
3150
8.01k
            oparg = inplace ? NB_INPLACE_LSHIFT : NB_LSHIFT;
3151
8.01k
            break;
3152
12.9k
        case RShift:
3153
12.9k
            oparg = inplace ? NB_INPLACE_RSHIFT : NB_RSHIFT;
3154
12.9k
            break;
3155
8.39k
        case BitOr:
3156
8.39k
            oparg = inplace ? NB_INPLACE_OR : NB_OR;
3157
8.39k
            break;
3158
11.7k
        case BitXor:
3159
11.7k
            oparg = inplace ? NB_INPLACE_XOR : NB_XOR;
3160
11.7k
            break;
3161
14.3k
        case BitAnd:
3162
14.3k
            oparg = inplace ? NB_INPLACE_AND : NB_AND;
3163
14.3k
            break;
3164
20.3k
        case FloorDiv:
3165
20.3k
            oparg = inplace ? NB_INPLACE_FLOOR_DIVIDE : NB_FLOOR_DIVIDE;
3166
20.3k
            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
538k
    }
3172
538k
    ADDOP_I(c, loc, BINARY_OP, oparg);
3173
538k
    return SUCCESS;
3174
538k
}
3175
3176
3177
static int
3178
1.80k
codegen_addop_yield(compiler *c, location loc) {
3179
1.80k
    PySTEntryObject *ste = SYMTABLE_ENTRY(c);
3180
1.80k
    if (ste->ste_generator && ste->ste_coroutine) {
3181
328
        ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_ASYNC_GEN_WRAP);
3182
328
    }
3183
1.80k
    ADDOP_I(c, loc, YIELD_VALUE, 0);
3184
1.80k
    ADDOP_I(c, loc, RESUME, RESUME_AFTER_YIELD);
3185
1.80k
    return SUCCESS;
3186
1.80k
}
3187
3188
static int
3189
codegen_load_classdict_freevar(compiler *c, location loc)
3190
4.54k
{
3191
4.54k
    ADDOP_N(c, loc, LOAD_DEREF, &_Py_ID(__classdict__), freevars);
3192
4.54k
    return SUCCESS;
3193
4.54k
}
3194
3195
static int
3196
codegen_nameop(compiler *c, location loc,
3197
               identifier name, expr_context_ty ctx)
3198
431k
{
3199
431k
    assert(!_PyUnicode_EqualToASCIIString(name, "None") &&
3200
431k
           !_PyUnicode_EqualToASCIIString(name, "True") &&
3201
431k
           !_PyUnicode_EqualToASCIIString(name, "False"));
3202
3203
431k
    PyObject *mangled = _PyCompile_MaybeMangle(c, name);
3204
431k
    if (!mangled) {
3205
0
        return ERROR;
3206
0
    }
3207
3208
431k
    int scope = _PyST_GetScope(SYMTABLE_ENTRY(c), mangled);
3209
431k
    RETURN_IF_ERROR(scope);
3210
431k
    _PyCompile_optype optype;
3211
431k
    Py_ssize_t arg = 0;
3212
431k
    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
431k
    assert(scope || PyUnicode_READ_CHAR(name, 0) == '_');
3219
3220
431k
    int op = 0;
3221
431k
    switch (optype) {
3222
10.3k
    case COMPILE_OP_DEREF:
3223
10.3k
        switch (ctx) {
3224
7.20k
        case Load:
3225
7.20k
            if (SYMTABLE_ENTRY(c)->ste_type == ClassBlock && !_PyCompile_IsInInlinedComp(c)) {
3226
3.12k
                op = LOAD_FROM_DICT_OR_DEREF;
3227
                // First load the locals
3228
3.12k
                if (codegen_addop_noarg(INSTR_SEQUENCE(c), LOAD_LOCALS, loc) < 0) {
3229
0
                    goto error;
3230
0
                }
3231
3.12k
            }
3232
4.08k
            else if (SYMTABLE_ENTRY(c)->ste_can_see_class_scope) {
3233
1.05k
                op = LOAD_FROM_DICT_OR_DEREF;
3234
                // First load the classdict
3235
1.05k
                if (codegen_load_classdict_freevar(c, loc) < 0) {
3236
0
                    goto error;
3237
0
                }
3238
1.05k
            }
3239
3.03k
            else {
3240
3.03k
                op = LOAD_DEREF;
3241
3.03k
            }
3242
7.20k
            break;
3243
7.20k
        case Store: op = STORE_DEREF; break;
3244
67
        case Del: op = DELETE_DEREF; break;
3245
10.3k
        }
3246
10.3k
        break;
3247
96.7k
    case COMPILE_OP_FAST:
3248
96.7k
        switch (ctx) {
3249
12.3k
        case Load: op = LOAD_FAST; break;
3250
80.8k
        case Store: op = STORE_FAST; break;
3251
3.53k
        case Del: op = DELETE_FAST; break;
3252
96.7k
        }
3253
96.7k
        ADDOP_N(c, loc, op, mangled, varnames);
3254
96.7k
        return SUCCESS;
3255
83.7k
    case COMPILE_OP_GLOBAL:
3256
83.7k
        switch (ctx) {
3257
83.1k
        case Load:
3258
83.1k
            if (SYMTABLE_ENTRY(c)->ste_can_see_class_scope && scope == GLOBAL_IMPLICIT) {
3259
3.49k
                op = LOAD_FROM_DICT_OR_GLOBALS;
3260
                // First load the classdict
3261
3.49k
                if (codegen_load_classdict_freevar(c, loc) < 0) {
3262
0
                    goto error;
3263
0
                }
3264
79.6k
            } else {
3265
79.6k
                op = LOAD_GLOBAL;
3266
79.6k
            }
3267
83.1k
            break;
3268
83.1k
        case Store: op = STORE_GLOBAL; break;
3269
108
        case Del: op = DELETE_GLOBAL; break;
3270
83.7k
        }
3271
83.7k
        break;
3272
240k
    case COMPILE_OP_NAME:
3273
240k
        switch (ctx) {
3274
170k
        case Load:
3275
170k
            op = (SYMTABLE_ENTRY(c)->ste_type == ClassBlock
3276
26.3k
                    && _PyCompile_IsInInlinedComp(c))
3277
170k
                ? LOAD_GLOBAL
3278
170k
                : LOAD_NAME;
3279
170k
            break;
3280
68.2k
        case Store: op = STORE_NAME; break;
3281
2.15k
        case Del: op = DELETE_NAME; break;
3282
240k
        }
3283
240k
        break;
3284
431k
    }
3285
3286
431k
    assert(op);
3287
334k
    Py_DECREF(mangled);
3288
334k
    if (op == LOAD_GLOBAL) {
3289
82.5k
        arg <<= 1;
3290
82.5k
    }
3291
334k
    ADDOP_I(c, loc, op, arg);
3292
334k
    return SUCCESS;
3293
3294
0
error:
3295
0
    Py_DECREF(mangled);
3296
0
    return ERROR;
3297
334k
}
3298
3299
static int
3300
codegen_boolop(compiler *c, expr_ty e)
3301
1.76k
{
3302
1.76k
    int jumpi;
3303
1.76k
    Py_ssize_t i, n;
3304
1.76k
    asdl_expr_seq *s;
3305
3306
1.76k
    location loc = LOC(e);
3307
1.76k
    assert(e->kind == BoolOp_kind);
3308
1.76k
    if (e->v.BoolOp.op == And)
3309
946
        jumpi = JUMP_IF_FALSE;
3310
819
    else
3311
819
        jumpi = JUMP_IF_TRUE;
3312
1.76k
    NEW_JUMP_TARGET_LABEL(c, end);
3313
1.76k
    s = e->v.BoolOp.values;
3314
1.76k
    n = asdl_seq_LEN(s) - 1;
3315
1.76k
    assert(n >= 0);
3316
6.37k
    for (i = 0; i < n; ++i) {
3317
4.60k
        VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i));
3318
4.60k
        ADDOP_JUMP(c, loc, jumpi, end);
3319
4.60k
        ADDOP(c, loc, POP_TOP);
3320
4.60k
    }
3321
1.76k
    VISIT(c, expr, (expr_ty)asdl_seq_GET(s, n));
3322
3323
1.76k
    USE_LABEL(c, end);
3324
1.76k
    return SUCCESS;
3325
1.76k
}
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
73.8k
{
3332
73.8k
    Py_ssize_t n = asdl_seq_LEN(elts);
3333
73.8k
    int big = n + pushed + (injected_arg ? 1 : 0) > _PY_STACK_USE_GUIDELINE;
3334
73.8k
    int seen_star = 0;
3335
262k
    for (Py_ssize_t i = 0; i < n; i++) {
3336
193k
        expr_ty elt = asdl_seq_GET(elts, i);
3337
193k
        if (elt->kind == Starred_kind) {
3338
4.96k
            seen_star = 1;
3339
4.96k
            break;
3340
4.96k
        }
3341
193k
    }
3342
73.8k
    if (!seen_star && !big) {
3343
216k
        for (Py_ssize_t i = 0; i < n; i++) {
3344
148k
            expr_ty elt = asdl_seq_GET(elts, i);
3345
148k
            VISIT(c, expr, elt);
3346
148k
        }
3347
68.3k
        if (injected_arg) {
3348
0
            RETURN_IF_ERROR(codegen_nameop(c, loc, injected_arg, Load));
3349
0
            n++;
3350
0
        }
3351
68.3k
        if (tuple) {
3352
59.3k
            ADDOP_I(c, loc, BUILD_TUPLE, n+pushed);
3353
59.3k
        } else {
3354
8.99k
            ADDOP_I(c, loc, build, n+pushed);
3355
8.99k
        }
3356
68.3k
        return SUCCESS;
3357
68.3k
    }
3358
5.44k
    int sequence_built = 0;
3359
5.44k
    if (big) {
3360
525
        ADDOP_I(c, loc, build, pushed);
3361
525
        sequence_built = 1;
3362
525
    }
3363
62.6k
    for (Py_ssize_t i = 0; i < n; i++) {
3364
57.1k
        expr_ty elt = asdl_seq_GET(elts, i);
3365
57.1k
        if (elt->kind == Starred_kind) {
3366
6.16k
            if (sequence_built == 0) {
3367
4.92k
                ADDOP_I(c, loc, build, i+pushed);
3368
4.92k
                sequence_built = 1;
3369
4.92k
            }
3370
6.16k
            VISIT(c, expr, elt->v.Starred.value);
3371
6.15k
            ADDOP_I(c, loc, extend, 1);
3372
6.15k
        }
3373
51.0k
        else {
3374
51.0k
            VISIT(c, expr, elt);
3375
51.0k
            if (sequence_built) {
3376
45.2k
                ADDOP_I(c, loc, add, 1);
3377
45.2k
            }
3378
51.0k
        }
3379
57.1k
    }
3380
5.44k
    assert(sequence_built);
3381
5.43k
    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.43k
    if (tuple) {
3386
4.93k
        ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_LIST_TO_TUPLE);
3387
4.93k
    }
3388
5.43k
    return SUCCESS;
3389
5.43k
}
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
71.0k
{
3396
71.0k
    return starunpack_helper_impl(c, loc, elts, NULL, pushed,
3397
71.0k
                                  build, add, extend, tuple);
3398
71.0k
}
3399
3400
static int
3401
unpack_helper(compiler *c, location loc, asdl_expr_seq *elts)
3402
20.6k
{
3403
20.6k
    Py_ssize_t n = asdl_seq_LEN(elts);
3404
20.6k
    int seen_star = 0;
3405
72.9k
    for (Py_ssize_t i = 0; i < n; i++) {
3406
52.3k
        expr_ty elt = asdl_seq_GET(elts, i);
3407
52.3k
        if (elt->kind == Starred_kind && !seen_star) {
3408
498
            if ((i >= (1 << 8)) ||
3409
498
                (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
498
            ADDOP_I(c, loc, UNPACK_EX, (i + ((n-i-1) << 8)));
3415
498
            seen_star = 1;
3416
498
        }
3417
51.8k
        else if (elt->kind == Starred_kind) {
3418
8
            return _PyCompile_Error(c, loc,
3419
8
                "multiple starred expressions in assignment");
3420
8
        }
3421
52.3k
    }
3422
20.5k
    if (!seen_star) {
3423
20.1k
        ADDOP_I(c, loc, UNPACK_SEQUENCE, n);
3424
20.1k
    }
3425
20.5k
    return SUCCESS;
3426
20.5k
}
3427
3428
static int
3429
assignment_helper(compiler *c, location loc, asdl_expr_seq *elts)
3430
20.6k
{
3431
20.6k
    Py_ssize_t n = asdl_seq_LEN(elts);
3432
20.6k
    RETURN_IF_ERROR(unpack_helper(c, loc, elts));
3433
72.6k
    for (Py_ssize_t i = 0; i < n; i++) {
3434
52.0k
        expr_ty elt = asdl_seq_GET(elts, i);
3435
52.0k
        VISIT(c, expr, elt->kind != Starred_kind ? elt : elt->v.Starred.value);
3436
52.0k
    }
3437
20.5k
    return SUCCESS;
3438
20.5k
}
3439
3440
static int
3441
codegen_list(compiler *c, expr_ty e)
3442
4.37k
{
3443
4.37k
    location loc = LOC(e);
3444
4.37k
    asdl_expr_seq *elts = e->v.List.elts;
3445
4.37k
    if (e->v.List.ctx == Store) {
3446
335
        return assignment_helper(c, loc, elts);
3447
335
    }
3448
4.04k
    else if (e->v.List.ctx == Load) {
3449
3.52k
        return starunpack_helper(c, loc, elts, 0,
3450
3.52k
                                 BUILD_LIST, LIST_APPEND, LIST_EXTEND, 0);
3451
3.52k
    }
3452
519
    else {
3453
519
        VISIT_SEQ(c, expr, elts);
3454
519
    }
3455
519
    return SUCCESS;
3456
4.37k
}
3457
3458
static int
3459
codegen_tuple(compiler *c, expr_ty e)
3460
82.1k
{
3461
82.1k
    location loc = LOC(e);
3462
82.1k
    asdl_expr_seq *elts = e->v.Tuple.elts;
3463
82.1k
    if (e->v.Tuple.ctx == Store) {
3464
20.2k
        return assignment_helper(c, loc, elts);
3465
20.2k
    }
3466
61.8k
    else if (e->v.Tuple.ctx == Load) {
3467
61.5k
        return starunpack_helper(c, loc, elts, 0,
3468
61.5k
                                 BUILD_LIST, LIST_APPEND, LIST_EXTEND, 1);
3469
61.5k
    }
3470
344
    else {
3471
344
        VISIT_SEQ(c, expr, elts);
3472
344
    }
3473
344
    return SUCCESS;
3474
82.1k
}
3475
3476
static int
3477
codegen_set(compiler *c, expr_ty e)
3478
5.98k
{
3479
5.98k
    location loc = LOC(e);
3480
5.98k
    return starunpack_helper(c, loc, e->v.Set.elts, 0,
3481
5.98k
                             BUILD_SET, SET_ADD, SET_UPDATE, 0);
3482
5.98k
}
3483
3484
static int
3485
codegen_subdict(compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end)
3486
458
{
3487
458
    Py_ssize_t i, n = end - begin;
3488
458
    int big = n*2 > _PY_STACK_USE_GUIDELINE;
3489
458
    location loc = LOC(e);
3490
458
    if (big) {
3491
56
        ADDOP_I(c, loc, BUILD_MAP, 0);
3492
56
    }
3493
1.90k
    for (i = begin; i < end; i++) {
3494
1.44k
        VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i));
3495
1.44k
        VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
3496
1.44k
        if (big) {
3497
951
            ADDOP_I(c, loc, MAP_ADD, 1);
3498
951
        }
3499
1.44k
    }
3500
458
    if (!big) {
3501
402
        ADDOP_I(c, loc, BUILD_MAP, n);
3502
402
    }
3503
458
    return SUCCESS;
3504
458
}
3505
3506
static int
3507
codegen_dict(compiler *c, expr_ty e)
3508
696
{
3509
696
    location loc = LOC(e);
3510
696
    Py_ssize_t i, n, elements;
3511
696
    int have_dict;
3512
696
    int is_unpacking = 0;
3513
696
    n = asdl_seq_LEN(e->v.Dict.values);
3514
696
    have_dict = 0;
3515
696
    elements = 0;
3516
2.94k
    for (i = 0; i < n; i++) {
3517
2.25k
        is_unpacking = (expr_ty)asdl_seq_GET(e->v.Dict.keys, i) == NULL;
3518
2.25k
        if (is_unpacking) {
3519
811
            if (elements) {
3520
348
                RETURN_IF_ERROR(codegen_subdict(c, e, i - elements, i));
3521
348
                if (have_dict) {
3522
303
                    ADDOP_I(c, loc, DICT_UPDATE, 1);
3523
303
                }
3524
348
                have_dict = 1;
3525
348
                elements = 0;
3526
348
            }
3527
811
            if (have_dict == 0) {
3528
66
                ADDOP_I(c, loc, BUILD_MAP, 0);
3529
66
                have_dict = 1;
3530
66
            }
3531
811
            VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
3532
811
            ADDOP_I(c, loc, DICT_UPDATE, 1);
3533
811
        }
3534
1.44k
        else {
3535
1.44k
            if (elements*2 > _PY_STACK_USE_GUIDELINE) {
3536
55
                RETURN_IF_ERROR(codegen_subdict(c, e, i - elements, i + 1));
3537
55
                if (have_dict) {
3538
49
                    ADDOP_I(c, loc, DICT_UPDATE, 1);
3539
49
                }
3540
55
                have_dict = 1;
3541
55
                elements = 0;
3542
55
            }
3543
1.38k
            else {
3544
1.38k
                elements++;
3545
1.38k
            }
3546
1.44k
        }
3547
2.25k
    }
3548
696
    if (elements) {
3549
55
        RETURN_IF_ERROR(codegen_subdict(c, e, n - elements, n));
3550
55
        if (have_dict) {
3551
4
            ADDOP_I(c, loc, DICT_UPDATE, 1);
3552
4
        }
3553
55
        have_dict = 1;
3554
55
    }
3555
696
    if (!have_dict) {
3556
528
        ADDOP_I(c, loc, BUILD_MAP, 0);
3557
528
    }
3558
696
    return SUCCESS;
3559
696
}
3560
3561
static int
3562
codegen_compare(compiler *c, expr_ty e)
3563
15.2k
{
3564
15.2k
    location loc = LOC(e);
3565
15.2k
    Py_ssize_t i, n;
3566
3567
15.2k
    RETURN_IF_ERROR(codegen_check_compare(c, e));
3568
15.2k
    VISIT(c, expr, e->v.Compare.left);
3569
15.2k
    assert(asdl_seq_LEN(e->v.Compare.ops) > 0);
3570
15.1k
    n = asdl_seq_LEN(e->v.Compare.ops) - 1;
3571
15.1k
    if (n == 0) {
3572
9.87k
        VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, 0));
3573
9.86k
        ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, 0));
3574
9.86k
    }
3575
5.27k
    else {
3576
5.27k
        NEW_JUMP_TARGET_LABEL(c, cleanup);
3577
32.5k
        for (i = 0; i < n; i++) {
3578
27.2k
            VISIT(c, expr,
3579
27.2k
                (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
3580
27.2k
            ADDOP_I(c, loc, SWAP, 2);
3581
27.2k
            ADDOP_I(c, loc, COPY, 2);
3582
27.2k
            ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, i));
3583
27.2k
            ADDOP_I(c, loc, COPY, 1);
3584
27.2k
            ADDOP(c, loc, TO_BOOL);
3585
27.2k
            ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, cleanup);
3586
27.2k
            ADDOP(c, loc, POP_TOP);
3587
27.2k
        }
3588
5.22k
        VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
3589
5.22k
        ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, n));
3590
5.22k
        NEW_JUMP_TARGET_LABEL(c, end);
3591
5.22k
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
3592
3593
5.22k
        USE_LABEL(c, cleanup);
3594
5.22k
        ADDOP_I(c, loc, SWAP, 2);
3595
5.22k
        ADDOP(c, loc, POP_TOP);
3596
3597
5.22k
        USE_LABEL(c, end);
3598
5.22k
    }
3599
15.0k
    return SUCCESS;
3600
15.1k
}
3601
3602
static PyTypeObject *
3603
infer_type(expr_ty e)
3604
34.9k
{
3605
34.9k
    switch (e->kind) {
3606
7.31k
    case Tuple_kind:
3607
7.31k
        return &PyTuple_Type;
3608
1.33k
    case List_kind:
3609
1.35k
    case ListComp_kind:
3610
1.35k
        return &PyList_Type;
3611
383
    case Dict_kind:
3612
837
    case DictComp_kind:
3613
837
        return &PyDict_Type;
3614
88
    case Set_kind:
3615
608
    case SetComp_kind:
3616
608
        return &PySet_Type;
3617
469
    case GeneratorExp_kind:
3618
469
        return &PyGen_Type;
3619
207
    case Lambda_kind:
3620
207
        return &PyFunction_Type;
3621
64
    case TemplateStr_kind:
3622
64
    case Interpolation_kind:
3623
64
        return &_PyTemplate_Type;
3624
484
    case JoinedStr_kind:
3625
484
    case FormattedValue_kind:
3626
484
        return &PyUnicode_Type;
3627
9.01k
    case Constant_kind:
3628
9.01k
        return Py_TYPE(e->v.Constant.value);
3629
14.5k
    default:
3630
14.5k
        return NULL;
3631
34.9k
    }
3632
34.9k
}
3633
3634
static int
3635
check_caller(compiler *c, expr_ty e)
3636
9.36k
{
3637
9.36k
    switch (e->kind) {
3638
1.56k
    case Constant_kind:
3639
1.79k
    case Tuple_kind:
3640
1.96k
    case List_kind:
3641
1.97k
    case ListComp_kind:
3642
2.27k
    case Dict_kind:
3643
2.72k
    case DictComp_kind:
3644
2.75k
    case Set_kind:
3645
3.16k
    case SetComp_kind:
3646
3.63k
    case GeneratorExp_kind:
3647
3.78k
    case JoinedStr_kind:
3648
3.79k
    case TemplateStr_kind:
3649
3.79k
    case FormattedValue_kind:
3650
3.79k
    case Interpolation_kind: {
3651
3.79k
        location loc = LOC(e);
3652
3.79k
        return _PyCompile_Warn(c, loc, "'%.200s' object is not callable; "
3653
3.79k
                                       "perhaps you missed a comma?",
3654
3.79k
                                       infer_type(e)->tp_name);
3655
3.79k
    }
3656
5.57k
    default:
3657
5.57k
        return SUCCESS;
3658
9.36k
    }
3659
9.36k
}
3660
3661
static int
3662
check_subscripter(compiler *c, expr_ty e)
3663
23.2k
{
3664
23.2k
    PyObject *v;
3665
3666
23.2k
    switch (e->kind) {
3667
10.2k
    case Constant_kind:
3668
10.2k
        v = e->v.Constant.value;
3669
10.2k
        if (!(v == Py_None || v == Py_Ellipsis ||
3670
10.2k
              PyLong_Check(v) || PyFloat_Check(v) || PyComplex_Check(v) ||
3671
8.67k
              PyAnySet_Check(v)))
3672
8.67k
        {
3673
8.67k
            return SUCCESS;
3674
8.67k
        }
3675
1.55k
        _Py_FALLTHROUGH;
3676
1.56k
    case Set_kind:
3677
1.56k
    case SetComp_kind:
3678
1.56k
    case GeneratorExp_kind:
3679
1.61k
    case TemplateStr_kind:
3680
1.61k
    case Interpolation_kind:
3681
1.61k
    case Lambda_kind: {
3682
1.61k
        location loc = LOC(e);
3683
1.61k
        return _PyCompile_Warn(c, loc, "'%.200s' object is not subscriptable; "
3684
1.61k
                                       "perhaps you missed a comma?",
3685
1.61k
                                       infer_type(e)->tp_name);
3686
1.61k
    }
3687
12.9k
    default:
3688
12.9k
        return SUCCESS;
3689
23.2k
    }
3690
23.2k
}
3691
3692
static int
3693
check_index(compiler *c, expr_ty e, expr_ty s)
3694
23.2k
{
3695
23.2k
    PyObject *v;
3696
3697
23.2k
    PyTypeObject *index_type = infer_type(s);
3698
23.2k
    if (index_type == NULL
3699
8.70k
        || PyType_FastSubclass(index_type, Py_TPFLAGS_LONG_SUBCLASS)
3700
16.6k
        || index_type == &PySlice_Type) {
3701
16.6k
        return SUCCESS;
3702
16.6k
    }
3703
3704
6.58k
    switch (e->kind) {
3705
2.29k
    case Constant_kind:
3706
2.29k
        v = e->v.Constant.value;
3707
2.29k
        if (!(PyUnicode_Check(v) || PyBytes_Check(v) || PyTuple_Check(v))) {
3708
581
            return SUCCESS;
3709
581
        }
3710
1.70k
        _Py_FALLTHROUGH;
3711
2.97k
    case Tuple_kind:
3712
4.09k
    case List_kind:
3713
4.10k
    case ListComp_kind:
3714
4.16k
    case JoinedStr_kind:
3715
4.16k
    case FormattedValue_kind: {
3716
4.16k
        location loc = LOC(e);
3717
4.16k
        return _PyCompile_Warn(c, loc, "%.200s indices must be integers "
3718
4.16k
                                       "or slices, not %.200s; "
3719
4.16k
                                       "perhaps you missed a comma?",
3720
4.16k
                                       infer_type(e)->tp_name,
3721
4.16k
                                       index_type->tp_name);
3722
4.16k
    }
3723
1.83k
    default:
3724
1.83k
        return SUCCESS;
3725
6.58k
    }
3726
6.58k
}
3727
3728
static int
3729
is_import_originated(compiler *c, expr_ty e)
3730
1.43k
{
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.43k
    if (e->kind != Name_kind) {
3738
844
        return 0;
3739
844
    }
3740
3741
591
    long flags = _PyST_GetSymbol(SYMTABLE(c)->st_top, e->v.Name.id);
3742
591
    RETURN_IF_ERROR(flags);
3743
591
    return flags & DEF_IMPORT;
3744
591
}
3745
3746
static int
3747
can_optimize_super_call(compiler *c, expr_ty attr)
3748
15.1k
{
3749
15.1k
    expr_ty e = attr->v.Attribute.value;
3750
15.1k
    if (e->kind != Call_kind ||
3751
4.02k
        e->v.Call.func->kind != Name_kind ||
3752
2.20k
        !_PyUnicode_EqualToASCIIString(e->v.Call.func->v.Name.id, "super") ||
3753
1.69k
        _PyUnicode_EqualToASCIIString(attr->v.Attribute.attr, "__class__") ||
3754
13.5k
        asdl_seq_LEN(e->v.Call.keywords) != 0) {
3755
13.5k
        return 0;
3756
13.5k
    }
3757
1.61k
    Py_ssize_t num_args = asdl_seq_LEN(e->v.Call.args);
3758
3759
1.61k
    PyObject *super_name = e->v.Call.func->v.Name.id;
3760
    // detect statically-visible shadowing of 'super' name
3761
1.61k
    int scope = _PyST_GetScope(SYMTABLE_ENTRY(c), super_name);
3762
1.61k
    RETURN_IF_ERROR(scope);
3763
1.61k
    if (scope != GLOBAL_IMPLICIT) {
3764
230
        return 0;
3765
230
    }
3766
1.38k
    scope = _PyST_GetScope(SYMTABLE(c)->st_top, super_name);
3767
1.38k
    RETURN_IF_ERROR(scope);
3768
1.38k
    if (scope != 0) {
3769
233
        return 0;
3770
233
    }
3771
3772
1.15k
    if (num_args == 2) {
3773
1.85k
        for (Py_ssize_t i = 0; i < num_args; i++) {
3774
1.40k
            expr_ty elt = asdl_seq_GET(e->v.Call.args, i);
3775
1.40k
            if (elt->kind == Starred_kind) {
3776
388
                return 0;
3777
388
            }
3778
1.40k
        }
3779
        // exactly two non-starred args; we can just load
3780
        // the provided args
3781
444
        return 1;
3782
832
    }
3783
3784
318
    if (num_args != 0) {
3785
203
        return 0;
3786
203
    }
3787
    // we need the following for zero-arg super():
3788
3789
    // enclosing function should have at least one argument
3790
115
    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
69
    if (_PyCompile_GetRefType(c, &_Py_ID(__class__)) == FREE) {
3796
0
        return 1;
3797
0
    }
3798
69
    return 0;
3799
69
}
3800
3801
static int
3802
444
load_args_for_super(compiler *c, expr_ty e) {
3803
444
    location loc = LOC(e);
3804
3805
    // load super() global
3806
444
    PyObject *super_name = e->v.Call.func->v.Name.id;
3807
444
    RETURN_IF_ERROR(codegen_nameop(c, LOC(e->v.Call.func), super_name, Load));
3808
3809
444
    if (asdl_seq_LEN(e->v.Call.args) == 2) {
3810
444
        VISIT(c, expr, asdl_seq_GET(e->v.Call.args, 0));
3811
444
        VISIT(c, expr, asdl_seq_GET(e->v.Call.args, 1));
3812
444
        return SUCCESS;
3813
444
    }
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.6k
{
3837
19.6k
    assert(attr->kind == Attribute_kind);
3838
19.6k
    if (loc.lineno != attr->end_lineno) {
3839
1.76k
        loc.lineno = attr->end_lineno;
3840
1.76k
        int len = (int)PyUnicode_GET_LENGTH(attr->v.Attribute.attr);
3841
1.76k
        if (len <= attr->end_col_offset) {
3842
1.76k
            loc.col_offset = attr->end_col_offset - len;
3843
1.76k
        }
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
1.76k
        loc.end_lineno = Py_MAX(loc.lineno, loc.end_lineno);
3852
1.76k
        if (loc.lineno == loc.end_lineno) {
3853
1.42k
            loc.end_col_offset = Py_MAX(loc.col_offset, loc.end_col_offset);
3854
1.42k
        }
3855
1.76k
    }
3856
19.6k
    return loc;
3857
19.6k
}
3858
3859
static int
3860
maybe_optimize_function_call(compiler *c, expr_ty e, jump_target_label end)
3861
9.28k
{
3862
9.28k
    asdl_expr_seq *args = e->v.Call.args;
3863
9.28k
    asdl_keyword_seq *kwds = e->v.Call.keywords;
3864
9.28k
    expr_ty func = e->v.Call.func;
3865
3866
9.28k
    if (! (func->kind == Name_kind &&
3867
3.45k
           asdl_seq_LEN(args) == 1 &&
3868
1.33k
           asdl_seq_LEN(kwds) == 0 &&
3869
984
           asdl_seq_GET(args, 0)->kind == GeneratorExp_kind))
3870
9.22k
    {
3871
9.22k
        return 0;
3872
9.22k
    }
3873
3874
60
    location loc = LOC(func);
3875
3876
60
    int optimized = 0;
3877
60
    NEW_JUMP_TARGET_LABEL(c, skip_optimization);
3878
3879
60
    int const_oparg = -1;
3880
60
    PyObject *initial_res = NULL;
3881
60
    int continue_jump_opcode = -1;
3882
60
    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
60
    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
60
    else if (_PyUnicode_EqualToASCIIString(func->v.Name.id, "tuple")) {
3893
0
        const_oparg = CONSTANT_BUILTIN_TUPLE;
3894
0
    }
3895
60
    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
60
    USE_LABEL(c, skip_optimization);
3943
60
    return optimized;
3944
60
}
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.3k
{
3950
10.3k
    Py_ssize_t argsl, i, kwdsl;
3951
10.3k
    expr_ty meth = e->v.Call.func;
3952
10.3k
    asdl_expr_seq *args = e->v.Call.args;
3953
10.3k
    asdl_keyword_seq *kwds = e->v.Call.keywords;
3954
3955
    /* Check that the call node is an attribute access */
3956
10.3k
    if (meth->kind != Attribute_kind || meth->v.Attribute.ctx != Load) {
3957
8.87k
        return 0;
3958
8.87k
    }
3959
3960
    /* Check that the base object is not something that is imported */
3961
1.43k
    int ret = is_import_originated(c, meth->v.Attribute.value);
3962
1.43k
    RETURN_IF_ERROR(ret);
3963
1.43k
    if (ret) {
3964
0
        return 0;
3965
0
    }
3966
3967
    /* Check that there aren't too many arguments */
3968
1.43k
    argsl = asdl_seq_LEN(args);
3969
1.43k
    kwdsl = asdl_seq_LEN(kwds);
3970
1.43k
    if (argsl + kwdsl + (kwdsl != 0) >= _PY_STACK_USE_GUIDELINE) {
3971
202
        return 0;
3972
202
    }
3973
    /* Check that there are no *varargs types of arguments. */
3974
3.06k
    for (i = 0; i < argsl; i++) {
3975
1.88k
        expr_ty elt = asdl_seq_GET(args, i);
3976
1.88k
        if (elt->kind == Starred_kind) {
3977
56
            return 0;
3978
56
        }
3979
1.88k
    }
3980
3981
1.85k
    for (i = 0; i < kwdsl; i++) {
3982
915
        keyword_ty kw = asdl_seq_GET(kwds, i);
3983
915
        if (kw->arg == NULL) {
3984
238
            return 0;
3985
238
        }
3986
915
    }
3987
3988
    /* Alright, we can optimize the code. */
3989
939
    location loc = LOC(meth);
3990
3991
939
    ret = can_optimize_super_call(c, meth);
3992
939
    RETURN_IF_ERROR(ret);
3993
939
    if (ret) {
3994
1
        RETURN_IF_ERROR(load_args_for_super(c, meth->v.Attribute.value));
3995
1
        int opcode = asdl_seq_LEN(meth->v.Attribute.value->v.Call.args) ?
3996
1
            LOAD_SUPER_METHOD : LOAD_ZERO_SUPER_METHOD;
3997
1
        ADDOP_NAME(c, loc, opcode, meth->v.Attribute.attr, names);
3998
1
        loc = update_start_location_to_match_attr(c, loc, meth);
3999
1
        ADDOP(c, loc, NOP);
4000
938
    } else {
4001
938
        VISIT(c, expr, meth->v.Attribute.value);
4002
926
        loc = update_start_location_to_match_attr(c, loc, meth);
4003
926
        ADDOP_NAME(c, loc, LOAD_METHOD, meth->v.Attribute.attr, names);
4004
926
    }
4005
4006
927
    VISIT_SEQ(c, expr, e->v.Call.args);
4007
4008
902
    if (kwdsl) {
4009
364
        VISIT_SEQ(c, keyword, kwds);
4010
361
        RETURN_IF_ERROR(
4011
361
            codegen_call_simple_kw_helper(c, loc, kwds, kwdsl));
4012
361
        loc = update_start_location_to_match_attr(c, LOC(e), meth);
4013
361
        ADDOP_I(c, loc, CALL_KW, argsl + kwdsl);
4014
361
    }
4015
538
    else {
4016
538
        loc = update_start_location_to_match_attr(c, LOC(e), meth);
4017
538
        ADDOP_I(c, loc, CALL, argsl);
4018
538
    }
4019
899
    return 1;
4020
902
}
4021
4022
static int
4023
codegen_validate_keywords(compiler *c, asdl_keyword_seq *keywords)
4024
26.8k
{
4025
26.8k
    Py_ssize_t nkeywords = asdl_seq_LEN(keywords);
4026
34.2k
    for (Py_ssize_t i = 0; i < nkeywords; i++) {
4027
7.41k
        keyword_ty key = ((keyword_ty)asdl_seq_GET(keywords, i));
4028
7.41k
        if (key->arg == NULL) {
4029
3.38k
            continue;
4030
3.38k
        }
4031
9.23k
        for (Py_ssize_t j = i + 1; j < nkeywords; j++) {
4032
5.24k
            keyword_ty other = ((keyword_ty)asdl_seq_GET(keywords, j));
4033
5.24k
            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.24k
        }
4037
4.03k
    }
4038
26.8k
    return SUCCESS;
4039
26.8k
}
4040
4041
static int
4042
codegen_call(compiler *c, expr_ty e)
4043
10.3k
{
4044
10.3k
    RETURN_IF_ERROR(codegen_validate_keywords(c, e->v.Call.keywords));
4045
10.3k
    int ret = maybe_optimize_method_call(c, e);
4046
10.3k
    if (ret < 0) {
4047
40
        return ERROR;
4048
40
    }
4049
10.2k
    if (ret == 1) {
4050
899
        return SUCCESS;
4051
899
    }
4052
9.36k
    NEW_JUMP_TARGET_LABEL(c, skip_normal_call);
4053
9.36k
    RETURN_IF_ERROR(check_caller(c, e->v.Call.func));
4054
9.36k
    VISIT(c, expr, e->v.Call.func);
4055
9.28k
    RETURN_IF_ERROR(maybe_optimize_function_call(c, e, skip_normal_call));
4056
9.28k
    location loc = LOC(e->v.Call.func);
4057
9.28k
    ADDOP(c, loc, PUSH_NULL);
4058
9.28k
    loc = LOC(e);
4059
9.28k
    ret = codegen_call_helper(c, loc, 0,
4060
9.28k
                              e->v.Call.args,
4061
9.28k
                              e->v.Call.keywords);
4062
9.28k
    USE_LABEL(c, skip_normal_call);
4063
9.28k
    return ret;
4064
9.28k
}
4065
4066
static int
4067
codegen_template_str(compiler *c, expr_ty e)
4068
837
{
4069
837
    location loc = LOC(e);
4070
837
    expr_ty value;
4071
4072
837
    Py_ssize_t value_count = asdl_seq_LEN(e->v.TemplateStr.values);
4073
837
    int last_was_interpolation = 1;
4074
837
    Py_ssize_t stringslen = 0;
4075
4.50k
    for (Py_ssize_t i = 0; i < value_count; i++) {
4076
3.66k
        value = asdl_seq_GET(e->v.TemplateStr.values, i);
4077
3.66k
        if (value->kind == Interpolation_kind) {
4078
1.96k
            if (last_was_interpolation) {
4079
479
                ADDOP_LOAD_CONST(c, loc, Py_NewRef(&_Py_STR(empty)));
4080
479
                stringslen++;
4081
479
            }
4082
1.96k
            last_was_interpolation = 1;
4083
1.96k
        }
4084
1.69k
        else {
4085
1.69k
            VISIT(c, expr, value);
4086
1.69k
            stringslen++;
4087
1.69k
            last_was_interpolation = 0;
4088
1.69k
        }
4089
3.66k
    }
4090
837
    if (last_was_interpolation) {
4091
627
        ADDOP_LOAD_CONST(c, loc, Py_NewRef(&_Py_STR(empty)));
4092
627
        stringslen++;
4093
627
    }
4094
837
    ADDOP_I(c, loc, BUILD_TUPLE, stringslen);
4095
4096
837
    Py_ssize_t interpolationslen = 0;
4097
4.48k
    for (Py_ssize_t i = 0; i < value_count; i++) {
4098
3.65k
        value = asdl_seq_GET(e->v.TemplateStr.values, i);
4099
3.65k
        if (value->kind == Interpolation_kind) {
4100
1.96k
            VISIT(c, expr, value);
4101
1.95k
            interpolationslen++;
4102
1.95k
        }
4103
3.65k
    }
4104
831
    ADDOP_I(c, loc, BUILD_TUPLE, interpolationslen);
4105
831
    ADDOP(c, loc, BUILD_TEMPLATE);
4106
831
    return SUCCESS;
4107
831
}
4108
4109
static int
4110
codegen_joined_str(compiler *c, expr_ty e)
4111
4.58k
{
4112
4.58k
    location loc = LOC(e);
4113
4.58k
    Py_ssize_t value_count = asdl_seq_LEN(e->v.JoinedStr.values);
4114
4.58k
    if (value_count > _PY_STACK_USE_GUIDELINE) {
4115
58
        _Py_DECLARE_STR(empty, "");
4116
58
        ADDOP_LOAD_CONST_NEW(c, loc, Py_NewRef(&_Py_STR(empty)));
4117
58
        ADDOP_NAME(c, loc, LOAD_METHOD, &_Py_ID(join), names);
4118
58
        ADDOP_I(c, loc, BUILD_LIST, 0);
4119
4.08k
        for (Py_ssize_t i = 0; i < asdl_seq_LEN(e->v.JoinedStr.values); i++) {
4120
4.03k
            VISIT(c, expr, asdl_seq_GET(e->v.JoinedStr.values, i));
4121
4.02k
            ADDOP_I(c, loc, LIST_APPEND, 1);
4122
4.02k
        }
4123
51
        ADDOP_I(c, loc, CALL, 1);
4124
51
    }
4125
4.52k
    else {
4126
4.52k
        VISIT_SEQ(c, expr, e->v.JoinedStr.values);
4127
4.50k
        if (value_count > 1) {
4128
1.64k
            ADDOP_I(c, loc, BUILD_STRING, value_count);
4129
1.64k
        }
4130
2.86k
        else if (value_count == 0) {
4131
1.31k
            _Py_DECLARE_STR(empty, "");
4132
1.31k
            ADDOP_LOAD_CONST_NEW(c, loc, Py_NewRef(&_Py_STR(empty)));
4133
1.31k
        }
4134
4.50k
    }
4135
4.55k
    return SUCCESS;
4136
4.58k
}
4137
4138
static int
4139
codegen_interpolation(compiler *c, expr_ty e)
4140
1.96k
{
4141
1.96k
    location loc = LOC(e);
4142
4143
1.96k
    VISIT(c, expr, e->v.Interpolation.value);
4144
1.96k
    ADDOP_LOAD_CONST(c, loc, e->v.Interpolation.str);
4145
4146
1.96k
    int oparg = 2;
4147
1.96k
    if (e->v.Interpolation.format_spec) {
4148
368
        oparg++;
4149
368
        VISIT(c, expr, e->v.Interpolation.format_spec);
4150
368
    }
4151
4152
1.95k
    int conversion = e->v.Interpolation.conversion;
4153
1.95k
    if (conversion != -1) {
4154
864
        switch (conversion) {
4155
570
        case 's': oparg |= FVC_STR << 2;   break;
4156
218
        case 'r': oparg |= FVC_REPR << 2;  break;
4157
76
        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
864
        }
4163
864
    }
4164
4165
1.95k
    ADDOP_I(c, loc, BUILD_INTERPOLATION, oparg);
4166
1.95k
    return SUCCESS;
4167
1.95k
}
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.47k
{
4173
4.47k
    int conversion = e->v.FormattedValue.conversion;
4174
4.47k
    int oparg;
4175
4176
    /* The expression to be formatted. */
4177
4.47k
    VISIT(c, expr, e->v.FormattedValue.value);
4178
4179
4.45k
    location loc = LOC(e);
4180
4.45k
    if (conversion != -1) {
4181
2.15k
        switch (conversion) {
4182
900
        case 's': oparg = FVC_STR;   break;
4183
942
        case 'r': oparg = FVC_REPR;  break;
4184
311
        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.15k
        }
4190
2.15k
        ADDOP_I(c, loc, CONVERT_VALUE, oparg);
4191
2.15k
    }
4192
4.45k
    if (e->v.FormattedValue.format_spec) {
4193
        /* Evaluate the format spec, and update our opcode arg. */
4194
806
        VISIT(c, expr, e->v.FormattedValue.format_spec);
4195
800
        ADDOP(c, loc, FORMAT_WITH_SPEC);
4196
3.64k
    } else {
4197
3.64k
        ADDOP(c, loc, FORMAT_SIMPLE);
4198
3.64k
    }
4199
4.44k
    return SUCCESS;
4200
4.45k
}
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
951
{
4207
951
    Py_ssize_t i, n = end - begin;
4208
951
    keyword_ty kw;
4209
951
    assert(n > 0);
4210
951
    int big = n*2 > _PY_STACK_USE_GUIDELINE;
4211
951
    if (big) {
4212
0
        ADDOP_I(c, NO_LOCATION, BUILD_MAP, 0);
4213
0
    }
4214
2.22k
    for (i = begin; i < end; i++) {
4215
1.27k
        kw = asdl_seq_GET(keywords, i);
4216
1.27k
        ADDOP_LOAD_CONST(c, loc, kw->arg);
4217
1.27k
        VISIT(c, expr, kw->value);
4218
1.27k
        if (big) {
4219
0
            ADDOP_I(c, NO_LOCATION, MAP_ADD, 1);
4220
0
        }
4221
1.27k
    }
4222
950
    if (!big) {
4223
950
        ADDOP_I(c, loc, BUILD_MAP, n);
4224
950
    }
4225
950
    return SUCCESS;
4226
950
}
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
619
{
4235
619
    PyObject *names;
4236
619
    names = PyTuple_New(nkwelts);
4237
619
    if (names == NULL) {
4238
0
        return ERROR;
4239
0
    }
4240
1.64k
    for (Py_ssize_t i = 0; i < nkwelts; i++) {
4241
1.02k
        keyword_ty kw = asdl_seq_GET(keywords, i);
4242
1.02k
        PyTuple_SET_ITEM(names, i, Py_NewRef(kw->arg));
4243
1.02k
    }
4244
619
    ADDOP_LOAD_CONST_NEW(c, loc, names);
4245
619
    return SUCCESS;
4246
619
}
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
16.5k
{
4256
16.5k
    Py_ssize_t i, nseen, nelts, nkwelts;
4257
4258
16.5k
    RETURN_IF_ERROR(codegen_validate_keywords(c, keywords));
4259
4260
16.5k
    nelts = asdl_seq_LEN(args);
4261
16.5k
    nkwelts = asdl_seq_LEN(keywords);
4262
4263
16.5k
    if (nelts + nkwelts*2 > _PY_STACK_USE_GUIDELINE) {
4264
201
         goto ex_call;
4265
201
    }
4266
20.2k
    for (i = 0; i < nelts; i++) {
4267
5.57k
        expr_ty elt = asdl_seq_GET(args, i);
4268
5.57k
        if (elt->kind == Starred_kind) {
4269
1.66k
            goto ex_call;
4270
1.66k
        }
4271
5.57k
    }
4272
15.3k
    for (i = 0; i < nkwelts; i++) {
4273
1.78k
        keyword_ty kw = asdl_seq_GET(keywords, i);
4274
1.78k
        if (kw->arg == NULL) {
4275
1.09k
            goto ex_call;
4276
1.09k
        }
4277
1.78k
    }
4278
4279
    /* No * or ** args, so can use faster calling sequence */
4280
16.6k
    for (i = 0; i < nelts; i++) {
4281
3.12k
        expr_ty elt = asdl_seq_GET(args, i);
4282
3.12k
        assert(elt->kind != Starred_kind);
4283
3.12k
        VISIT(c, expr, elt);
4284
3.12k
    }
4285
13.5k
    if (injected_arg) {
4286
2.76k
        RETURN_IF_ERROR(codegen_nameop(c, loc, injected_arg, Load));
4287
2.76k
        nelts++;
4288
2.76k
    }
4289
13.5k
    if (nkwelts) {
4290
261
        VISIT_SEQ(c, keyword, keywords);
4291
258
        RETURN_IF_ERROR(
4292
258
            codegen_call_simple_kw_helper(c, loc, keywords, nkwelts));
4293
258
        ADDOP_I(c, loc, CALL_KW, n + nelts + nkwelts);
4294
258
    }
4295
13.2k
    else {
4296
13.2k
        ADDOP_I(c, loc, CALL, n + nelts);
4297
13.2k
    }
4298
13.5k
    return SUCCESS;
4299
4300
2.95k
ex_call:
4301
4302
    /* Do positional arguments. */
4303
2.95k
    if (n == 0 && nelts == 1 && ((expr_ty)asdl_seq_GET(args, 0))->kind == Starred_kind) {
4304
109
        VISIT(c, expr, ((expr_ty)asdl_seq_GET(args, 0))->v.Starred.value);
4305
109
    }
4306
2.84k
    else {
4307
2.84k
        RETURN_IF_ERROR(starunpack_helper_impl(c, loc, args, injected_arg, n,
4308
2.84k
                                               BUILD_LIST, LIST_APPEND, LIST_EXTEND, 1));
4309
2.84k
    }
4310
    /* Then keyword arguments */
4311
2.93k
    if (nkwelts) {
4312
        /* Has a new dict been pushed */
4313
1.35k
        int have_dict = 0;
4314
4315
1.35k
        nseen = 0;  /* the number of keyword arguments on the stack following */
4316
4.32k
        for (i = 0; i < nkwelts; i++) {
4317
2.97k
            keyword_ty kw = asdl_seq_GET(keywords, i);
4318
2.97k
            if (kw->arg == NULL) {
4319
                /* A keyword argument unpacking. */
4320
1.69k
                if (nseen) {
4321
555
                    RETURN_IF_ERROR(codegen_subkwargs(c, loc, keywords, i - nseen, i));
4322
555
                    if (have_dict) {
4323
191
                        ADDOP_I(c, loc, DICT_MERGE, 1);
4324
191
                    }
4325
555
                    have_dict = 1;
4326
555
                    nseen = 0;
4327
555
                }
4328
1.69k
                if (!have_dict) {
4329
761
                    ADDOP_I(c, loc, BUILD_MAP, 0);
4330
761
                    have_dict = 1;
4331
761
                }
4332
1.69k
                VISIT(c, expr, kw->value);
4333
1.69k
                ADDOP_I(c, loc, DICT_MERGE, 1);
4334
1.69k
            }
4335
1.27k
            else {
4336
1.27k
                nseen++;
4337
1.27k
            }
4338
2.97k
        }
4339
1.35k
        if (nseen) {
4340
            /* Pack up any trailing keyword arguments. */
4341
396
            RETURN_IF_ERROR(codegen_subkwargs(c, loc, keywords, nkwelts - nseen, nkwelts));
4342
395
            if (have_dict) {
4343
168
                ADDOP_I(c, loc, DICT_MERGE, 1);
4344
168
            }
4345
395
            have_dict = 1;
4346
395
        }
4347
1.35k
        assert(have_dict);
4348
1.35k
    }
4349
2.93k
    if (nkwelts == 0) {
4350
1.58k
        ADDOP(c, loc, PUSH_NULL);
4351
1.58k
    }
4352
2.93k
    ADDOP(c, loc, CALL_FUNCTION_EX);
4353
2.93k
    return SUCCESS;
4354
2.93k
}
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
13.7k
{
4362
13.7k
    return codegen_call_helper_impl(c, loc, n, args, NULL, keywords);
4363
13.7k
}
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.36k
{
4389
5.36k
    comprehension_ty gen;
4390
5.36k
    gen = (comprehension_ty)asdl_seq_GET(generators, gen_index);
4391
5.36k
    if (gen->is_async) {
4392
1.35k
        return codegen_async_comprehension_generator(
4393
1.35k
            c, loc, generators, gen_index, depth, elt, val, type,
4394
1.35k
            iter_on_stack);
4395
4.01k
    } else {
4396
4.01k
        return codegen_sync_comprehension_generator(
4397
4.01k
            c, loc, generators, gen_index, depth, elt, val, type,
4398
4.01k
            iter_on_stack);
4399
4.01k
    }
4400
5.36k
}
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.01k
{
4409
    /* generate code for the iterator, then each of the ifs,
4410
       and then write to the element */
4411
4412
4.01k
    NEW_JUMP_TARGET_LABEL(c, start);
4413
4.01k
    NEW_JUMP_TARGET_LABEL(c, if_cleanup);
4414
4.01k
    NEW_JUMP_TARGET_LABEL(c, anchor);
4415
4416
4.01k
    comprehension_ty gen = (comprehension_ty)asdl_seq_GET(generators,
4417
4.01k
                                                          gen_index);
4418
4419
4.01k
    if (!iter_on_stack) {
4420
1.72k
        if (gen_index == 0) {
4421
1.23k
            assert(METADATA(c)->u_argcount == 1);
4422
1.23k
            ADDOP_I(c, loc, LOAD_FAST, 0);
4423
1.23k
        }
4424
487
        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
487
            asdl_expr_seq *elts;
4430
487
            switch (gen->iter->kind) {
4431
0
                case List_kind:
4432
0
                    elts = gen->iter->v.List.elts;
4433
0
                    break;
4434
81
                case Tuple_kind:
4435
81
                    elts = gen->iter->v.Tuple.elts;
4436
81
                    break;
4437
406
                default:
4438
406
                    elts = NULL;
4439
487
            }
4440
487
            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
487
            if (IS_JUMP_TARGET_LABEL(start)) {
4448
487
                VISIT(c, expr, gen->iter);
4449
487
            }
4450
487
        }
4451
1.72k
    }
4452
4453
4.00k
    if (IS_JUMP_TARGET_LABEL(start)) {
4454
4.00k
        depth += 2;
4455
4.00k
        ADDOP(c, LOC(gen->iter), GET_ITER);
4456
4.00k
        USE_LABEL(c, start);
4457
4.00k
        ADDOP_JUMP(c, LOC(gen->iter), FOR_ITER, anchor);
4458
4.00k
    }
4459
4.00k
    VISIT(c, expr, gen->target);
4460
4461
    /* XXX this needs to be cleaned up...a lot! */
4462
3.95k
    Py_ssize_t n = asdl_seq_LEN(gen->ifs);
4463
5.87k
    for (Py_ssize_t i = 0; i < n; i++) {
4464
1.98k
        expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i);
4465
1.98k
        RETURN_IF_ERROR(codegen_jump_if(c, loc, e, if_cleanup, 0));
4466
1.98k
    }
4467
4468
3.89k
    if (++gen_index < asdl_seq_LEN(generators)) {
4469
501
        RETURN_IF_ERROR(
4470
501
            codegen_comprehension_generator(c, loc,
4471
501
                                            generators, gen_index, depth,
4472
501
                                            elt, val, type, 0));
4473
501
    }
4474
4475
3.74k
    location elt_loc = LOC(elt);
4476
4477
    /* only append after the last for generator */
4478
3.74k
    if (gen_index >= asdl_seq_LEN(generators)) {
4479
        /* comprehension specific code */
4480
3.39k
        switch (type) {
4481
1.18k
        case COMP_GENEXP:
4482
1.18k
            VISIT(c, expr, elt);
4483
1.18k
            ADDOP_YIELD(c, elt_loc);
4484
1.18k
            ADDOP(c, elt_loc, POP_TOP);
4485
1.18k
            break;
4486
1.47k
        case COMP_LISTCOMP:
4487
1.47k
            VISIT(c, expr, elt);
4488
1.47k
            ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1);
4489
1.47k
            break;
4490
1.47k
        case COMP_SETCOMP:
4491
675
            VISIT(c, expr, elt);
4492
675
            ADDOP_I(c, elt_loc, SET_ADD, depth + 1);
4493
675
            break;
4494
675
        case COMP_DICTCOMP:
4495
            /* With '{k: v}', k is evaluated before v, so we do
4496
               the same. */
4497
57
            VISIT(c, expr, elt);
4498
57
            VISIT(c, expr, val);
4499
57
            elt_loc = LOCATION(elt->lineno,
4500
57
                               val->end_lineno,
4501
57
                               elt->col_offset,
4502
57
                               val->end_col_offset);
4503
57
            ADDOP_I(c, elt_loc, MAP_ADD, depth + 1);
4504
57
            break;
4505
57
        default:
4506
0
            return ERROR;
4507
3.39k
        }
4508
3.39k
    }
4509
4510
3.74k
    USE_LABEL(c, if_cleanup);
4511
3.74k
    if (IS_JUMP_TARGET_LABEL(start)) {
4512
3.74k
        ADDOP_JUMP(c, elt_loc, JUMP, start);
4513
4514
3.74k
        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
3.74k
        ADDOP(c, NO_LOCATION, END_FOR);
4520
3.74k
        ADDOP(c, NO_LOCATION, POP_ITER);
4521
3.74k
    }
4522
4523
3.74k
    return SUCCESS;
4524
3.74k
}
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.35k
{
4533
1.35k
    NEW_JUMP_TARGET_LABEL(c, start);
4534
1.35k
    NEW_JUMP_TARGET_LABEL(c, send);
4535
1.35k
    NEW_JUMP_TARGET_LABEL(c, except);
4536
1.35k
    NEW_JUMP_TARGET_LABEL(c, if_cleanup);
4537
4538
1.35k
    comprehension_ty gen = (comprehension_ty)asdl_seq_GET(generators,
4539
1.35k
                                                          gen_index);
4540
4541
1.35k
    if (!iter_on_stack) {
4542
427
        if (gen_index == 0) {
4543
28
            assert(METADATA(c)->u_argcount == 1);
4544
28
            ADDOP_I(c, loc, LOAD_FAST, 0);
4545
28
        }
4546
399
        else {
4547
            /* Sub-iter - calculate on the fly */
4548
399
            VISIT(c, expr, gen->iter);
4549
399
        }
4550
427
    }
4551
1.34k
    ADDOP(c, LOC(gen->iter), GET_AITER);
4552
4553
1.34k
    USE_LABEL(c, start);
4554
    /* Runtime will push a block here, so we need to account for that */
4555
1.34k
    RETURN_IF_ERROR(
4556
1.34k
        _PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_ASYNC_COMPREHENSION_GENERATOR,
4557
1.34k
                              start, NO_LABEL, NULL));
4558
4559
1.34k
    ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
4560
1.34k
    ADDOP(c, loc, GET_ANEXT);
4561
1.34k
    ADDOP_LOAD_CONST(c, loc, Py_None);
4562
1.34k
    USE_LABEL(c, send);
4563
1.34k
    ADD_YIELD_FROM(c, loc, 1);
4564
1.34k
    ADDOP(c, loc, POP_BLOCK);
4565
1.34k
    VISIT(c, expr, gen->target);
4566
4567
1.33k
    Py_ssize_t n = asdl_seq_LEN(gen->ifs);
4568
1.49k
    for (Py_ssize_t i = 0; i < n; i++) {
4569
155
        expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i);
4570
155
        RETURN_IF_ERROR(codegen_jump_if(c, loc, e, if_cleanup, 0));
4571
155
    }
4572
4573
1.33k
    depth++;
4574
1.33k
    if (++gen_index < asdl_seq_LEN(generators)) {
4575
385
        RETURN_IF_ERROR(
4576
385
            codegen_comprehension_generator(c, loc,
4577
385
                                            generators, gen_index, depth,
4578
385
                                            elt, val, type, 0));
4579
385
    }
4580
4581
1.19k
    location elt_loc = LOC(elt);
4582
    /* only append after the last for generator */
4583
1.19k
    if (gen_index >= asdl_seq_LEN(generators)) {
4584
        /* comprehension specific code */
4585
951
        switch (type) {
4586
26
        case COMP_GENEXP:
4587
26
            VISIT(c, expr, elt);
4588
26
            ADDOP_YIELD(c, elt_loc);
4589
26
            ADDOP(c, elt_loc, POP_TOP);
4590
26
            break;
4591
26
        case COMP_LISTCOMP:
4592
0
            VISIT(c, expr, elt);
4593
0
            ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1);
4594
0
            break;
4595
399
        case COMP_SETCOMP:
4596
399
            VISIT(c, expr, elt);
4597
399
            ADDOP_I(c, elt_loc, SET_ADD, depth + 1);
4598
399
            break;
4599
526
        case COMP_DICTCOMP:
4600
            /* With '{k: v}', k is evaluated before v, so we do
4601
               the same. */
4602
526
            VISIT(c, expr, elt);
4603
526
            VISIT(c, expr, val);
4604
526
            elt_loc = LOCATION(elt->lineno,
4605
526
                               val->end_lineno,
4606
526
                               elt->col_offset,
4607
526
                               val->end_col_offset);
4608
526
            ADDOP_I(c, elt_loc, MAP_ADD, depth + 1);
4609
526
            break;
4610
526
        default:
4611
0
            return ERROR;
4612
951
        }
4613
951
    }
4614
4615
1.19k
    USE_LABEL(c, if_cleanup);
4616
1.19k
    ADDOP_JUMP(c, elt_loc, JUMP, start);
4617
4618
1.19k
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_ASYNC_COMPREHENSION_GENERATOR, start);
4619
4620
1.19k
    USE_LABEL(c, except);
4621
4622
1.19k
    ADDOP_JUMP(c, loc, END_ASYNC_FOR, send);
4623
4624
1.19k
    return SUCCESS;
4625
1.19k
}
4626
4627
static int
4628
codegen_push_inlined_comprehension_locals(compiler *c, location loc,
4629
                                          PySTEntryObject *comp,
4630
                                          _PyCompile_InlinedComprehensionState *state)
4631
3.21k
{
4632
3.21k
    int in_class_block = (SYMTABLE_ENTRY(c)->ste_type == ClassBlock) &&
4633
1.28k
                          !_PyCompile_IsInInlinedComp(c);
4634
3.21k
    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.21k
    PyObject *k, *v;
4638
3.21k
    Py_ssize_t pos = 0;
4639
26.6k
    while (PyDict_Next(comp->ste_symbols, &pos, &k, &v)) {
4640
23.3k
        long symbol = PyLong_AsLong(v);
4641
23.3k
        assert(symbol >= 0 || PyErr_Occurred());
4642
23.3k
        RETURN_IF_ERROR(symbol);
4643
23.3k
        long scope = SYMBOL_TO_SCOPE(symbol);
4644
4645
23.3k
        long outsymbol = _PyST_GetSymbol(outer, k);
4646
23.3k
        RETURN_IF_ERROR(outsymbol);
4647
23.3k
        long outsc = SYMBOL_TO_SCOPE(outsymbol);
4648
4649
23.3k
        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.1k
            if (state->pushed_locals == NULL) {
4654
2.20k
                state->pushed_locals = PyList_New(0);
4655
2.20k
                if (state->pushed_locals == NULL) {
4656
0
                    return ERROR;
4657
0
                }
4658
2.20k
            }
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.1k
            ADDOP_NAME(c, loc, LOAD_FAST_AND_CLEAR, k, varnames);
4663
12.1k
            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.1k
            if (PyList_Append(state->pushed_locals, k) < 0) {
4671
0
                return ERROR;
4672
0
            }
4673
12.1k
        }
4674
23.3k
    }
4675
3.21k
    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.20k
        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.20k
        NEW_JUMP_TARGET_LABEL(c, cleanup);
4686
2.20k
        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.20k
        ADDOP_JUMP(c, loc, SETUP_FINALLY, cleanup);
4691
2.20k
    }
4692
3.21k
    return SUCCESS;
4693
3.21k
}
4694
4695
static int
4696
push_inlined_comprehension_state(compiler *c, location loc,
4697
                                 PySTEntryObject *comp,
4698
                                 _PyCompile_InlinedComprehensionState *state)
4699
3.21k
{
4700
3.21k
    RETURN_IF_ERROR(
4701
3.21k
        _PyCompile_TweakInlinedComprehensionScopes(c, loc, comp, state));
4702
3.21k
    RETURN_IF_ERROR(
4703
3.21k
        codegen_push_inlined_comprehension_locals(c, loc, comp, state));
4704
3.21k
    return SUCCESS;
4705
3.21k
}
4706
4707
static int
4708
restore_inlined_comprehension_locals(compiler *c, location loc,
4709
                                     _PyCompile_InlinedComprehensionState *state)
4710
4.18k
{
4711
4.18k
    PyObject *k;
4712
    // pop names we pushed to stack earlier
4713
4.18k
    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.18k
    ADDOP_I(c, loc, SWAP, npops + 1);
4719
26.4k
    for (Py_ssize_t i = npops - 1; i >= 0; --i) {
4720
22.2k
        k = PyList_GetItem(state->pushed_locals, i);
4721
22.2k
        if (k == NULL) {
4722
0
            return ERROR;
4723
0
        }
4724
22.2k
        ADDOP_NAME(c, loc, STORE_FAST_MAYBE_NULL, k, varnames);
4725
22.2k
    }
4726
4.18k
    return SUCCESS;
4727
4.18k
}
4728
4729
static int
4730
codegen_pop_inlined_comprehension_locals(compiler *c, location loc,
4731
                                         _PyCompile_InlinedComprehensionState *state)
4732
3.11k
{
4733
3.11k
    if (state->pushed_locals) {
4734
2.09k
        ADDOP(c, NO_LOCATION, POP_BLOCK);
4735
4736
2.09k
        NEW_JUMP_TARGET_LABEL(c, end);
4737
2.09k
        ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, end);
4738
4739
        // cleanup from an exception inside the comprehension
4740
2.09k
        USE_LABEL(c, state->cleanup);
4741
        // discard incomplete comprehension result (beneath exc on stack)
4742
2.09k
        ADDOP_I(c, NO_LOCATION, SWAP, 2);
4743
2.09k
        ADDOP(c, NO_LOCATION, POP_TOP);
4744
2.09k
        RETURN_IF_ERROR(restore_inlined_comprehension_locals(c, loc, state));
4745
2.09k
        ADDOP_I(c, NO_LOCATION, RERAISE, 0);
4746
4747
2.09k
        USE_LABEL(c, end);
4748
2.09k
        RETURN_IF_ERROR(restore_inlined_comprehension_locals(c, loc, state));
4749
2.09k
        Py_CLEAR(state->pushed_locals);
4750
2.09k
    }
4751
3.11k
    return SUCCESS;
4752
3.11k
}
4753
4754
static int
4755
pop_inlined_comprehension_state(compiler *c, location loc,
4756
                                _PyCompile_InlinedComprehensionState *state)
4757
3.11k
{
4758
3.11k
    RETURN_IF_ERROR(codegen_pop_inlined_comprehension_locals(c, loc, state));
4759
3.11k
    RETURN_IF_ERROR(_PyCompile_RevertInlinedComprehensionScopes(c, loc, state));
4760
3.11k
    return SUCCESS;
4761
3.11k
}
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.49k
{
4768
4.49k
    PyCodeObject *co = NULL;
4769
4.49k
    _PyCompile_InlinedComprehensionState inline_state = {NULL, NULL, NULL, NO_LABEL};
4770
4.49k
    comprehension_ty outermost;
4771
4.49k
    PySTEntryObject *entry = _PySymtable_Lookup(SYMTABLE(c), (void *)e);
4772
4.49k
    if (entry == NULL) {
4773
0
        goto error;
4774
0
    }
4775
4.49k
    int is_inlined = entry->ste_comp_inlined;
4776
4.49k
    int is_async_comprehension = entry->ste_coroutine;
4777
4778
4.49k
    location loc = LOC(e);
4779
4780
4.49k
    outermost = (comprehension_ty) asdl_seq_GET(generators, 0);
4781
4.49k
    if (is_inlined) {
4782
3.22k
        VISIT(c, expr, outermost->iter);
4783
3.21k
        if (push_inlined_comprehension_state(c, loc, entry, &inline_state)) {
4784
0
            goto error;
4785
0
        }
4786
3.21k
    }
4787
1.26k
    else {
4788
        /* Receive outermost iter as an implicit argument */
4789
1.26k
        _PyCompile_CodeUnitMetadata umd = {
4790
1.26k
            .u_argcount = 1,
4791
1.26k
        };
4792
1.26k
        if (codegen_enter_scope(c, name, COMPILE_SCOPE_COMPREHENSION,
4793
1.26k
                                (void *)e, e->lineno, NULL, &umd) < 0) {
4794
0
            goto error;
4795
0
        }
4796
1.26k
    }
4797
4.48k
    Py_CLEAR(entry);
4798
4799
4.48k
    if (type != COMP_GENEXP) {
4800
3.23k
        int op;
4801
3.23k
        switch (type) {
4802
1.47k
        case COMP_LISTCOMP:
4803
1.47k
            op = BUILD_LIST;
4804
1.47k
            break;
4805
1.17k
        case COMP_SETCOMP:
4806
1.17k
            op = BUILD_SET;
4807
1.17k
            break;
4808
583
        case COMP_DICTCOMP:
4809
583
            op = BUILD_MAP;
4810
583
            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.23k
        }
4816
4817
3.23k
        ADDOP_I(c, loc, op, 0);
4818
3.23k
        if (is_inlined) {
4819
3.21k
            ADDOP_I(c, loc, SWAP, 2);
4820
3.21k
        }
4821
3.23k
    }
4822
4823
4.48k
    if (codegen_comprehension_generator(c, loc, generators, 0, 0,
4824
4.48k
                                        elt, val, type, is_inlined) < 0) {
4825
140
        goto error_in_scope;
4826
140
    }
4827
4828
4.34k
    if (is_inlined) {
4829
3.11k
        if (pop_inlined_comprehension_state(c, loc, &inline_state)) {
4830
0
            goto error;
4831
0
        }
4832
3.11k
        return SUCCESS;
4833
3.11k
    }
4834
4835
1.23k
    if (type != COMP_GENEXP) {
4836
21
        ADDOP(c, LOC(e), RETURN_VALUE);
4837
21
    }
4838
1.23k
    if (type == COMP_GENEXP) {
4839
1.21k
        if (codegen_wrap_in_stopiteration_handler(c) < 0) {
4840
0
            goto error_in_scope;
4841
0
        }
4842
1.21k
    }
4843
4844
1.23k
    co = _PyCompile_OptimizeAndAssemble(c, 1);
4845
1.23k
    _PyCompile_ExitScope(c);
4846
1.23k
    if (co == NULL) {
4847
0
        goto error;
4848
0
    }
4849
4850
1.23k
    loc = LOC(e);
4851
1.23k
    if (codegen_make_closure(c, loc, co, 0) < 0) {
4852
0
        goto error;
4853
0
    }
4854
1.23k
    Py_CLEAR(co);
4855
4856
1.23k
    VISIT(c, expr, outermost->iter);
4857
1.23k
    ADDOP_I(c, loc, CALL, 0);
4858
4859
1.23k
    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.23k
    return SUCCESS;
4866
140
error_in_scope:
4867
140
    if (!is_inlined) {
4868
33
        _PyCompile_ExitScope(c);
4869
33
    }
4870
140
error:
4871
140
    Py_XDECREF(co);
4872
140
    Py_XDECREF(entry);
4873
140
    Py_XDECREF(inline_state.pushed_locals);
4874
140
    Py_XDECREF(inline_state.temp_symbols);
4875
140
    Py_XDECREF(inline_state.fast_hidden);
4876
140
    return ERROR;
4877
140
}
4878
4879
static int
4880
codegen_genexp(compiler *c, expr_ty e)
4881
1.24k
{
4882
1.24k
    assert(e->kind == GeneratorExp_kind);
4883
1.24k
    _Py_DECLARE_STR(anon_genexpr, "<genexpr>");
4884
1.24k
    return codegen_comprehension(c, e, COMP_GENEXP, &_Py_STR(anon_genexpr),
4885
1.24k
                                 e->v.GeneratorExp.generators,
4886
1.24k
                                 e->v.GeneratorExp.elt, NULL);
4887
1.24k
}
4888
4889
static int
4890
codegen_listcomp(compiler *c, expr_ty e)
4891
1.47k
{
4892
1.47k
    assert(e->kind == ListComp_kind);
4893
1.47k
    _Py_DECLARE_STR(anon_listcomp, "<listcomp>");
4894
1.47k
    return codegen_comprehension(c, e, COMP_LISTCOMP, &_Py_STR(anon_listcomp),
4895
1.47k
                                 e->v.ListComp.generators,
4896
1.47k
                                 e->v.ListComp.elt, NULL);
4897
1.47k
}
4898
4899
static int
4900
codegen_setcomp(compiler *c, expr_ty e)
4901
1.18k
{
4902
1.18k
    assert(e->kind == SetComp_kind);
4903
1.18k
    _Py_DECLARE_STR(anon_setcomp, "<setcomp>");
4904
1.18k
    return codegen_comprehension(c, e, COMP_SETCOMP, &_Py_STR(anon_setcomp),
4905
1.18k
                                 e->v.SetComp.generators,
4906
1.18k
                                 e->v.SetComp.elt, NULL);
4907
1.18k
}
4908
4909
4910
static int
4911
codegen_dictcomp(compiler *c, expr_ty e)
4912
583
{
4913
583
    assert(e->kind == DictComp_kind);
4914
583
    _Py_DECLARE_STR(anon_dictcomp, "<dictcomp>");
4915
583
    return codegen_comprehension(c, e, COMP_DICTCOMP, &_Py_STR(anon_dictcomp),
4916
583
                                 e->v.DictComp.generators,
4917
583
                                 e->v.DictComp.key, e->v.DictComp.value);
4918
583
}
4919
4920
4921
static int
4922
codegen_visit_keyword(compiler *c, keyword_ty k)
4923
1.03k
{
4924
1.03k
    VISIT(c, expr, k->value);
4925
1.02k
    return SUCCESS;
4926
1.03k
}
4927
4928
4929
static int
4930
7.85k
codegen_with_except_finish(compiler *c, jump_target_label cleanup) {
4931
7.85k
    NEW_JUMP_TARGET_LABEL(c, suppress);
4932
7.85k
    ADDOP(c, NO_LOCATION, TO_BOOL);
4933
7.85k
    ADDOP_JUMP(c, NO_LOCATION, POP_JUMP_IF_TRUE, suppress);
4934
7.85k
    ADDOP_I(c, NO_LOCATION, RERAISE, 2);
4935
4936
7.85k
    USE_LABEL(c, suppress);
4937
7.85k
    ADDOP(c, NO_LOCATION, POP_TOP); /* exc_value */
4938
7.85k
    ADDOP(c, NO_LOCATION, POP_BLOCK);
4939
7.85k
    ADDOP(c, NO_LOCATION, POP_EXCEPT);
4940
7.85k
    ADDOP(c, NO_LOCATION, POP_TOP);
4941
7.85k
    ADDOP(c, NO_LOCATION, POP_TOP);
4942
7.85k
    ADDOP(c, NO_LOCATION, POP_TOP);
4943
7.85k
    NEW_JUMP_TARGET_LABEL(c, exit);
4944
7.85k
    ADDOP_JUMP(c, NO_LOCATION, JUMP_NO_INTERRUPT, exit);
4945
4946
7.85k
    USE_LABEL(c, cleanup);
4947
7.85k
    POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
4948
4949
7.85k
    USE_LABEL(c, exit);
4950
7.85k
    return SUCCESS;
4951
7.85k
}
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
4.50k
{
4980
4.50k
    location loc = LOC(s);
4981
4.50k
    withitem_ty item = asdl_seq_GET(s->v.AsyncWith.items, pos);
4982
4983
4.50k
    assert(s->kind == AsyncWith_kind);
4984
4985
4.50k
    NEW_JUMP_TARGET_LABEL(c, block);
4986
4.50k
    NEW_JUMP_TARGET_LABEL(c, final);
4987
4.50k
    NEW_JUMP_TARGET_LABEL(c, exit);
4988
4.50k
    NEW_JUMP_TARGET_LABEL(c, cleanup);
4989
4990
    /* Evaluate EXPR */
4991
4.50k
    VISIT(c, expr, item->context_expr);
4992
4.50k
    loc = LOC(item->context_expr);
4993
4.50k
    ADDOP_I(c, loc, COPY, 1);
4994
4.50k
    ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___AEXIT__);
4995
4.50k
    ADDOP_I(c, loc, SWAP, 2);
4996
4.50k
    ADDOP_I(c, loc, SWAP, 3);
4997
4.50k
    ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___AENTER__);
4998
4.50k
    ADDOP_I(c, loc, CALL, 0);
4999
4.50k
    ADDOP_I(c, loc, GET_AWAITABLE, 1);
5000
4.50k
    ADDOP_LOAD_CONST(c, loc, Py_None);
5001
4.50k
    ADD_YIELD_FROM(c, loc, 1);
5002
5003
4.50k
    ADDOP_JUMP(c, loc, SETUP_WITH, final);
5004
5005
    /* SETUP_WITH pushes a finally block. */
5006
4.50k
    USE_LABEL(c, block);
5007
4.50k
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_ASYNC_WITH, block, final, s));
5008
5009
4.50k
    if (item->optional_vars) {
5010
600
        VISIT(c, expr, item->optional_vars);
5011
600
    }
5012
3.90k
    else {
5013
        /* Discard result from context.__aenter__() */
5014
3.90k
        ADDOP(c, loc, POP_TOP);
5015
3.90k
    }
5016
5017
4.50k
    pos++;
5018
4.50k
    if (pos == asdl_seq_LEN(s->v.AsyncWith.items)) {
5019
        /* BLOCK code */
5020
808
        VISIT_SEQ(c, stmt, s->v.AsyncWith.body);
5021
808
    }
5022
3.69k
    else {
5023
3.69k
        RETURN_IF_ERROR(codegen_async_with_inner(c, s, pos));
5024
3.69k
    }
5025
5026
4.43k
    _PyCompile_PopFBlock(c, COMPILE_FBLOCK_ASYNC_WITH, block);
5027
5028
4.43k
    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
4.43k
    RETURN_IF_ERROR(codegen_call_exit_with_nones(c, loc));
5035
4.43k
    ADDOP_I(c, loc, GET_AWAITABLE, 2);
5036
4.43k
    ADDOP_LOAD_CONST(c, loc, Py_None);
5037
4.43k
    ADD_YIELD_FROM(c, loc, 1);
5038
5039
4.43k
    ADDOP(c, loc, POP_TOP);
5040
5041
4.43k
    ADDOP_JUMP(c, loc, JUMP, exit);
5042
5043
    /* For exceptional outcome: */
5044
4.43k
    USE_LABEL(c, final);
5045
5046
4.43k
    ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
5047
4.43k
    ADDOP(c, loc, PUSH_EXC_INFO);
5048
4.43k
    ADDOP(c, loc, WITH_EXCEPT_START);
5049
4.43k
    ADDOP_I(c, loc, GET_AWAITABLE, 2);
5050
4.43k
    ADDOP_LOAD_CONST(c, loc, Py_None);
5051
4.43k
    ADD_YIELD_FROM(c, loc, 1);
5052
4.43k
    RETURN_IF_ERROR(codegen_with_except_finish(c, cleanup));
5053
5054
4.43k
    USE_LABEL(c, exit);
5055
4.43k
    return SUCCESS;
5056
4.43k
}
5057
5058
static int
5059
codegen_async_with(compiler *c, stmt_ty s)
5060
813
{
5061
813
    return codegen_async_with_inner(c, s, 0);
5062
813
}
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.51k
{
5089
3.51k
    withitem_ty item = asdl_seq_GET(s->v.With.items, pos);
5090
5091
3.51k
    assert(s->kind == With_kind);
5092
5093
3.51k
    NEW_JUMP_TARGET_LABEL(c, block);
5094
3.51k
    NEW_JUMP_TARGET_LABEL(c, final);
5095
3.51k
    NEW_JUMP_TARGET_LABEL(c, exit);
5096
3.51k
    NEW_JUMP_TARGET_LABEL(c, cleanup);
5097
5098
    /* Evaluate EXPR */
5099
3.51k
    VISIT(c, expr, item->context_expr);
5100
    /* Will push bound __exit__ */
5101
3.51k
    location loc = LOC(item->context_expr);
5102
3.51k
    ADDOP_I(c, loc, COPY, 1);
5103
3.51k
    ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___EXIT__);
5104
3.51k
    ADDOP_I(c, loc, SWAP, 2);
5105
3.51k
    ADDOP_I(c, loc, SWAP, 3);
5106
3.51k
    ADDOP_I(c, loc, LOAD_SPECIAL, SPECIAL___ENTER__);
5107
3.51k
    ADDOP_I(c, loc, CALL, 0);
5108
3.51k
    ADDOP_JUMP(c, loc, SETUP_WITH, final);
5109
5110
    /* SETUP_WITH pushes a finally block. */
5111
3.51k
    USE_LABEL(c, block);
5112
3.51k
    RETURN_IF_ERROR(_PyCompile_PushFBlock(c, loc, COMPILE_FBLOCK_WITH, block, final, s));
5113
5114
3.51k
    if (item->optional_vars) {
5115
212
        VISIT(c, expr, item->optional_vars);
5116
212
    }
5117
3.30k
    else {
5118
    /* Discard result from context.__enter__() */
5119
3.30k
        ADDOP(c, loc, POP_TOP);
5120
3.30k
    }
5121
5122
3.51k
    pos++;
5123
3.51k
    if (pos == asdl_seq_LEN(s->v.With.items)) {
5124
        /* BLOCK code */
5125
1.02k
        VISIT_SEQ(c, stmt, s->v.With.body);
5126
1.02k
    }
5127
2.49k
    else {
5128
2.49k
        RETURN_IF_ERROR(codegen_with_inner(c, s, pos));
5129
2.49k
    }
5130
5131
3.41k
    ADDOP(c, NO_LOCATION, POP_BLOCK);
5132
3.41k
    _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.41k
    RETURN_IF_ERROR(codegen_call_exit_with_nones(c, loc));
5140
3.41k
    ADDOP(c, loc, POP_TOP);
5141
3.41k
    ADDOP_JUMP(c, loc, JUMP, exit);
5142
5143
    /* For exceptional outcome: */
5144
3.41k
    USE_LABEL(c, final);
5145
5146
3.41k
    ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
5147
3.41k
    ADDOP(c, loc, PUSH_EXC_INFO);
5148
3.41k
    ADDOP(c, loc, WITH_EXCEPT_START);
5149
3.41k
    RETURN_IF_ERROR(codegen_with_except_finish(c, cleanup));
5150
5151
3.41k
    USE_LABEL(c, exit);
5152
3.41k
    return SUCCESS;
5153
3.41k
}
5154
5155
static int
5156
codegen_with(compiler *c, stmt_ty s)
5157
1.02k
{
5158
1.02k
    return codegen_with_inner(c, s, 0);
5159
1.02k
}
5160
5161
static int
5162
codegen_visit_expr(compiler *c, expr_ty e)
5163
1.93M
{
5164
1.93M
    if (Py_EnterRecursiveCall(" during compilation")) {
5165
0
        return ERROR;
5166
0
    }
5167
1.93M
    location loc = LOC(e);
5168
1.93M
    switch (e->kind) {
5169
281
    case NamedExpr_kind:
5170
281
        VISIT(c, expr, e->v.NamedExpr.value);
5171
281
        ADDOP_I(c, loc, COPY, 1);
5172
281
        VISIT(c, expr, e->v.NamedExpr.target);
5173
281
        break;
5174
1.76k
    case BoolOp_kind:
5175
1.76k
        return codegen_boolop(c, e);
5176
510k
    case BinOp_kind:
5177
510k
        VISIT(c, expr, e->v.BinOp.left);
5178
510k
        VISIT(c, expr, e->v.BinOp.right);
5179
510k
        ADDOP_BINARY(c, loc, e->v.BinOp.op);
5180
510k
        break;
5181
510k
    case UnaryOp_kind:
5182
222k
        VISIT(c, expr, e->v.UnaryOp.operand);
5183
221k
        if (e->v.UnaryOp.op == UAdd) {
5184
94.3k
            ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_UNARY_POSITIVE);
5185
94.3k
        }
5186
127k
        else if (e->v.UnaryOp.op == Not) {
5187
2.40k
            ADDOP(c, loc, TO_BOOL);
5188
2.40k
            ADDOP(c, loc, UNARY_NOT);
5189
2.40k
        }
5190
124k
        else {
5191
124k
            ADDOP(c, loc, unaryop(e->v.UnaryOp.op));
5192
124k
        }
5193
221k
        break;
5194
221k
    case Lambda_kind:
5195
4.13k
        return codegen_lambda(c, e);
5196
971
    case IfExp_kind:
5197
971
        return codegen_ifexp(c, e);
5198
696
    case Dict_kind:
5199
696
        return codegen_dict(c, e);
5200
5.98k
    case Set_kind:
5201
5.98k
        return codegen_set(c, e);
5202
1.24k
    case GeneratorExp_kind:
5203
1.24k
        return codegen_genexp(c, e);
5204
1.47k
    case ListComp_kind:
5205
1.47k
        return codegen_listcomp(c, e);
5206
1.18k
    case SetComp_kind:
5207
1.18k
        return codegen_setcomp(c, e);
5208
583
    case DictComp_kind:
5209
583
        return codegen_dictcomp(c, e);
5210
635
    case Yield_kind:
5211
635
        if (!_PyST_IsFunctionLike(SYMTABLE_ENTRY(c))) {
5212
42
            return _PyCompile_Error(c, loc, "'yield' outside function");
5213
42
        }
5214
593
        if (e->v.Yield.value) {
5215
104
            VISIT(c, expr, e->v.Yield.value);
5216
104
        }
5217
489
        else {
5218
489
            ADDOP_LOAD_CONST(c, loc, Py_None);
5219
489
        }
5220
593
        ADDOP_YIELD(c, loc);
5221
593
        break;
5222
593
    case YieldFrom_kind:
5223
4
        if (!_PyST_IsFunctionLike(SYMTABLE_ENTRY(c))) {
5224
4
            return _PyCompile_Error(c, loc, "'yield from' outside function");
5225
4
        }
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
16
    case Await_kind:
5235
16
        VISIT(c, expr, e->v.Await.value);
5236
16
        ADDOP_I(c, loc, GET_AWAITABLE, 0);
5237
16
        ADDOP_LOAD_CONST(c, loc, Py_None);
5238
16
        ADD_YIELD_FROM(c, loc, 1);
5239
16
        break;
5240
15.2k
    case Compare_kind:
5241
15.2k
        return codegen_compare(c, e);
5242
10.3k
    case Call_kind:
5243
10.3k
        return codegen_call(c, e);
5244
678k
    case Constant_kind:
5245
678k
        ADDOP_LOAD_CONST(c, loc, e->v.Constant.value);
5246
678k
        break;
5247
678k
    case JoinedStr_kind:
5248
4.58k
        return codegen_joined_str(c, e);
5249
837
    case TemplateStr_kind:
5250
837
        return codegen_template_str(c, e);
5251
4.47k
    case FormattedValue_kind:
5252
4.47k
        return codegen_formatted_value(c, e);
5253
1.96k
    case Interpolation_kind:
5254
1.96k
        return codegen_interpolation(c, e);
5255
    /* The following exprs can be assignment targets. */
5256
16.2k
    case Attribute_kind:
5257
16.2k
        if (e->v.Attribute.ctx == Load) {
5258
14.1k
            int ret = can_optimize_super_call(c, e);
5259
14.1k
            RETURN_IF_ERROR(ret);
5260
14.1k
            if (ret) {
5261
443
                RETURN_IF_ERROR(load_args_for_super(c, e->v.Attribute.value));
5262
443
                int opcode = asdl_seq_LEN(e->v.Attribute.value->v.Call.args) ?
5263
443
                    LOAD_SUPER_ATTR : LOAD_ZERO_SUPER_ATTR;
5264
443
                ADDOP_NAME(c, loc, opcode, e->v.Attribute.attr, names);
5265
443
                loc = update_start_location_to_match_attr(c, loc, e);
5266
443
                ADDOP(c, loc, NOP);
5267
443
                return SUCCESS;
5268
443
            }
5269
14.1k
        }
5270
15.8k
        RETURN_IF_ERROR(_PyCompile_MaybeAddStaticAttributeToClass(c, e));
5271
15.8k
        VISIT(c, expr, e->v.Attribute.value);
5272
15.7k
        loc = LOC(e);
5273
15.7k
        loc = update_start_location_to_match_attr(c, loc, e);
5274
15.7k
        switch (e->v.Attribute.ctx) {
5275
13.7k
        case Load:
5276
13.7k
            ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names);
5277
13.7k
            break;
5278
13.7k
        case Store:
5279
1.41k
            ADDOP_NAME(c, loc, STORE_ATTR, e->v.Attribute.attr, names);
5280
1.41k
            break;
5281
1.41k
        case Del:
5282
642
            ADDOP_NAME(c, loc, DELETE_ATTR, e->v.Attribute.attr, names);
5283
642
            break;
5284
15.7k
        }
5285
15.7k
        break;
5286
24.7k
    case Subscript_kind:
5287
24.7k
        return codegen_subscript(c, e);
5288
159
    case Starred_kind:
5289
159
        switch (e->v.Starred.ctx) {
5290
48
        case Store:
5291
            /* In all legitimate cases, the Starred node was already replaced
5292
             * by codegen_list/codegen_tuple. XXX: is that okay? */
5293
48
            return _PyCompile_Error(c, loc,
5294
48
                "starred assignment target must be in a list or tuple");
5295
111
        default:
5296
111
            return _PyCompile_Error(c, loc,
5297
111
                "can't use starred expression here");
5298
159
        }
5299
0
        break;
5300
9.08k
    case Slice_kind:
5301
9.08k
        RETURN_IF_ERROR(codegen_slice(c, e));
5302
9.06k
        break;
5303
333k
    case Name_kind:
5304
333k
        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.37k
    case List_kind:
5307
4.37k
        return codegen_list(c, e);
5308
82.1k
    case Tuple_kind:
5309
82.1k
        return codegen_tuple(c, e);
5310
1.93M
    }
5311
1.43M
    return SUCCESS;
5312
1.93M
}
5313
5314
static bool
5315
is_constant_slice(expr_ty s)
5316
34.2k
{
5317
34.2k
    return s->kind == Slice_kind &&
5318
16.7k
        (s->v.Slice.lower == NULL ||
5319
4.60k
         s->v.Slice.lower->kind == Constant_kind) &&
5320
14.6k
        (s->v.Slice.upper == NULL ||
5321
7.17k
         s->v.Slice.upper->kind == Constant_kind) &&
5322
13.4k
        (s->v.Slice.step == NULL ||
5323
6.03k
         s->v.Slice.step->kind == Constant_kind);
5324
34.2k
}
5325
5326
static bool
5327
should_apply_two_element_slice_optimization(expr_ty s)
5328
25.2k
{
5329
25.2k
    return !is_constant_slice(s) &&
5330
19.0k
           s->kind == Slice_kind &&
5331
1.55k
           s->v.Slice.step == NULL;
5332
25.2k
}
5333
5334
static int
5335
codegen_augassign(compiler *c, stmt_ty s)
5336
2.54k
{
5337
2.54k
    assert(s->kind == AugAssign_kind);
5338
2.54k
    expr_ty e = s->v.AugAssign.target;
5339
5340
2.54k
    location loc = LOC(e);
5341
5342
2.54k
    switch (e->kind) {
5343
783
    case Attribute_kind:
5344
783
        VISIT(c, expr, e->v.Attribute.value);
5345
783
        ADDOP_I(c, loc, COPY, 1);
5346
783
        loc = update_start_location_to_match_attr(c, loc, e);
5347
783
        ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names);
5348
783
        break;
5349
783
    case Subscript_kind:
5350
239
        VISIT(c, expr, e->v.Subscript.value);
5351
239
        if (should_apply_two_element_slice_optimization(e->v.Subscript.slice)) {
5352
19
            RETURN_IF_ERROR(codegen_slice_two_parts(c, e->v.Subscript.slice));
5353
18
            ADDOP_I(c, loc, COPY, 3);
5354
18
            ADDOP_I(c, loc, COPY, 3);
5355
18
            ADDOP_I(c, loc, COPY, 3);
5356
18
            ADDOP(c, loc, BINARY_SLICE);
5357
18
        }
5358
220
        else {
5359
220
            VISIT(c, expr, e->v.Subscript.slice);
5360
220
            ADDOP_I(c, loc, COPY, 2);
5361
220
            ADDOP_I(c, loc, COPY, 2);
5362
220
            ADDOP_I(c, loc, BINARY_OP, NB_SUBSCR);
5363
220
        }
5364
238
        break;
5365
1.51k
    case Name_kind:
5366
1.51k
        RETURN_IF_ERROR(codegen_nameop(c, loc, e->v.Name.id, Load));
5367
1.51k
        break;
5368
1.51k
    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.54k
    }
5374
5375
2.53k
    loc = LOC(s);
5376
5377
2.53k
    VISIT(c, expr, s->v.AugAssign.value);
5378
2.53k
    ADDOP_INPLACE(c, loc, s->v.AugAssign.op);
5379
5380
2.53k
    loc = LOC(e);
5381
5382
2.53k
    switch (e->kind) {
5383
783
    case Attribute_kind:
5384
783
        loc = update_start_location_to_match_attr(c, loc, e);
5385
783
        ADDOP_I(c, loc, SWAP, 2);
5386
783
        ADDOP_NAME(c, loc, STORE_ATTR, e->v.Attribute.attr, names);
5387
783
        break;
5388
783
    case Subscript_kind:
5389
237
        if (should_apply_two_element_slice_optimization(e->v.Subscript.slice)) {
5390
18
            ADDOP_I(c, loc, SWAP, 4);
5391
18
            ADDOP_I(c, loc, SWAP, 3);
5392
18
            ADDOP_I(c, loc, SWAP, 2);
5393
18
            ADDOP(c, loc, STORE_SLICE);
5394
18
        }
5395
219
        else {
5396
219
            ADDOP_I(c, loc, SWAP, 3);
5397
219
            ADDOP_I(c, loc, SWAP, 2);
5398
219
            ADDOP(c, loc, STORE_SUBSCR);
5399
219
        }
5400
237
        break;
5401
1.51k
    case Name_kind:
5402
1.51k
        return codegen_nameop(c, loc, e->v.Name.id, Store);
5403
0
    default:
5404
0
        Py_UNREACHABLE();
5405
2.53k
    }
5406
1.02k
    return SUCCESS;
5407
2.53k
}
5408
5409
static int
5410
codegen_check_ann_expr(compiler *c, expr_ty e)
5411
7.71k
{
5412
7.71k
    VISIT(c, expr, e);
5413
7.71k
    ADDOP(c, LOC(e), POP_TOP);
5414
7.71k
    return SUCCESS;
5415
7.71k
}
5416
5417
static int
5418
codegen_check_ann_subscr(compiler *c, expr_ty e)
5419
5.71k
{
5420
    /* We check that everything in a subscript is defined at runtime. */
5421
5.71k
    switch (e->kind) {
5422
3.31k
    case Slice_kind:
5423
3.31k
        if (e->v.Slice.lower && codegen_check_ann_expr(c, e->v.Slice.lower) < 0) {
5424
0
            return ERROR;
5425
0
        }
5426
3.31k
        if (e->v.Slice.upper && codegen_check_ann_expr(c, e->v.Slice.upper) < 0) {
5427
0
            return ERROR;
5428
0
        }
5429
3.31k
        if (e->v.Slice.step && codegen_check_ann_expr(c, e->v.Slice.step) < 0) {
5430
0
            return ERROR;
5431
0
        }
5432
3.31k
        return SUCCESS;
5433
288
    case Tuple_kind: {
5434
        /* extended slice */
5435
288
        asdl_expr_seq *elts = e->v.Tuple.elts;
5436
288
        Py_ssize_t i, n = asdl_seq_LEN(elts);
5437
5.51k
        for (i = 0; i < n; i++) {
5438
5.22k
            RETURN_IF_ERROR(codegen_check_ann_subscr(c, asdl_seq_GET(elts, i)));
5439
5.22k
        }
5440
282
        return SUCCESS;
5441
288
    }
5442
2.10k
    default:
5443
2.10k
        return codegen_check_ann_expr(c, e);
5444
5.71k
    }
5445
5.71k
}
5446
5447
static int
5448
codegen_annassign(compiler *c, stmt_ty s)
5449
16.7k
{
5450
16.7k
    location loc = LOC(s);
5451
16.7k
    expr_ty targ = s->v.AnnAssign.target;
5452
16.7k
    bool future_annotations = FUTURE_FEATURES(c) & CO_FUTURE_ANNOTATIONS;
5453
16.7k
    PyObject *mangled;
5454
5455
16.7k
    assert(s->kind == AnnAssign_kind);
5456
5457
    /* We perform the actual assignment first. */
5458
16.7k
    if (s->v.AnnAssign.value) {
5459
382
        VISIT(c, expr, s->v.AnnAssign.value);
5460
381
        VISIT(c, expr, targ);
5461
381
    }
5462
16.7k
    switch (targ->kind) {
5463
15.9k
    case Name_kind:
5464
        /* If we have a simple name in a module or class, store annotation. */
5465
15.9k
        if (s->v.AnnAssign.simple &&
5466
15.8k
            (SCOPE_TYPE(c) == COMPILE_SCOPE_MODULE ||
5467
14.9k
             SCOPE_TYPE(c) == COMPILE_SCOPE_CLASS)) {
5468
14.9k
            if (future_annotations) {
5469
2.22k
                VISIT(c, annexpr, s->v.AnnAssign.annotation);
5470
2.22k
                ADDOP_NAME(c, loc, LOAD_NAME, &_Py_ID(__annotations__), names);
5471
2.22k
                mangled = _PyCompile_MaybeMangle(c, targ->v.Name.id);
5472
2.22k
                ADDOP_LOAD_CONST_NEW(c, loc, mangled);
5473
2.22k
                ADDOP(c, loc, STORE_SUBSCR);
5474
2.22k
            }
5475
12.6k
            else {
5476
12.6k
                PyObject *conditional_annotation_index = NULL;
5477
12.6k
                RETURN_IF_ERROR(_PyCompile_AddDeferredAnnotation(
5478
12.6k
                    c, s, &conditional_annotation_index));
5479
12.6k
                if (conditional_annotation_index != NULL) {
5480
9.84k
                    if (SCOPE_TYPE(c) == COMPILE_SCOPE_CLASS) {
5481
185
                        ADDOP_NAME(c, loc, LOAD_DEREF, &_Py_ID(__conditional_annotations__), cellvars);
5482
185
                    }
5483
9.65k
                    else {
5484
9.65k
                        ADDOP_NAME(c, loc, LOAD_NAME, &_Py_ID(__conditional_annotations__), names);
5485
9.65k
                    }
5486
9.84k
                    ADDOP_LOAD_CONST_NEW(c, loc, conditional_annotation_index);
5487
9.84k
                    ADDOP_I(c, loc, SET_ADD, 1);
5488
9.84k
                    ADDOP(c, loc, POP_TOP);
5489
9.84k
                }
5490
12.6k
            }
5491
14.9k
        }
5492
15.9k
        break;
5493
15.9k
    case Attribute_kind:
5494
347
        if (!s->v.AnnAssign.value &&
5495
263
            codegen_check_ann_expr(c, targ->v.Attribute.value) < 0) {
5496
0
            return ERROR;
5497
0
        }
5498
347
        break;
5499
490
    case Subscript_kind:
5500
490
        if (!s->v.AnnAssign.value &&
5501
483
            (codegen_check_ann_expr(c, targ->v.Subscript.value) < 0 ||
5502
483
             codegen_check_ann_subscr(c, targ->v.Subscript.slice) < 0)) {
5503
5
                return ERROR;
5504
5
        }
5505
485
        break;
5506
485
    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
16.7k
    }
5512
16.7k
    return SUCCESS;
5513
16.7k
}
5514
5515
static int
5516
codegen_subscript(compiler *c, expr_ty e)
5517
24.7k
{
5518
24.7k
    location loc = LOC(e);
5519
24.7k
    expr_context_ty ctx = e->v.Subscript.ctx;
5520
5521
24.7k
    if (ctx == Load) {
5522
23.2k
        RETURN_IF_ERROR(check_subscripter(c, e->v.Subscript.value));
5523
23.2k
        RETURN_IF_ERROR(check_index(c, e->v.Subscript.value, e->v.Subscript.slice));
5524
23.2k
    }
5525
5526
24.7k
    VISIT(c, expr, e->v.Subscript.value);
5527
24.7k
    if (should_apply_two_element_slice_optimization(e->v.Subscript.slice) &&
5528
1.26k
        ctx != Del
5529
24.7k
    ) {
5530
1.15k
        RETURN_IF_ERROR(codegen_slice_two_parts(c, e->v.Subscript.slice));
5531
1.15k
        if (ctx == Load) {
5532
861
            ADDOP(c, loc, BINARY_SLICE);
5533
861
        }
5534
295
        else {
5535
295
            assert(ctx == Store);
5536
295
            ADDOP(c, loc, STORE_SLICE);
5537
295
        }
5538
1.15k
    }
5539
23.5k
    else {
5540
23.5k
        VISIT(c, expr, e->v.Subscript.slice);
5541
23.5k
        switch (ctx) {
5542
22.3k
            case Load:
5543
22.3k
                ADDOP_I(c, loc, BINARY_OP, NB_SUBSCR);
5544
22.3k
                break;
5545
22.3k
            case Store:
5546
849
                ADDOP(c, loc, STORE_SUBSCR);
5547
849
                break;
5548
849
            case Del:
5549
317
                ADDOP(c, loc, DELETE_SUBSCR);
5550
317
                break;
5551
23.5k
        }
5552
23.5k
    }
5553
24.6k
    return SUCCESS;
5554
24.7k
}
5555
5556
static int
5557
codegen_slice_two_parts(compiler *c, expr_ty s)
5558
3.12k
{
5559
3.12k
    if (s->v.Slice.lower) {
5560
1.99k
        VISIT(c, expr, s->v.Slice.lower);
5561
1.99k
    }
5562
1.13k
    else {
5563
1.13k
        ADDOP_LOAD_CONST(c, LOC(s), Py_None);
5564
1.13k
    }
5565
5566
3.12k
    if (s->v.Slice.upper) {
5567
2.01k
        VISIT(c, expr, s->v.Slice.upper);
5568
2.01k
    }
5569
1.10k
    else {
5570
1.10k
        ADDOP_LOAD_CONST(c, LOC(s), Py_None);
5571
1.10k
    }
5572
5573
3.10k
    return 0;
5574
3.12k
}
5575
5576
static int
5577
codegen_slice(compiler *c, expr_ty s)
5578
9.08k
{
5579
9.08k
    int n = 2;
5580
9.08k
    assert(s->kind == Slice_kind);
5581
5582
9.08k
    if (is_constant_slice(s)) {
5583
7.13k
        PyObject *start = NULL;
5584
7.13k
        if (s->v.Slice.lower) {
5585
1.32k
            start = s->v.Slice.lower->v.Constant.value;
5586
1.32k
        }
5587
7.13k
        PyObject *stop = NULL;
5588
7.13k
        if (s->v.Slice.upper) {
5589
3.22k
            stop = s->v.Slice.upper->v.Constant.value;
5590
3.22k
        }
5591
7.13k
        PyObject *step = NULL;
5592
7.13k
        if (s->v.Slice.step) {
5593
2.97k
            step = s->v.Slice.step->v.Constant.value;
5594
2.97k
        }
5595
7.13k
        PyObject *slice = PySlice_New(start, stop, step);
5596
7.13k
        if (slice == NULL) {
5597
0
            return ERROR;
5598
0
        }
5599
7.13k
        ADDOP_LOAD_CONST_NEW(c, LOC(s), slice);
5600
7.13k
        return SUCCESS;
5601
7.13k
    }
5602
5603
1.95k
    RETURN_IF_ERROR(codegen_slice_two_parts(c, s));
5604
5605
1.93k
    if (s->v.Slice.step) {
5606
377
        n++;
5607
377
        VISIT(c, expr, s->v.Slice.step);
5608
377
    }
5609
5610
1.92k
    ADDOP_I(c, LOC(s), BUILD_SLICE, n);
5611
1.92k
    return SUCCESS;
5612
1.92k
}
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
59.8k
    ((N)->kind == MatchAs_kind && !(N)->v.MatchAs.name)
5629
5630
#define WILDCARD_STAR_CHECK(N) \
5631
1.14k
    ((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
28.5k
    ((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
33.8k
{
5641
33.8k
    Py_ssize_t size = n + 1;
5642
33.8k
    if (size <= pc->fail_pop_size) {
5643
29.9k
        return SUCCESS;
5644
29.9k
    }
5645
3.90k
    Py_ssize_t needed = sizeof(jump_target_label) * size;
5646
3.90k
    jump_target_label *resized = PyMem_Realloc(pc->fail_pop, needed);
5647
3.90k
    if (resized == NULL) {
5648
0
        PyErr_NoMemory();
5649
0
        return ERROR;
5650
0
    }
5651
3.90k
    pc->fail_pop = resized;
5652
13.5k
    while (pc->fail_pop_size < size) {
5653
9.61k
        NEW_JUMP_TARGET_LABEL(c, new_block);
5654
9.61k
        pc->fail_pop[pc->fail_pop_size++] = new_block;
5655
9.61k
    }
5656
3.90k
    return SUCCESS;
5657
3.90k
}
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
33.8k
{
5664
    // Pop any items on the top of the stack, plus any objects we were going to
5665
    // capture on success:
5666
33.8k
    Py_ssize_t pops = pc->on_top + PyList_GET_SIZE(pc->stores);
5667
33.8k
    RETURN_IF_ERROR(ensure_fail_pop(c, pc, pops));
5668
33.8k
    ADDOP_JUMP(c, loc, op, pc->fail_pop[pops]);
5669
33.8k
    return SUCCESS;
5670
33.8k
}
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.25k
{
5677
3.25k
    if (!pc->fail_pop_size) {
5678
2
        assert(pc->fail_pop == NULL);
5679
2
        return SUCCESS;
5680
2
    }
5681
7.01k
    while (--pc->fail_pop_size) {
5682
3.76k
        USE_LABEL(c, pc->fail_pop[pc->fail_pop_size]);
5683
3.76k
        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
3.76k
    }
5690
3.25k
    USE_LABEL(c, pc->fail_pop[0]);
5691
3.25k
    PyMem_Free(pc->fail_pop);
5692
3.25k
    pc->fail_pop = NULL;
5693
3.25k
    return SUCCESS;
5694
3.25k
}
5695
5696
static int
5697
codegen_error_duplicate_store(compiler *c, location loc, identifier n)
5698
26
{
5699
26
    return _PyCompile_Error(c, loc,
5700
26
        "multiple assignments to name %R in pattern", n);
5701
26
}
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.77k
{
5707
12.3k
    while (1 < count) {
5708
9.55k
        ADDOP_I(c, loc, SWAP, count--);
5709
9.55k
    }
5710
2.77k
    return SUCCESS;
5711
2.77k
}
5712
5713
static int
5714
codegen_pattern_helper_store_name(compiler *c, location loc,
5715
                                  identifier n, pattern_context *pc)
5716
2.90k
{
5717
2.90k
    if (n == NULL) {
5718
96
        ADDOP(c, loc, POP_TOP);
5719
96
        return SUCCESS;
5720
96
    }
5721
    // Can't assign to the same name twice:
5722
2.80k
    int duplicate = PySequence_Contains(pc->stores, n);
5723
2.80k
    RETURN_IF_ERROR(duplicate);
5724
2.80k
    if (duplicate) {
5725
26
        return codegen_error_duplicate_store(c, loc, n);
5726
26
    }
5727
    // Rotate this object underneath any items we need to preserve:
5728
2.77k
    Py_ssize_t rotations = pc->on_top + PyList_GET_SIZE(pc->stores) + 1;
5729
2.77k
    RETURN_IF_ERROR(codegen_pattern_helper_rotate(c, loc, rotations));
5730
2.77k
    RETURN_IF_ERROR(PyList_Append(pc->stores, n));
5731
2.77k
    return SUCCESS;
5732
2.77k
}
5733
5734
5735
static int
5736
codegen_pattern_unpack_helper(compiler *c, location loc,
5737
                              asdl_pattern_seq *elts)
5738
1.23k
{
5739
1.23k
    Py_ssize_t n = asdl_seq_LEN(elts);
5740
1.23k
    int seen_star = 0;
5741
8.44k
    for (Py_ssize_t i = 0; i < n; i++) {
5742
7.21k
        pattern_ty elt = asdl_seq_GET(elts, i);
5743
7.21k
        if (elt->kind == MatchStar_kind && !seen_star) {
5744
864
            if ((i >= (1 << 8)) ||
5745
864
                (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
864
            ADDOP_I(c, loc, UNPACK_EX, (i + ((n-i-1) << 8)));
5751
864
            seen_star = 1;
5752
864
        }
5753
6.35k
        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.21k
    }
5758
1.23k
    if (!seen_star) {
5759
366
        ADDOP_I(c, loc, UNPACK_SEQUENCE, n);
5760
366
    }
5761
1.23k
    return SUCCESS;
5762
1.23k
}
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.23k
{
5769
1.23k
    RETURN_IF_ERROR(codegen_pattern_unpack_helper(c, loc, patterns));
5770
1.23k
    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.23k
    pc->on_top += size;
5774
6.18k
    for (Py_ssize_t i = 0; i < size; i++) {
5775
        // One less item to keep track of each time we loop through:
5776
5.08k
        pc->on_top--;
5777
5.08k
        pattern_ty pattern = asdl_seq_GET(patterns, i);
5778
5.08k
        RETURN_IF_ERROR(codegen_pattern_subpattern(c, pattern, pc));
5779
5.08k
    }
5780
1.09k
    return SUCCESS;
5781
1.23k
}
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
269
{
5791
    // We need to keep the subject around for extracting elements:
5792
269
    pc->on_top++;
5793
269
    Py_ssize_t size = asdl_seq_LEN(patterns);
5794
26.5k
    for (Py_ssize_t i = 0; i < size; i++) {
5795
26.2k
        pattern_ty pattern = asdl_seq_GET(patterns, i);
5796
26.2k
        if (WILDCARD_CHECK(pattern)) {
5797
159
            continue;
5798
159
        }
5799
26.1k
        if (i == star) {
5800
269
            assert(WILDCARD_STAR_CHECK(pattern));
5801
269
            continue;
5802
269
        }
5803
25.8k
        ADDOP_I(c, loc, COPY, 1);
5804
25.8k
        if (i < star) {
5805
62
            ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromSsize_t(i));
5806
62
        }
5807
25.8k
        else {
5808
            // The subject may not support negative indexing! Compute a
5809
            // nonnegative index:
5810
25.8k
            ADDOP(c, loc, GET_LEN);
5811
25.8k
            ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromSsize_t(size - i));
5812
25.8k
            ADDOP_BINARY(c, loc, Sub);
5813
25.8k
        }
5814
25.8k
        ADDOP_I(c, loc, BINARY_OP, NB_SUBSCR);
5815
25.8k
        RETURN_IF_ERROR(codegen_pattern_subpattern(c, pattern, pc));
5816
25.8k
    }
5817
    // Pop the subject, we're done with it:
5818
266
    pc->on_top--;
5819
266
    ADDOP(c, loc, POP_TOP);
5820
266
    return SUCCESS;
5821
266
}
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
31.4k
{
5828
31.4k
    int allow_irrefutable = pc->allow_irrefutable;
5829
31.4k
    pc->allow_irrefutable = 1;
5830
31.4k
    RETURN_IF_ERROR(codegen_pattern(c, p, pc));
5831
31.2k
    pc->allow_irrefutable = allow_irrefutable;
5832
31.2k
    return SUCCESS;
5833
31.4k
}
5834
5835
static int
5836
codegen_pattern_as(compiler *c, pattern_ty p, pattern_context *pc)
5837
2.06k
{
5838
2.06k
    assert(p->kind == MatchAs_kind);
5839
2.06k
    if (p->v.MatchAs.pattern == NULL) {
5840
        // An irrefutable match:
5841
1.70k
        if (!pc->allow_irrefutable) {
5842
23
            if (p->v.MatchAs.name) {
5843
17
                const char *e = "name capture %R makes remaining patterns unreachable";
5844
17
                return _PyCompile_Error(c, LOC(p), e, p->v.MatchAs.name);
5845
17
            }
5846
6
            const char *e = "wildcard makes remaining patterns unreachable";
5847
6
            return _PyCompile_Error(c, LOC(p), e);
5848
23
        }
5849
1.68k
        return codegen_pattern_helper_store_name(c, LOC(p), p->v.MatchAs.name, pc);
5850
1.70k
    }
5851
    // Need to make a copy for (possibly) storing later:
5852
352
    pc->on_top++;
5853
352
    ADDOP_I(c, LOC(p), COPY, 1);
5854
352
    RETURN_IF_ERROR(codegen_pattern(c, p->v.MatchAs.pattern, pc));
5855
    // Success! Store it:
5856
352
    pc->on_top--;
5857
352
    RETURN_IF_ERROR(codegen_pattern_helper_store_name(c, LOC(p), p->v.MatchAs.name, pc));
5858
351
    return SUCCESS;
5859
352
}
5860
5861
static int
5862
codegen_pattern_star(compiler *c, pattern_ty p, pattern_context *pc)
5863
864
{
5864
864
    assert(p->kind == MatchStar_kind);
5865
864
    RETURN_IF_ERROR(
5866
864
        codegen_pattern_helper_store_name(c, LOC(p), p->v.MatchStar.name, pc));
5867
864
    return SUCCESS;
5868
864
}
5869
5870
static int
5871
validate_kwd_attrs(compiler *c, asdl_identifier_seq *attrs, asdl_pattern_seq* patterns)
5872
153
{
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
153
    Py_ssize_t nattrs = asdl_seq_LEN(attrs);
5876
319
    for (Py_ssize_t i = 0; i < nattrs; i++) {
5877
172
        identifier attr = ((identifier)asdl_seq_GET(attrs, i));
5878
248
        for (Py_ssize_t j = i + 1; j < nattrs; j++) {
5879
82
            identifier other = ((identifier)asdl_seq_GET(attrs, j));
5880
82
            if (!PyUnicode_Compare(attr, other)) {
5881
6
                location loc = LOC((pattern_ty) asdl_seq_GET(patterns, j));
5882
6
                return _PyCompile_Error(c, loc, "attribute name repeated "
5883
6
                                                "in class pattern: %U", attr);
5884
6
            }
5885
82
        }
5886
172
    }
5887
147
    return SUCCESS;
5888
153
}
5889
5890
static int
5891
codegen_pattern_class(compiler *c, pattern_ty p, pattern_context *pc)
5892
325
{
5893
325
    assert(p->kind == MatchClass_kind);
5894
325
    asdl_pattern_seq *patterns = p->v.MatchClass.patterns;
5895
325
    asdl_identifier_seq *kwd_attrs = p->v.MatchClass.kwd_attrs;
5896
325
    asdl_pattern_seq *kwd_patterns = p->v.MatchClass.kwd_patterns;
5897
325
    Py_ssize_t nargs = asdl_seq_LEN(patterns);
5898
325
    Py_ssize_t nattrs = asdl_seq_LEN(kwd_attrs);
5899
325
    Py_ssize_t nkwd_patterns = asdl_seq_LEN(kwd_patterns);
5900
325
    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
325
    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
325
    if (nattrs) {
5911
153
        RETURN_IF_ERROR(validate_kwd_attrs(c, kwd_attrs, kwd_patterns));
5912
153
    }
5913
319
    VISIT(c, expr, p->v.MatchClass.cls);
5914
319
    PyObject *attr_names = PyTuple_New(nattrs);
5915
319
    if (attr_names == NULL) {
5916
0
        return ERROR;
5917
0
    }
5918
319
    Py_ssize_t i;
5919
477
    for (i = 0; i < nattrs; i++) {
5920
158
        PyObject *name = asdl_seq_GET(kwd_attrs, i);
5921
158
        PyTuple_SET_ITEM(attr_names, i, Py_NewRef(name));
5922
158
    }
5923
319
    ADDOP_LOAD_CONST_NEW(c, LOC(p), attr_names);
5924
319
    ADDOP_I(c, LOC(p), MATCH_CLASS, nargs);
5925
319
    ADDOP_I(c, LOC(p), COPY, 1);
5926
319
    ADDOP_LOAD_CONST(c, LOC(p), Py_None);
5927
319
    ADDOP_I(c, LOC(p), IS_OP, 1);
5928
    // TOS is now a tuple of (nargs + nattrs) attributes (or None):
5929
319
    pc->on_top++;
5930
319
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
5931
319
    ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, nargs + nattrs);
5932
319
    pc->on_top += nargs + nattrs - 1;
5933
753
    for (i = 0; i < nargs + nattrs; i++) {
5934
487
        pc->on_top--;
5935
487
        pattern_ty pattern;
5936
487
        if (i < nargs) {
5937
            // Positional:
5938
346
            pattern = asdl_seq_GET(patterns, i);
5939
346
        }
5940
141
        else {
5941
            // Keyword:
5942
141
            pattern = asdl_seq_GET(kwd_patterns, i - nargs);
5943
141
        }
5944
487
        if (WILDCARD_CHECK(pattern)) {
5945
4
            ADDOP(c, LOC(p), POP_TOP);
5946
4
            continue;
5947
4
        }
5948
483
        RETURN_IF_ERROR(codegen_pattern_subpattern(c, pattern, pc));
5949
483
    }
5950
    // Success! Pop the tuple of attributes:
5951
266
    return SUCCESS;
5952
319
}
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
621
{
6088
621
    assert(p->kind == MatchOr_kind);
6089
621
    NEW_JUMP_TARGET_LABEL(c, end);
6090
621
    Py_ssize_t size = asdl_seq_LEN(p->v.MatchOr.patterns);
6091
621
    assert(size > 1);
6092
    // We're going to be messing with pc. Keep the original info handy:
6093
621
    pattern_context old_pc = *pc;
6094
621
    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
621
    PyObject *control = NULL;
6099
    // NOTE: We can't use returning macros anymore! goto error on error.
6100
2.57k
    for (Py_ssize_t i = 0; i < size; i++) {
6101
1.97k
        pattern_ty alt = asdl_seq_GET(p->v.MatchOr.patterns, i);
6102
1.97k
        PyObject *pc_stores = PyList_New(0);
6103
1.97k
        if (pc_stores == NULL) {
6104
0
            goto error;
6105
0
        }
6106
1.97k
        Py_SETREF(pc->stores, pc_stores);
6107
        // An irrefutable sub-pattern must be last, if it is allowed at all:
6108
1.97k
        pc->allow_irrefutable = (i == size - 1) && old_pc.allow_irrefutable;
6109
1.97k
        pc->fail_pop = NULL;
6110
1.97k
        pc->fail_pop_size = 0;
6111
1.97k
        pc->on_top = 0;
6112
1.97k
        if (codegen_addop_i(INSTR_SEQUENCE(c), COPY, 1, LOC(alt)) < 0 ||
6113
1.97k
            codegen_pattern(c, alt, pc) < 0) {
6114
17
            goto error;
6115
17
        }
6116
        // Success!
6117
1.95k
        Py_ssize_t nstores = PyList_GET_SIZE(pc->stores);
6118
1.95k
        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
604
            assert(control == NULL);
6123
604
            control = Py_NewRef(pc->stores);
6124
604
        }
6125
1.35k
        else if (nstores != PyList_GET_SIZE(control)) {
6126
8
            goto diff;
6127
8
        }
6128
1.34k
        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
1.95k
        assert(control);
6175
1.94k
        if (codegen_addop_j(INSTR_SEQUENCE(c), LOC(alt), JUMP, end) < 0 ||
6176
1.94k
            emit_and_reset_fail_pop(c, LOC(alt), pc) < 0)
6177
0
        {
6178
0
            goto error;
6179
0
        }
6180
1.94k
    }
6181
596
    Py_DECREF(pc->stores);
6182
596
    *pc = old_pc;
6183
596
    Py_INCREF(pc->stores);
6184
    // Need to NULL this for the PyMem_Free call in the error block.
6185
596
    old_pc.fail_pop = NULL;
6186
    // No match. Pop the remaining copy of the subject and fail:
6187
596
    if (codegen_addop_noarg(INSTR_SEQUENCE(c), POP_TOP, LOC(p)) < 0 ||
6188
596
        jump_to_fail_pop(c, LOC(p), pc, JUMP) < 0) {
6189
0
        goto error;
6190
0
    }
6191
6192
596
    USE_LABEL(c, end);
6193
596
    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
596
    Py_ssize_t nrots = nstores + 1 + pc->on_top + PyList_GET_SIZE(pc->stores);
6201
596
    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
596
    Py_DECREF(old_pc.stores);
6222
596
    Py_DECREF(control);
6223
    // NOTE: Returning macros are safe again.
6224
    // Pop the copy of the subject:
6225
596
    ADDOP(c, LOC(p), POP_TOP);
6226
596
    return SUCCESS;
6227
8
diff:
6228
8
    _PyCompile_Error(c, LOC(p), "alternative patterns bind different names");
6229
25
error:
6230
25
    PyMem_Free(old_pc.fail_pop);
6231
25
    Py_DECREF(old_pc.stores);
6232
25
    Py_XDECREF(control);
6233
25
    return ERROR;
6234
8
}
6235
6236
6237
static int
6238
codegen_pattern_sequence(compiler *c, pattern_ty p,
6239
                         pattern_context *pc)
6240
1.71k
{
6241
1.71k
    assert(p->kind == MatchSequence_kind);
6242
1.71k
    asdl_pattern_seq *patterns = p->v.MatchSequence.patterns;
6243
1.71k
    Py_ssize_t size = asdl_seq_LEN(patterns);
6244
1.71k
    Py_ssize_t star = -1;
6245
1.71k
    int only_wildcard = 1;
6246
1.71k
    int star_wildcard = 0;
6247
    // Find a starred name, if it exists. There may be at most one:
6248
35.3k
    for (Py_ssize_t i = 0; i < size; i++) {
6249
33.6k
        pattern_ty pattern = asdl_seq_GET(patterns, i);
6250
33.6k
        if (pattern->kind == MatchStar_kind) {
6251
1.14k
            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.14k
            star_wildcard = WILDCARD_STAR_CHECK(pattern);
6256
1.14k
            only_wildcard &= star_wildcard;
6257
1.14k
            star = i;
6258
1.14k
            continue;
6259
1.14k
        }
6260
32.5k
        only_wildcard &= WILDCARD_CHECK(pattern);
6261
32.5k
    }
6262
    // We need to keep the subject on top during the sequence and length checks:
6263
1.71k
    pc->on_top++;
6264
1.71k
    ADDOP(c, LOC(p), MATCH_SEQUENCE);
6265
1.71k
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6266
1.71k
    if (star < 0) {
6267
        // No star: len(subject) == size
6268
573
        ADDOP(c, LOC(p), GET_LEN);
6269
573
        ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size));
6270
573
        ADDOP_COMPARE(c, LOC(p), Eq);
6271
573
        RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6272
573
    }
6273
1.14k
    else if (size > 1) {
6274
        // Star: len(subject) >= size - 1
6275
1.12k
        ADDOP(c, LOC(p), GET_LEN);
6276
1.12k
        ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size - 1));
6277
1.12k
        ADDOP_COMPARE(c, LOC(p), GtE);
6278
1.12k
        RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6279
1.12k
    }
6280
    // Whatever comes next should consume the subject:
6281
1.71k
    pc->on_top--;
6282
1.71k
    if (only_wildcard) {
6283
        // Patterns like: [] / [_] / [_, _] / [*_] / [_, *_] / [_, _, *_] / etc.
6284
215
        ADDOP(c, LOC(p), POP_TOP);
6285
215
    }
6286
1.49k
    else if (star_wildcard) {
6287
269
        RETURN_IF_ERROR(pattern_helper_sequence_subscr(c, LOC(p), patterns, star, pc));
6288
269
    }
6289
1.23k
    else {
6290
1.23k
        RETURN_IF_ERROR(pattern_helper_sequence_unpack(c, LOC(p), patterns, star, pc));
6291
1.23k
    }
6292
1.57k
    return SUCCESS;
6293
1.71k
}
6294
6295
static int
6296
codegen_pattern_value(compiler *c, pattern_ty p, pattern_context *pc)
6297
28.5k
{
6298
28.5k
    assert(p->kind == MatchValue_kind);
6299
28.5k
    expr_ty value = p->v.MatchValue.value;
6300
28.5k
    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
28.5k
    VISIT(c, expr, value);
6305
28.5k
    ADDOP_COMPARE(c, LOC(p), Eq);
6306
28.5k
    ADDOP(c, LOC(p), TO_BOOL);
6307
28.5k
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6308
28.5k
    return SUCCESS;
6309
28.5k
}
6310
6311
static int
6312
codegen_pattern_singleton(compiler *c, pattern_ty p, pattern_context *pc)
6313
1.01k
{
6314
1.01k
    assert(p->kind == MatchSingleton_kind);
6315
1.01k
    ADDOP_LOAD_CONST(c, LOC(p), p->v.MatchSingleton.value);
6316
1.01k
    ADDOP_COMPARE(c, LOC(p), Is);
6317
1.01k
    RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
6318
1.01k
    return SUCCESS;
6319
1.01k
}
6320
6321
static int
6322
codegen_pattern(compiler *c, pattern_ty p, pattern_context *pc)
6323
35.1k
{
6324
35.1k
    switch (p->kind) {
6325
28.5k
        case MatchValue_kind:
6326
28.5k
            return codegen_pattern_value(c, p, pc);
6327
1.01k
        case MatchSingleton_kind:
6328
1.01k
            return codegen_pattern_singleton(c, p, pc);
6329
1.71k
        case MatchSequence_kind:
6330
1.71k
            return codegen_pattern_sequence(c, p, pc);
6331
2
        case MatchMapping_kind:
6332
2
            return codegen_pattern_mapping(c, p, pc);
6333
325
        case MatchClass_kind:
6334
325
            return codegen_pattern_class(c, p, pc);
6335
864
        case MatchStar_kind:
6336
864
            return codegen_pattern_star(c, p, pc);
6337
2.06k
        case MatchAs_kind:
6338
2.06k
            return codegen_pattern_as(c, p, pc);
6339
621
        case MatchOr_kind:
6340
621
            return codegen_pattern_or(c, p, pc);
6341
35.1k
    }
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
35.1k
}
6347
6348
static int
6349
codegen_match_inner(compiler *c, stmt_ty s, pattern_context *pc)
6350
272
{
6351
272
    VISIT(c, expr, s->v.Match.subject);
6352
272
    NEW_JUMP_TARGET_LABEL(c, end);
6353
272
    Py_ssize_t cases = asdl_seq_LEN(s->v.Match.cases);
6354
272
    assert(cases > 0);
6355
272
    match_case_ty m = asdl_seq_GET(s->v.Match.cases, cases - 1);
6356
272
    int has_default = WILDCARD_CHECK(m->pattern) && 1 < cases;
6357
1.57k
    for (Py_ssize_t i = 0; i < cases - has_default; i++) {
6358
1.37k
        m = asdl_seq_GET(s->v.Match.cases, i);
6359
        // Only copy the subject if we're *not* on the last case:
6360
1.37k
        if (i != cases - has_default - 1) {
6361
1.10k
            ADDOP_I(c, LOC(m->pattern), COPY, 1);
6362
1.10k
        }
6363
1.37k
        pc->stores = PyList_New(0);
6364
1.37k
        if (pc->stores == NULL) {
6365
0
            return ERROR;
6366
0
        }
6367
        // Irrefutable cases must be either guarded, last, or both:
6368
1.37k
        pc->allow_irrefutable = m->guard != NULL || i == cases - 1;
6369
1.37k
        pc->fail_pop = NULL;
6370
1.37k
        pc->fail_pop_size = 0;
6371
1.37k
        pc->on_top = 0;
6372
        // NOTE: Can't use returning macros here (they'll leak pc->stores)!
6373
1.37k
        if (codegen_pattern(c, m->pattern, pc) < 0) {
6374
70
            Py_DECREF(pc->stores);
6375
70
            return ERROR;
6376
70
        }
6377
1.37k
        assert(!pc->on_top);
6378
        // It's a match! Store all of the captured names (they're on the stack).
6379
1.30k
        Py_ssize_t nstores = PyList_GET_SIZE(pc->stores);
6380
3.99k
        for (Py_ssize_t n = 0; n < nstores; n++) {
6381
2.69k
            PyObject *name = PyList_GET_ITEM(pc->stores, n);
6382
2.69k
            if (codegen_nameop(c, LOC(m->pattern), name, Store) < 0) {
6383
0
                Py_DECREF(pc->stores);
6384
0
                return ERROR;
6385
0
            }
6386
2.69k
        }
6387
1.30k
        Py_DECREF(pc->stores);
6388
        // NOTE: Returning macros are safe again.
6389
1.30k
        if (m->guard) {
6390
14
            RETURN_IF_ERROR(ensure_fail_pop(c, pc, 0));
6391
14
            RETURN_IF_ERROR(codegen_jump_if(c, LOC(m->pattern), m->guard, pc->fail_pop[0], 0));
6392
14
        }
6393
        // Success! Pop the subject off, we're done with it:
6394
1.30k
        if (i != cases - has_default - 1) {
6395
            /* Use the next location to give better locations for branch events */
6396
1.10k
            ADDOP(c, NEXT_LOCATION, POP_TOP);
6397
1.10k
        }
6398
1.30k
        VISIT_SEQ(c, stmt, m->body);
6399
1.30k
        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.30k
        RETURN_IF_ERROR(emit_and_reset_fail_pop(c, LOC(m->pattern), pc));
6404
1.30k
    }
6405
202
    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
202
    USE_LABEL(c, end);
6423
202
    return SUCCESS;
6424
202
}
6425
6426
static int
6427
codegen_match(compiler *c, stmt_ty s)
6428
272
{
6429
272
    pattern_context pc;
6430
272
    pc.fail_pop = NULL;
6431
272
    int result = codegen_match_inner(c, s, &pc);
6432
272
    PyMem_Free(pc.fail_pop);
6433
272
    return result;
6434
272
}
6435
6436
#undef WILDCARD_CHECK
6437
#undef WILDCARD_STAR_CHECK
6438
6439
6440
int
6441
_PyCodegen_AddReturnAtEnd(compiler *c, int addNone)
6442
42.0k
{
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
42.0k
    if (addNone) {
6447
34.3k
        ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
6448
34.3k
    }
6449
42.0k
    ADDOP(c, NO_LOCATION, RETURN_VALUE);
6450
42.0k
    return SUCCESS;
6451
42.0k
}