Coverage Report

Created: 2026-02-09 07:07

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