Coverage Report

Created: 2026-07-14 06:16

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