Coverage Report

Created: 2026-10-31 06:21

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