Coverage Report

Created: 2026-02-26 06:53

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