Coverage Report

Created: 2026-05-16 06:46

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