Coverage Report

Created: 2026-06-21 06:15

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