Coverage Report

Created: 2025-07-18 06:09

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