Coverage Report

Created: 2026-03-23 06:45

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