Coverage Report

Created: 2026-05-30 06:18

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