LCOV - code coverage report
Current view: top level - Python - compile.c (source / functions) Hit Total Coverage
Test: CPython 3.12 LCOV report [commit 5e6661bce9] Lines: 3732 4990 74.8 %
Date: 2023-03-20 08:15:36 Functions: 245 269 91.1 %
Branches: 2719 4935 55.1 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * This file compiles an abstract syntax tree (AST) into Python bytecode.
       3                 :            :  *
       4                 :            :  * The primary entry point is _PyAST_Compile(), which returns a
       5                 :            :  * PyCodeObject.  The compiler makes several passes to build the code
       6                 :            :  * object:
       7                 :            :  *   1. Checks for future statements.  See future.c
       8                 :            :  *   2. Builds a symbol table.  See symtable.c.
       9                 :            :  *   3. Generate code for basic blocks.  See compiler_mod() in this file.
      10                 :            :  *   4. Assemble the basic blocks into final code.  See assemble() in
      11                 :            :  *      this file.
      12                 :            :  *   5. Optimize the byte code (peephole optimizations).
      13                 :            :  *
      14                 :            :  * Note that compiler_mod() suggests module, but the module ast type
      15                 :            :  * (mod_ty) has cases for expressions and interactive statements.
      16                 :            :  *
      17                 :            :  * CAUTION: The VISIT_* macros abort the current function when they
      18                 :            :  * encounter a problem. So don't invoke them when there is memory
      19                 :            :  * which needs to be released. Code blocks are OK, as the compiler
      20                 :            :  * structure takes care of releasing those.  Use the arena to manage
      21                 :            :  * objects.
      22                 :            :  */
      23                 :            : 
      24                 :            : #include <stdbool.h>
      25                 :            : 
      26                 :            : // Need _PyOpcode_RelativeJump of pycore_opcode.h
      27                 :            : #define NEED_OPCODE_TABLES
      28                 :            : 
      29                 :            : #include "Python.h"
      30                 :            : #include "pycore_ast.h"           // _PyAST_GetDocString()
      31                 :            : #include "pycore_code.h"          // _PyCode_New()
      32                 :            : #include "pycore_compile.h"
      33                 :            : #include "pycore_intrinsics.h"
      34                 :            : #include "pycore_long.h"          // _PyLong_GetZero()
      35                 :            : #include "pycore_opcode.h"        // _PyOpcode_Caches
      36                 :            : #include "pycore_pymem.h"         // _PyMem_IsPtrFreed()
      37                 :            : #include "pycore_symtable.h"      // PySTEntryObject, _PyFuture_FromAST()
      38                 :            : 
      39                 :            : #include "opcode_metadata.h"      // _PyOpcode_opcode_metadata, _PyOpcode_num_popped/pushed
      40                 :            : 
      41                 :            : 
      42                 :            : #define DEFAULT_BLOCK_SIZE 16
      43                 :            : #define DEFAULT_CODE_SIZE 128
      44                 :            : #define DEFAULT_LNOTAB_SIZE 16
      45                 :            : #define DEFAULT_CNOTAB_SIZE 32
      46                 :            : 
      47                 :            : #define COMP_GENEXP   0
      48                 :            : #define COMP_LISTCOMP 1
      49                 :            : #define COMP_SETCOMP  2
      50                 :            : #define COMP_DICTCOMP 3
      51                 :            : 
      52                 :            : /* A soft limit for stack use, to avoid excessive
      53                 :            :  * memory use for large constants, etc.
      54                 :            :  *
      55                 :            :  * The value 30 is plucked out of thin air.
      56                 :            :  * Code that could use more stack than this is
      57                 :            :  * rare, so the exact value is unimportant.
      58                 :            :  */
      59                 :            : #define STACK_USE_GUIDELINE 30
      60                 :            : 
      61                 :            : #undef SUCCESS
      62                 :            : #undef ERROR
      63                 :            : #define SUCCESS 0
      64                 :            : #define ERROR -1
      65                 :            : 
      66                 :            : #define RETURN_IF_ERROR(X)  \
      67                 :            :     if ((X) == -1) {        \
      68                 :            :         return ERROR;       \
      69                 :            :     }
      70                 :            : 
      71                 :            : /* If we exceed this limit, it should
      72                 :            :  * be considered a compiler bug.
      73                 :            :  * Currently it should be impossible
      74                 :            :  * to exceed STACK_USE_GUIDELINE * 100,
      75                 :            :  * as 100 is the maximum parse depth.
      76                 :            :  * For performance reasons we will
      77                 :            :  * want to reduce this to a
      78                 :            :  * few hundred in the future.
      79                 :            :  *
      80                 :            :  * NOTE: Whatever MAX_ALLOWED_STACK_USE is
      81                 :            :  * set to, it should never restrict what Python
      82                 :            :  * we can write, just how we compile it.
      83                 :            :  */
      84                 :            : #define MAX_ALLOWED_STACK_USE (STACK_USE_GUIDELINE * 100)
      85                 :            : 
      86                 :            : 
      87                 :            : #define MAX_REAL_OPCODE 254
      88                 :            : 
      89                 :            : #define IS_WITHIN_OPCODE_RANGE(opcode) \
      90                 :            :         (((opcode) >= 0 && (opcode) <= MAX_REAL_OPCODE) || \
      91                 :            :          IS_PSEUDO_OPCODE(opcode))
      92                 :            : 
      93                 :            : #define IS_JUMP_OPCODE(opcode) \
      94                 :            :          is_bit_set_in_table(_PyOpcode_Jump, opcode)
      95                 :            : 
      96                 :            : #define IS_BLOCK_PUSH_OPCODE(opcode) \
      97                 :            :         ((opcode) == SETUP_FINALLY || \
      98                 :            :          (opcode) == SETUP_WITH || \
      99                 :            :          (opcode) == SETUP_CLEANUP)
     100                 :            : 
     101                 :            : #define HAS_TARGET(opcode) \
     102                 :            :         (IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode))
     103                 :            : 
     104                 :            : /* opcodes that must be last in the basicblock */
     105                 :            : #define IS_TERMINATOR_OPCODE(opcode) \
     106                 :            :         (IS_JUMP_OPCODE(opcode) || IS_SCOPE_EXIT_OPCODE(opcode))
     107                 :            : 
     108                 :            : /* opcodes which are not emitted in codegen stage, only by the assembler */
     109                 :            : #define IS_ASSEMBLER_OPCODE(opcode) \
     110                 :            :         ((opcode) == JUMP_FORWARD || \
     111                 :            :          (opcode) == JUMP_BACKWARD || \
     112                 :            :          (opcode) == JUMP_BACKWARD_NO_INTERRUPT)
     113                 :            : 
     114                 :            : #define IS_BACKWARDS_JUMP_OPCODE(opcode) \
     115                 :            :         ((opcode) == JUMP_BACKWARD || \
     116                 :            :          (opcode) == JUMP_BACKWARD_NO_INTERRUPT)
     117                 :            : 
     118                 :            : #define IS_UNCONDITIONAL_JUMP_OPCODE(opcode) \
     119                 :            :         ((opcode) == JUMP || \
     120                 :            :          (opcode) == JUMP_NO_INTERRUPT || \
     121                 :            :          (opcode) == JUMP_FORWARD || \
     122                 :            :          (opcode) == JUMP_BACKWARD || \
     123                 :            :          (opcode) == JUMP_BACKWARD_NO_INTERRUPT)
     124                 :            : 
     125                 :            : #define IS_SCOPE_EXIT_OPCODE(opcode) \
     126                 :            :         ((opcode) == RETURN_VALUE || \
     127                 :            :          (opcode) == RETURN_CONST || \
     128                 :            :          (opcode) == RAISE_VARARGS || \
     129                 :            :          (opcode) == RERAISE)
     130                 :            : 
     131                 :            : #define IS_SUPERINSTRUCTION_OPCODE(opcode) \
     132                 :            :         ((opcode) == LOAD_FAST__LOAD_FAST || \
     133                 :            :          (opcode) == LOAD_FAST__LOAD_CONST || \
     134                 :            :          (opcode) == LOAD_CONST__LOAD_FAST || \
     135                 :            :          (opcode) == STORE_FAST__LOAD_FAST || \
     136                 :            :          (opcode) == STORE_FAST__STORE_FAST)
     137                 :            : 
     138                 :            : #define IS_TOP_LEVEL_AWAIT(C) ( \
     139                 :            :         ((C)->c_flags.cf_flags & PyCF_ALLOW_TOP_LEVEL_AWAIT) \
     140                 :            :         && ((C)->u->u_ste->ste_type == ModuleBlock))
     141                 :            : 
     142                 :            : typedef _PyCompilerSrcLocation location;
     143                 :            : 
     144                 :            : #define LOCATION(LNO, END_LNO, COL, END_COL) \
     145                 :            :     ((const location){(LNO), (END_LNO), (COL), (END_COL)})
     146                 :            : 
     147                 :            : static location NO_LOCATION = {-1, -1, -1, -1};
     148                 :            : 
     149                 :            : /* Return true if loc1 starts after loc2 ends. */
     150                 :            : static inline bool
     151                 :        524 : location_is_after(location loc1, location loc2) {
     152         [ -  + ]:        524 :     return (loc1.lineno > loc2.end_lineno) ||
     153         [ #  # ]:          0 :             ((loc1.lineno == loc2.end_lineno) &&
     154         [ #  # ]:          0 :              (loc1.col_offset > loc2.end_col_offset));
     155                 :            : }
     156                 :            : 
     157                 :            : static inline bool
     158                 :     342036 : same_location(location a, location b)
     159                 :            : {
     160                 :     595006 :     return a.lineno == b.lineno &&
     161         [ +  + ]:     252970 :            a.end_lineno == b.end_lineno &&
     162   [ +  +  +  + ]:     719666 :            a.col_offset == b.col_offset &&
     163         [ +  + ]:     124660 :            a.end_col_offset == b.end_col_offset;
     164                 :            : }
     165                 :            : 
     166                 :            : #define LOC(x) SRC_LOCATION_FROM_AST(x)
     167                 :            : 
     168                 :            : typedef struct jump_target_label_ {
     169                 :            :     int id;
     170                 :            : } jump_target_label;
     171                 :            : 
     172                 :            : static struct jump_target_label_ NO_LABEL = {-1};
     173                 :            : 
     174                 :            : #define SAME_LABEL(L1, L2) ((L1).id == (L2).id)
     175                 :            : #define IS_LABEL(L) (!SAME_LABEL((L), (NO_LABEL)))
     176                 :            : 
     177                 :            : #define NEW_JUMP_TARGET_LABEL(C, NAME) \
     178                 :            :     jump_target_label NAME = instr_sequence_new_label(INSTR_SEQUENCE(C)); \
     179                 :            :     if (!IS_LABEL(NAME)) { \
     180                 :            :         return ERROR; \
     181                 :            :     }
     182                 :            : 
     183                 :            : #define USE_LABEL(C, LBL) \
     184                 :            :     RETURN_IF_ERROR(instr_sequence_use_label(INSTR_SEQUENCE(C), (LBL).id))
     185                 :            : 
     186                 :            : struct cfg_instr {
     187                 :            :     int i_opcode;
     188                 :            :     int i_oparg;
     189                 :            :     location i_loc;
     190                 :            :     struct basicblock_ *i_target; /* target block (if jump instruction) */
     191                 :            :     struct basicblock_ *i_except; /* target block when exception is raised */
     192                 :            : };
     193                 :            : 
     194                 :            : /* One arg*/
     195                 :            : #define INSTR_SET_OP1(I, OP, ARG) \
     196                 :            :     do { \
     197                 :            :         assert(HAS_ARG(OP)); \
     198                 :            :         struct cfg_instr *_instr__ptr_ = (I); \
     199                 :            :         _instr__ptr_->i_opcode = (OP); \
     200                 :            :         _instr__ptr_->i_oparg = (ARG); \
     201                 :            :     } while (0);
     202                 :            : 
     203                 :            : /* No args*/
     204                 :            : #define INSTR_SET_OP0(I, OP) \
     205                 :            :     do { \
     206                 :            :         assert(!HAS_ARG(OP)); \
     207                 :            :         struct cfg_instr *_instr__ptr_ = (I); \
     208                 :            :         _instr__ptr_->i_opcode = (OP); \
     209                 :            :         _instr__ptr_->i_oparg = 0; \
     210                 :            :     } while (0);
     211                 :            : 
     212                 :            : typedef struct exceptstack {
     213                 :            :     struct basicblock_ *handlers[CO_MAXBLOCKS+1];
     214                 :            :     int depth;
     215                 :            : } ExceptStack;
     216                 :            : 
     217                 :            : #define LOG_BITS_PER_INT 5
     218                 :            : #define MASK_LOW_LOG_BITS 31
     219                 :            : 
     220                 :            : static inline int
     221                 :    4262278 : is_bit_set_in_table(const uint32_t *table, int bitindex) {
     222                 :            :     /* Is the relevant bit set in the relevant word? */
     223                 :            :     /* 512 bits fit into 9 32-bits words.
     224                 :            :      * Word is indexed by (bitindex>>ln(size of int in bits)).
     225                 :            :      * Bit within word is the low bits of bitindex.
     226                 :            :      */
     227   [ +  -  +  - ]:    4262278 :     if (bitindex >= 0 && bitindex < 512) {
     228                 :    4262278 :         uint32_t word = table[bitindex >> LOG_BITS_PER_INT];
     229                 :    4262278 :         return (word >> (bitindex & MASK_LOW_LOG_BITS)) & 1;
     230                 :            :     }
     231                 :            :     else {
     232                 :          0 :         return 0;
     233                 :            :     }
     234                 :            : }
     235                 :            : 
     236                 :            : static inline int
     237                 :      26506 : is_relative_jump(struct cfg_instr *i)
     238                 :            : {
     239                 :      26506 :     return is_bit_set_in_table(_PyOpcode_RelativeJump, i->i_opcode);
     240                 :            : }
     241                 :            : 
     242                 :            : static inline int
     243                 :    1431493 : is_block_push(struct cfg_instr *i)
     244                 :            : {
     245   [ +  +  +  +  :    1431493 :     return IS_BLOCK_PUSH_OPCODE(i->i_opcode);
                   +  + ]
     246                 :            : }
     247                 :            : 
     248                 :            : static inline int
     249                 :    1621642 : is_jump(struct cfg_instr *i)
     250                 :            : {
     251                 :    1621642 :     return IS_JUMP_OPCODE(i->i_opcode);
     252                 :            : }
     253                 :            : 
     254                 :            : static int
     255                 :    1860948 : instr_size(struct cfg_instr *instruction)
     256                 :            : {
     257                 :    1860948 :     int opcode = instruction->i_opcode;
     258                 :            :     assert(!IS_PSEUDO_OPCODE(opcode));
     259                 :    1860948 :     int oparg = instruction->i_oparg;
     260                 :            :     assert(HAS_ARG(opcode) || oparg == 0);
     261                 :    1860948 :     int extended_args = (0xFFFFFF < oparg) + (0xFFFF < oparg) + (0xFF < oparg);
     262                 :    1860948 :     int caches = _PyOpcode_Caches[opcode];
     263                 :    1860948 :     return extended_args + 1 + caches;
     264                 :            : }
     265                 :            : 
     266                 :            : static void
     267                 :     342036 : write_instr(_Py_CODEUNIT *codestr, struct cfg_instr *instruction, int ilen)
     268                 :            : {
     269                 :     342036 :     int opcode = instruction->i_opcode;
     270                 :            :     assert(!IS_PSEUDO_OPCODE(opcode));
     271                 :     342036 :     int oparg = instruction->i_oparg;
     272                 :            :     assert(HAS_ARG(opcode) || oparg == 0);
     273                 :     342036 :     int caches = _PyOpcode_Caches[opcode];
     274   [ -  -  +  +  :     342036 :     switch (ilen - caches) {
                      - ]
     275                 :          0 :         case 4:
     276                 :          0 :             codestr->op.code = EXTENDED_ARG;
     277                 :          0 :             codestr->op.arg = (oparg >> 24) & 0xFF;
     278                 :          0 :             codestr++;
     279                 :            :             /* fall through */
     280                 :          0 :         case 3:
     281                 :          0 :             codestr->op.code = EXTENDED_ARG;
     282                 :          0 :             codestr->op.arg = (oparg >> 16) & 0xFF;
     283                 :          0 :             codestr++;
     284                 :            :             /* fall through */
     285                 :       3324 :         case 2:
     286                 :       3324 :             codestr->op.code = EXTENDED_ARG;
     287                 :       3324 :             codestr->op.arg = (oparg >> 8) & 0xFF;
     288                 :       3324 :             codestr++;
     289                 :            :             /* fall through */
     290                 :     342036 :         case 1:
     291                 :     342036 :             codestr->op.code = opcode;
     292                 :     342036 :             codestr->op.arg = oparg & 0xFF;
     293                 :     342036 :             codestr++;
     294                 :     342036 :             break;
     295                 :          0 :         default:
     296                 :          0 :             Py_UNREACHABLE();
     297                 :            :     }
     298         [ +  + ]:     815594 :     while (caches--) {
     299                 :     473558 :         codestr->op.code = CACHE;
     300                 :     473558 :         codestr->op.arg = 0;
     301                 :     473558 :         codestr++;
     302                 :            :     }
     303                 :     342036 : }
     304                 :            : 
     305                 :            : typedef struct basicblock_ {
     306                 :            :     /* Each basicblock in a compilation unit is linked via b_list in the
     307                 :            :        reverse order that the block are allocated.  b_list points to the next
     308                 :            :        block, not to be confused with b_next, which is next by control flow. */
     309                 :            :     struct basicblock_ *b_list;
     310                 :            :     /* The label of this block if it is a jump target, -1 otherwise */
     311                 :            :     jump_target_label b_label;
     312                 :            :     /* Exception stack at start of block, used by assembler to create the exception handling table */
     313                 :            :     ExceptStack *b_exceptstack;
     314                 :            :     /* pointer to an array of instructions, initially NULL */
     315                 :            :     struct cfg_instr *b_instr;
     316                 :            :     /* If b_next is non-NULL, it is a pointer to the next
     317                 :            :        block reached by normal control flow. */
     318                 :            :     struct basicblock_ *b_next;
     319                 :            :     /* number of instructions used */
     320                 :            :     int b_iused;
     321                 :            :     /* length of instruction array (b_instr) */
     322                 :            :     int b_ialloc;
     323                 :            :     /* Used by add_checks_for_loads_of_unknown_variables */
     324                 :            :     uint64_t b_unsafe_locals_mask;
     325                 :            :     /* Number of predecessors that a block has. */
     326                 :            :     int b_predecessors;
     327                 :            :     /* depth of stack upon entry of block, computed by stackdepth() */
     328                 :            :     int b_startdepth;
     329                 :            :     /* instruction offset for block, computed by assemble_jump_offsets() */
     330                 :            :     int b_offset;
     331                 :            :     /* Basic block is an exception handler that preserves lasti */
     332                 :            :     unsigned b_preserve_lasti : 1;
     333                 :            :     /* Used by compiler passes to mark whether they have visited a basic block. */
     334                 :            :     unsigned b_visited : 1;
     335                 :            :     /* b_except_handler is used by the cold-detection algorithm to mark exception targets */
     336                 :            :     unsigned b_except_handler : 1;
     337                 :            :     /* b_cold is true if this block is not perf critical (like an exception handler) */
     338                 :            :     unsigned b_cold : 1;
     339                 :            :     /* b_warm is used by the cold-detection algorithm to mark blocks which are definitely not cold */
     340                 :            :     unsigned b_warm : 1;
     341                 :            : } basicblock;
     342                 :            : 
     343                 :            : 
     344                 :            : static struct cfg_instr *
     345                 :    1316809 : basicblock_last_instr(const basicblock *b) {
     346                 :            :     assert(b->b_iused >= 0);
     347         [ +  + ]:    1316809 :     if (b->b_iused > 0) {
     348                 :            :         assert(b->b_instr != NULL);
     349                 :    1272680 :         return &b->b_instr[b->b_iused - 1];
     350                 :            :     }
     351                 :      44129 :     return NULL;
     352                 :            : }
     353                 :            : 
     354                 :            : static inline int
     355                 :      65096 : basicblock_exits_scope(const basicblock *b) {
     356                 :      65096 :     struct cfg_instr *last = basicblock_last_instr(b);
     357   [ +  -  +  +  :      65096 :     return last && IS_SCOPE_EXIT_OPCODE(last->i_opcode);
          +  +  +  +  +  
                      + ]
     358                 :            : }
     359                 :            : 
     360                 :            : static inline int
     361                 :     347556 : basicblock_nofallthrough(const basicblock *b) {
     362                 :     347556 :     struct cfg_instr *last = basicblock_last_instr(b);
     363         [ +  + ]:     692674 :     return (last &&
     364   [ +  +  +  +  :     345118 :             (IS_SCOPE_EXIT_OPCODE(last->i_opcode) ||
             +  +  +  + ]
     365   [ +  +  +  +  :     247926 :              IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)));
          +  -  +  -  -  
                      + ]
     366                 :            : }
     367                 :            : 
     368                 :            : #define BB_NO_FALLTHROUGH(B) (basicblock_nofallthrough(B))
     369                 :            : #define BB_HAS_FALLTHROUGH(B) (!basicblock_nofallthrough(B))
     370                 :            : 
     371                 :            : /* fblockinfo tracks the current frame block.
     372                 :            : 
     373                 :            : A frame block is used to handle loops, try/except, and try/finally.
     374                 :            : It's called a frame block to distinguish it from a basic block in the
     375                 :            : compiler IR.
     376                 :            : */
     377                 :            : 
     378                 :            : enum fblocktype { WHILE_LOOP, FOR_LOOP, TRY_EXCEPT, FINALLY_TRY, FINALLY_END,
     379                 :            :                   WITH, ASYNC_WITH, HANDLER_CLEANUP, POP_VALUE, EXCEPTION_HANDLER,
     380                 :            :                   EXCEPTION_GROUP_HANDLER, ASYNC_COMPREHENSION_GENERATOR };
     381                 :            : 
     382                 :            : struct fblockinfo {
     383                 :            :     enum fblocktype fb_type;
     384                 :            :     jump_target_label fb_block;
     385                 :            :     /* (optional) type-specific exit or cleanup block */
     386                 :            :     jump_target_label fb_exit;
     387                 :            :     /* (optional) additional information required for unwinding */
     388                 :            :     void *fb_datum;
     389                 :            : };
     390                 :            : 
     391                 :            : enum {
     392                 :            :     COMPILER_SCOPE_MODULE,
     393                 :            :     COMPILER_SCOPE_CLASS,
     394                 :            :     COMPILER_SCOPE_FUNCTION,
     395                 :            :     COMPILER_SCOPE_ASYNC_FUNCTION,
     396                 :            :     COMPILER_SCOPE_LAMBDA,
     397                 :            :     COMPILER_SCOPE_COMPREHENSION,
     398                 :            : };
     399                 :            : 
     400                 :            : typedef struct cfg_builder_ {
     401                 :            :     /* The entryblock, at which control flow begins. All blocks of the
     402                 :            :        CFG are reachable through the b_next links */
     403                 :            :     basicblock *g_entryblock;
     404                 :            :     /* Pointer to the most recently allocated block.  By following
     405                 :            :        b_list links, you can reach all allocated blocks. */
     406                 :            :     basicblock *g_block_list;
     407                 :            :     /* pointer to the block currently being constructed */
     408                 :            :     basicblock *g_curblock;
     409                 :            :     /* label for the next instruction to be placed */
     410                 :            :     jump_target_label g_current_label;
     411                 :            : } cfg_builder;
     412                 :            : 
     413                 :            : typedef struct {
     414                 :            :     int i_opcode;
     415                 :            :     int i_oparg;
     416                 :            :     location i_loc;
     417                 :            : } instruction;
     418                 :            : 
     419                 :            : 
     420                 :            : typedef struct instr_sequence_ {
     421                 :            :     instruction *s_instrs;
     422                 :            :     int s_allocated;
     423                 :            :     int s_used;
     424                 :            : 
     425                 :            :     int *s_labelmap;       /* label id --> instr offset */
     426                 :            :     int s_labelmap_size;
     427                 :            :     int s_next_free_label; /* next free label id */
     428                 :            : } instr_sequence;
     429                 :            : 
     430                 :            : #define INITIAL_INSTR_SEQUENCE_SIZE 100
     431                 :            : #define INITIAL_INSTR_SEQUENCE_LABELS_MAP_SIZE 10
     432                 :            : 
     433                 :            : /*
     434                 :            :  * Resize the array if index is out of range.
     435                 :            :  *
     436                 :            :  * idx: the index we want to access
     437                 :            :  * arr: pointer to the array
     438                 :            :  * alloc: pointer to the capacity of the array
     439                 :            :  * default_alloc: initial number of items
     440                 :            :  * item_size: size of each item
     441                 :            :  *
     442                 :            :  */
     443                 :            : static int
     444                 :     815334 : ensure_array_large_enough(int idx, void **arr_, int *alloc, int default_alloc, size_t item_size)
     445                 :            : {
     446                 :     815334 :     void *arr = *arr_;
     447         [ +  + ]:     815334 :     if (arr == NULL) {
     448                 :      72673 :         int new_alloc = default_alloc;
     449         [ -  + ]:      72673 :         if (idx >= new_alloc) {
     450                 :          0 :             new_alloc = idx + default_alloc;
     451                 :            :         }
     452                 :      72673 :         arr = PyObject_Calloc(new_alloc, item_size);
     453         [ -  + ]:      72673 :         if (arr == NULL) {
     454                 :          0 :             PyErr_NoMemory();
     455                 :          0 :             return ERROR;
     456                 :            :         }
     457                 :      72673 :         *alloc = new_alloc;
     458                 :            :     }
     459         [ +  + ]:     742661 :     else if (idx >= *alloc) {
     460                 :       8183 :         size_t oldsize = *alloc * item_size;
     461                 :       8183 :         int new_alloc = *alloc << 1;
     462         [ -  + ]:       8183 :         if (idx >= new_alloc) {
     463                 :          0 :             new_alloc = idx + default_alloc;
     464                 :            :         }
     465                 :       8183 :         size_t newsize = new_alloc * item_size;
     466                 :            : 
     467         [ -  + ]:       8183 :         if (oldsize > (SIZE_MAX >> 1)) {
     468                 :          0 :             PyErr_NoMemory();
     469                 :          0 :             return ERROR;
     470                 :            :         }
     471                 :            : 
     472                 :            :         assert(newsize > 0);
     473                 :       8183 :         void *tmp = PyObject_Realloc(arr, newsize);
     474         [ -  + ]:       8183 :         if (tmp == NULL) {
     475                 :          0 :             PyErr_NoMemory();
     476                 :          0 :             return ERROR;
     477                 :            :         }
     478                 :       8183 :         *alloc = new_alloc;
     479                 :       8183 :         arr = tmp;
     480                 :       8183 :         memset((char *)arr + oldsize, 0, newsize - oldsize);
     481                 :            :     }
     482                 :            : 
     483                 :     815334 :     *arr_ = arr;
     484                 :     815334 :     return SUCCESS;
     485                 :            : }
     486                 :            : 
     487                 :            : static int
     488                 :     386612 : instr_sequence_next_inst(instr_sequence *seq) {
     489                 :            :     assert(seq->s_instrs != NULL || seq->s_used == 0);
     490                 :            : 
     491         [ -  + ]:     386612 :     RETURN_IF_ERROR(
     492                 :            :         ensure_array_large_enough(seq->s_used + 1,
     493                 :            :                                   (void**)&seq->s_instrs,
     494                 :            :                                   &seq->s_allocated,
     495                 :            :                                   INITIAL_INSTR_SEQUENCE_SIZE,
     496                 :            :                                   sizeof(instruction)));
     497                 :            :     assert(seq->s_used < seq->s_allocated);
     498                 :     386612 :     return seq->s_used++;
     499                 :            : }
     500                 :            : 
     501                 :            : static jump_target_label
     502                 :      33597 : instr_sequence_new_label(instr_sequence *seq)
     503                 :            : {
     504                 :      33597 :     jump_target_label lbl = {++seq->s_next_free_label};
     505                 :      33597 :     return lbl;
     506                 :            : }
     507                 :            : 
     508                 :            : static int
     509                 :      33597 : instr_sequence_use_label(instr_sequence *seq, int lbl) {
     510                 :      33597 :     int old_size = seq->s_labelmap_size;
     511         [ -  + ]:      33597 :     RETURN_IF_ERROR(
     512                 :            :         ensure_array_large_enough(lbl,
     513                 :            :                                   (void**)&seq->s_labelmap,
     514                 :            :                                   &seq->s_labelmap_size,
     515                 :            :                                   INITIAL_INSTR_SEQUENCE_LABELS_MAP_SIZE,
     516                 :            :                                   sizeof(int)));
     517                 :            : 
     518         [ +  + ]:      97907 :     for(int i = old_size; i < seq->s_labelmap_size; i++) {
     519                 :      64310 :         seq->s_labelmap[i] = -111;  /* something weird, for debugging */
     520                 :            :     }
     521                 :      33597 :     seq->s_labelmap[lbl] = seq->s_used; /* label refers to the next instruction */
     522                 :      33597 :     return SUCCESS;
     523                 :            : }
     524                 :            : 
     525                 :            : static int
     526                 :     386082 : instr_sequence_addop(instr_sequence *seq, int opcode, int oparg, location loc)
     527                 :            : {
     528                 :            :     assert(IS_WITHIN_OPCODE_RANGE(opcode));
     529                 :            :     assert(!IS_ASSEMBLER_OPCODE(opcode));
     530                 :            :     assert(HAS_ARG(opcode) || HAS_TARGET(opcode) || oparg == 0);
     531                 :            :     assert(0 <= oparg && oparg < (1 << 30));
     532                 :            : 
     533                 :     386082 :     int idx = instr_sequence_next_inst(seq);
     534         [ -  + ]:     386082 :     RETURN_IF_ERROR(idx);
     535                 :     386082 :     instruction *ci = &seq->s_instrs[idx];
     536                 :     386082 :     ci->i_opcode = opcode;
     537                 :     386082 :     ci->i_oparg = oparg;
     538                 :     386082 :     ci->i_loc = loc;
     539                 :     386082 :     return SUCCESS;
     540                 :            : }
     541                 :            : 
     542                 :            : static int
     543                 :        530 : instr_sequence_insert_instruction(instr_sequence *seq, int pos,
     544                 :            :                                   int opcode, int oparg, location loc)
     545                 :            : {
     546                 :            :     assert(pos >= 0 && pos <= seq->s_used);
     547                 :        530 :     int last_idx = instr_sequence_next_inst(seq);
     548         [ -  + ]:        530 :     RETURN_IF_ERROR(last_idx);
     549         [ +  + ]:      27294 :     for (int i=last_idx-1; i >= pos; i--) {
     550                 :      26764 :         seq->s_instrs[i+1] = seq->s_instrs[i];
     551                 :            :     }
     552                 :        530 :     instruction *ci = &seq->s_instrs[pos];
     553                 :        530 :     ci->i_opcode = opcode;
     554                 :        530 :     ci->i_oparg = oparg;
     555                 :        530 :     ci->i_loc = loc;
     556                 :            : 
     557                 :            :     /* fix the labels map */
     558         [ +  + ]:       8160 :     for(int lbl=0; lbl < seq->s_labelmap_size; lbl++) {
     559         [ +  + ]:       7630 :         if (seq->s_labelmap[lbl] >= pos) {
     560                 :       4243 :             seq->s_labelmap[lbl]++;
     561                 :            :         }
     562                 :            :     }
     563                 :        530 :     return SUCCESS;
     564                 :            : }
     565                 :            : 
     566                 :            : static void
     567                 :       8041 : instr_sequence_fini(instr_sequence *seq) {
     568                 :       8041 :     PyObject_Free(seq->s_labelmap);
     569                 :       8041 :     seq->s_labelmap = NULL;
     570                 :            : 
     571                 :       8041 :     PyObject_Free(seq->s_instrs);
     572                 :       8041 :     seq->s_instrs = NULL;
     573                 :       8041 : }
     574                 :            : 
     575                 :            : static int basicblock_addop(basicblock *b, int opcode, int oparg, location loc);
     576                 :            : static int cfg_builder_maybe_start_new_block(cfg_builder *g);
     577                 :            : 
     578                 :            : static int
     579                 :      33597 : cfg_builder_use_label(cfg_builder *g, jump_target_label lbl)
     580                 :            : {
     581                 :      33597 :     g->g_current_label = lbl;
     582                 :      33597 :     return cfg_builder_maybe_start_new_block(g);
     583                 :            : }
     584                 :            : 
     585                 :            : static int
     586                 :     386612 : cfg_builder_addop(cfg_builder *g, int opcode, int oparg, location loc)
     587                 :            : {
     588         [ -  + ]:     386612 :     RETURN_IF_ERROR(cfg_builder_maybe_start_new_block(g));
     589                 :     386612 :     return basicblock_addop(g->g_curblock, opcode, oparg, loc);
     590                 :            : }
     591                 :            : 
     592                 :            : static int cfg_builder_init(cfg_builder *g);
     593                 :            : 
     594                 :            : static int
     595                 :       8041 : instr_sequence_to_cfg(instr_sequence *seq, cfg_builder *g) {
     596                 :       8041 :     memset(g, 0, sizeof(cfg_builder));
     597         [ -  + ]:       8041 :     RETURN_IF_ERROR(cfg_builder_init(g));
     598                 :            :     /* Note: there can be more than one label for the same offset */
     599         [ +  + ]:     394653 :     for (int i = 0; i < seq->s_used; i++) {
     600         [ +  + ]:   10102672 :         for (int j=0; j < seq->s_labelmap_size; j++) {
     601         [ +  + ]:    9716060 :             if (seq->s_labelmap[j] == i) {
     602                 :      33597 :                 jump_target_label lbl = {j};
     603         [ -  + ]:      33597 :                 RETURN_IF_ERROR(cfg_builder_use_label(g, lbl));
     604                 :            :             }
     605                 :            :         }
     606                 :     386612 :         instruction *instr = &seq->s_instrs[i];
     607         [ -  + ]:     386612 :         RETURN_IF_ERROR(cfg_builder_addop(g, instr->i_opcode, instr->i_oparg, instr->i_loc));
     608                 :            :     }
     609                 :       8041 :     int nblocks = 0;
     610         [ +  + ]:      69608 :     for (basicblock *b = g->g_block_list; b != NULL; b = b->b_list) {
     611                 :      61567 :         nblocks++;
     612                 :            :     }
     613         [ -  + ]:       8041 :     if ((size_t)nblocks > SIZE_MAX / sizeof(basicblock *)) {
     614                 :          0 :         PyErr_NoMemory();
     615                 :          0 :         return ERROR;
     616                 :            :     }
     617                 :       8041 :     return SUCCESS;
     618                 :            : }
     619                 :            : 
     620                 :            : 
     621                 :            : /* The following items change on entry and exit of code blocks.
     622                 :            :    They must be saved and restored when returning to a block.
     623                 :            : */
     624                 :            : struct compiler_unit {
     625                 :            :     PySTEntryObject *u_ste;
     626                 :            : 
     627                 :            :     PyObject *u_name;
     628                 :            :     PyObject *u_qualname;  /* dot-separated qualified name (lazy) */
     629                 :            :     int u_scope_type;
     630                 :            : 
     631                 :            :     /* The following fields are dicts that map objects to
     632                 :            :        the index of them in co_XXX.      The index is used as
     633                 :            :        the argument for opcodes that refer to those collections.
     634                 :            :     */
     635                 :            :     PyObject *u_consts;    /* all constants */
     636                 :            :     PyObject *u_names;     /* all names */
     637                 :            :     PyObject *u_varnames;  /* local variables */
     638                 :            :     PyObject *u_cellvars;  /* cell variables */
     639                 :            :     PyObject *u_freevars;  /* free variables */
     640                 :            : 
     641                 :            :     PyObject *u_private;        /* for private name mangling */
     642                 :            : 
     643                 :            :     Py_ssize_t u_argcount;        /* number of arguments for block */
     644                 :            :     Py_ssize_t u_posonlyargcount;        /* number of positional only arguments for block */
     645                 :            :     Py_ssize_t u_kwonlyargcount; /* number of keyword only arguments for block */
     646                 :            : 
     647                 :            :     instr_sequence u_instr_sequence; /* codegen output */
     648                 :            : 
     649                 :            :     int u_nfblocks;
     650                 :            :     struct fblockinfo u_fblock[CO_MAXBLOCKS];
     651                 :            : 
     652                 :            :     int u_firstlineno; /* the first lineno of the block */
     653                 :            : };
     654                 :            : 
     655                 :            : /* This struct captures the global state of a compilation.
     656                 :            : 
     657                 :            : The u pointer points to the current compilation unit, while units
     658                 :            : for enclosing blocks are stored in c_stack.     The u and c_stack are
     659                 :            : managed by compiler_enter_scope() and compiler_exit_scope().
     660                 :            : 
     661                 :            : Note that we don't track recursion levels during compilation - the
     662                 :            : task of detecting and rejecting excessive levels of nesting is
     663                 :            : handled by the symbol analysis pass.
     664                 :            : 
     665                 :            : */
     666                 :            : 
     667                 :            : struct compiler {
     668                 :            :     PyObject *c_filename;
     669                 :            :     struct symtable *c_st;
     670                 :            :     PyFutureFeatures c_future;   /* module's __future__ */
     671                 :            :     PyCompilerFlags c_flags;
     672                 :            : 
     673                 :            :     int c_optimize;              /* optimization level */
     674                 :            :     int c_interactive;           /* true if in interactive mode */
     675                 :            :     int c_nestlevel;
     676                 :            :     PyObject *c_const_cache;     /* Python dict holding all constants,
     677                 :            :                                     including names tuple */
     678                 :            :     struct compiler_unit *u; /* compiler state for current block */
     679                 :            :     PyObject *c_stack;           /* Python list holding compiler_unit ptrs */
     680                 :            :     PyArena *c_arena;            /* pointer to memory allocation arena */
     681                 :            : };
     682                 :            : 
     683                 :            : #define INSTR_SEQUENCE(C) (&((C)->u->u_instr_sequence))
     684                 :            : 
     685                 :            : 
     686                 :            : typedef struct {
     687                 :            :     // A list of strings corresponding to name captures. It is used to track:
     688                 :            :     // - Repeated name assignments in the same pattern.
     689                 :            :     // - Different name assignments in alternatives.
     690                 :            :     // - The order of name assignments in alternatives.
     691                 :            :     PyObject *stores;
     692                 :            :     // If 0, any name captures against our subject will raise.
     693                 :            :     int allow_irrefutable;
     694                 :            :     // An array of blocks to jump to on failure. Jumping to fail_pop[i] will pop
     695                 :            :     // i items off of the stack. The end result looks like this (with each block
     696                 :            :     // falling through to the next):
     697                 :            :     // fail_pop[4]: POP_TOP
     698                 :            :     // fail_pop[3]: POP_TOP
     699                 :            :     // fail_pop[2]: POP_TOP
     700                 :            :     // fail_pop[1]: POP_TOP
     701                 :            :     // fail_pop[0]: NOP
     702                 :            :     jump_target_label *fail_pop;
     703                 :            :     // The current length of fail_pop.
     704                 :            :     Py_ssize_t fail_pop_size;
     705                 :            :     // The number of items on top of the stack that need to *stay* on top of the
     706                 :            :     // stack. Variable captures go beneath these. All of them will be popped on
     707                 :            :     // failure.
     708                 :            :     Py_ssize_t on_top;
     709                 :            : } pattern_context;
     710                 :            : 
     711                 :            : static int basicblock_next_instr(basicblock *);
     712                 :            : 
     713                 :            : static int codegen_addop_i(instr_sequence *seq, int opcode, Py_ssize_t oparg, location loc);
     714                 :            : 
     715                 :            : static void compiler_free(struct compiler *);
     716                 :            : static int compiler_error(struct compiler *, location loc, const char *, ...);
     717                 :            : static int compiler_warn(struct compiler *, location loc, const char *, ...);
     718                 :            : static int compiler_nameop(struct compiler *, location, identifier, expr_context_ty);
     719                 :            : 
     720                 :            : static PyCodeObject *compiler_mod(struct compiler *, mod_ty);
     721                 :            : static int compiler_visit_stmt(struct compiler *, stmt_ty);
     722                 :            : static int compiler_visit_keyword(struct compiler *, keyword_ty);
     723                 :            : static int compiler_visit_expr(struct compiler *, expr_ty);
     724                 :            : static int compiler_augassign(struct compiler *, stmt_ty);
     725                 :            : static int compiler_annassign(struct compiler *, stmt_ty);
     726                 :            : static int compiler_subscript(struct compiler *, expr_ty);
     727                 :            : static int compiler_slice(struct compiler *, expr_ty);
     728                 :            : 
     729                 :            : static bool are_all_items_const(asdl_expr_seq *, Py_ssize_t, Py_ssize_t);
     730                 :            : 
     731                 :            : 
     732                 :            : static int compiler_with(struct compiler *, stmt_ty, int);
     733                 :            : static int compiler_async_with(struct compiler *, stmt_ty, int);
     734                 :            : static int compiler_async_for(struct compiler *, stmt_ty);
     735                 :            : static int compiler_call_simple_kw_helper(struct compiler *c,
     736                 :            :                                           location loc,
     737                 :            :                                           asdl_keyword_seq *keywords,
     738                 :            :                                           Py_ssize_t nkwelts);
     739                 :            : static int compiler_call_helper(struct compiler *c, location loc,
     740                 :            :                                 int n, asdl_expr_seq *args,
     741                 :            :                                 asdl_keyword_seq *keywords);
     742                 :            : static int compiler_try_except(struct compiler *, stmt_ty);
     743                 :            : static int compiler_try_star_except(struct compiler *, stmt_ty);
     744                 :            : static int compiler_set_qualname(struct compiler *);
     745                 :            : 
     746                 :            : static int compiler_sync_comprehension_generator(
     747                 :            :                                       struct compiler *c, location loc,
     748                 :            :                                       asdl_comprehension_seq *generators, int gen_index,
     749                 :            :                                       int depth,
     750                 :            :                                       expr_ty elt, expr_ty val, int type);
     751                 :            : 
     752                 :            : static int compiler_async_comprehension_generator(
     753                 :            :                                       struct compiler *c, location loc,
     754                 :            :                                       asdl_comprehension_seq *generators, int gen_index,
     755                 :            :                                       int depth,
     756                 :            :                                       expr_ty elt, expr_ty val, int type);
     757                 :            : 
     758                 :            : static int compiler_pattern(struct compiler *, pattern_ty, pattern_context *);
     759                 :            : static int compiler_match(struct compiler *, stmt_ty);
     760                 :            : static int compiler_pattern_subpattern(struct compiler *,
     761                 :            :                                        pattern_ty, pattern_context *);
     762                 :            : 
     763                 :            : static int remove_redundant_nops(basicblock *bb);
     764                 :            : 
     765                 :            : static PyCodeObject *assemble(struct compiler *, int addNone);
     766                 :            : 
     767                 :            : #define CAPSULE_NAME "compile.c compiler unit"
     768                 :            : 
     769                 :            : 
     770                 :            : static int
     771                 :        319 : compiler_setup(struct compiler *c, mod_ty mod, PyObject *filename,
     772                 :            :                PyCompilerFlags flags, int optimize, PyArena *arena)
     773                 :            : {
     774                 :        319 :     c->c_const_cache = PyDict_New();
     775         [ -  + ]:        319 :     if (!c->c_const_cache) {
     776                 :          0 :         return ERROR;
     777                 :            :     }
     778                 :            : 
     779                 :        319 :     c->c_stack = PyList_New(0);
     780         [ -  + ]:        319 :     if (!c->c_stack) {
     781                 :          0 :         return ERROR;
     782                 :            :     }
     783                 :            : 
     784                 :        319 :     c->c_filename = Py_NewRef(filename);
     785                 :        319 :     c->c_arena = arena;
     786         [ -  + ]:        319 :     if (!_PyFuture_FromAST(mod, filename, &c->c_future)) {
     787                 :          0 :         return ERROR;
     788                 :            :     }
     789                 :        319 :     int merged = c->c_future.ff_features | flags.cf_flags;
     790                 :        319 :     c->c_future.ff_features = merged;
     791                 :        319 :     flags.cf_flags = merged;
     792                 :        319 :     c->c_flags = flags;
     793         [ +  + ]:        319 :     c->c_optimize = (optimize == -1) ? _Py_GetConfig()->optimization_level : optimize;
     794                 :        319 :     c->c_nestlevel = 0;
     795                 :            : 
     796                 :            :     _PyASTOptimizeState state;
     797                 :        319 :     state.optimize = c->c_optimize;
     798                 :        319 :     state.ff_features = merged;
     799                 :            : 
     800         [ -  + ]:        319 :     if (!_PyAST_Optimize(mod, arena, &state)) {
     801                 :          0 :         return ERROR;
     802                 :            :     }
     803                 :        319 :     c->c_st = _PySymtable_Build(mod, filename, &c->c_future);
     804         [ -  + ]:        319 :     if (c->c_st == NULL) {
     805         [ #  # ]:          0 :         if (!PyErr_Occurred()) {
     806                 :          0 :             PyErr_SetString(PyExc_SystemError, "no symtable");
     807                 :            :         }
     808                 :          0 :         return ERROR;
     809                 :            :     }
     810                 :        319 :     return SUCCESS;
     811                 :            : }
     812                 :            : 
     813                 :            : static struct compiler*
     814                 :        319 : new_compiler(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags,
     815                 :            :              int optimize, PyArena *arena)
     816                 :            : {
     817         [ +  + ]:        319 :     PyCompilerFlags flags = pflags ? *pflags : _PyCompilerFlags_INIT;
     818                 :        319 :     struct compiler *c = PyMem_Calloc(1, sizeof(struct compiler));
     819         [ -  + ]:        319 :     if (c == NULL) {
     820                 :          0 :         return NULL;
     821                 :            :     }
     822         [ -  + ]:        319 :     if (compiler_setup(c, mod, filename, flags, optimize, arena) < 0) {
     823                 :          0 :         compiler_free(c);
     824                 :          0 :         return NULL;
     825                 :            :     }
     826                 :        319 :     return c;
     827                 :            : }
     828                 :            : 
     829                 :            : PyCodeObject *
     830                 :        319 : _PyAST_Compile(mod_ty mod, PyObject *filename, PyCompilerFlags *pflags,
     831                 :            :                int optimize, PyArena *arena)
     832                 :            : {
     833                 :        319 :     struct compiler *c = new_compiler(mod, filename, pflags, optimize, arena);
     834         [ -  + ]:        319 :     if (c == NULL) {
     835                 :          0 :         return NULL;
     836                 :            :     }
     837                 :            : 
     838                 :        319 :     PyCodeObject *co = compiler_mod(c, mod);
     839                 :        319 :     compiler_free(c);
     840                 :            :     assert(co || PyErr_Occurred());
     841                 :        319 :     return co;
     842                 :            : }
     843                 :            : 
     844                 :            : static void
     845                 :        319 : compiler_free(struct compiler *c)
     846                 :            : {
     847         [ +  - ]:        319 :     if (c->c_st)
     848                 :        319 :         _PySymtable_Free(c->c_st);
     849                 :        319 :     Py_XDECREF(c->c_filename);
     850                 :        319 :     Py_XDECREF(c->c_const_cache);
     851                 :        319 :     Py_XDECREF(c->c_stack);
     852                 :        319 :     PyMem_Free(c);
     853                 :        319 : }
     854                 :            : 
     855                 :            : static PyObject *
     856                 :       8041 : list2dict(PyObject *list)
     857                 :            : {
     858                 :            :     Py_ssize_t i, n;
     859                 :            :     PyObject *v, *k;
     860                 :       8041 :     PyObject *dict = PyDict_New();
     861         [ -  + ]:       8041 :     if (!dict) return NULL;
     862                 :            : 
     863                 :       8041 :     n = PyList_Size(list);
     864         [ +  + ]:      22014 :     for (i = 0; i < n; i++) {
     865                 :      13973 :         v = PyLong_FromSsize_t(i);
     866         [ -  + ]:      13973 :         if (!v) {
     867                 :          0 :             Py_DECREF(dict);
     868                 :          0 :             return NULL;
     869                 :            :         }
     870                 :      13973 :         k = PyList_GET_ITEM(list, i);
     871         [ -  + ]:      13973 :         if (PyDict_SetItem(dict, k, v) < 0) {
     872                 :          0 :             Py_DECREF(v);
     873                 :          0 :             Py_DECREF(dict);
     874                 :          0 :             return NULL;
     875                 :            :         }
     876                 :      13973 :         Py_DECREF(v);
     877                 :            :     }
     878                 :       8041 :     return dict;
     879                 :            : }
     880                 :            : 
     881                 :            : /* Return new dict containing names from src that match scope(s).
     882                 :            : 
     883                 :            : src is a symbol table dictionary.  If the scope of a name matches
     884                 :            : either scope_type or flag is set, insert it into the new dict.  The
     885                 :            : values are integers, starting at offset and increasing by one for
     886                 :            : each key.
     887                 :            : */
     888                 :            : 
     889                 :            : static PyObject *
     890                 :      16082 : dictbytype(PyObject *src, int scope_type, int flag, Py_ssize_t offset)
     891                 :            : {
     892                 :      16082 :     Py_ssize_t i = offset, scope, num_keys, key_i;
     893                 :      16082 :     PyObject *k, *v, *dest = PyDict_New();
     894                 :            :     PyObject *sorted_keys;
     895                 :            : 
     896                 :            :     assert(offset >= 0);
     897         [ -  + ]:      16082 :     if (dest == NULL)
     898                 :          0 :         return NULL;
     899                 :            : 
     900                 :            :     /* Sort the keys so that we have a deterministic order on the indexes
     901                 :            :        saved in the returned dictionary.  These indexes are used as indexes
     902                 :            :        into the free and cell var storage.  Therefore if they aren't
     903                 :            :        deterministic, then the generated bytecode is not deterministic.
     904                 :            :     */
     905                 :      16082 :     sorted_keys = PyDict_Keys(src);
     906         [ -  + ]:      16082 :     if (sorted_keys == NULL)
     907                 :          0 :         return NULL;
     908         [ -  + ]:      16082 :     if (PyList_Sort(sorted_keys) != 0) {
     909                 :          0 :         Py_DECREF(sorted_keys);
     910                 :          0 :         return NULL;
     911                 :            :     }
     912                 :      16082 :     num_keys = PyList_GET_SIZE(sorted_keys);
     913                 :            : 
     914         [ +  + ]:     118292 :     for (key_i = 0; key_i < num_keys; key_i++) {
     915                 :            :         /* XXX this should probably be a macro in symtable.h */
     916                 :            :         long vi;
     917                 :     102210 :         k = PyList_GET_ITEM(sorted_keys, key_i);
     918                 :     102210 :         v = PyDict_GetItemWithError(src, k);
     919                 :            :         assert(v && PyLong_Check(v));
     920                 :     102210 :         vi = PyLong_AS_LONG(v);
     921                 :     102210 :         scope = (vi >> SCOPE_OFFSET) & SCOPE_MASK;
     922                 :            : 
     923   [ +  +  -  + ]:     102210 :         if (scope == scope_type || vi & flag) {
     924                 :       1525 :             PyObject *item = PyLong_FromSsize_t(i);
     925         [ -  + ]:       1525 :             if (item == NULL) {
     926                 :          0 :                 Py_DECREF(sorted_keys);
     927                 :          0 :                 Py_DECREF(dest);
     928                 :          0 :                 return NULL;
     929                 :            :             }
     930                 :       1525 :             i++;
     931         [ -  + ]:       1525 :             if (PyDict_SetItem(dest, k, item) < 0) {
     932                 :          0 :                 Py_DECREF(sorted_keys);
     933                 :          0 :                 Py_DECREF(item);
     934                 :          0 :                 Py_DECREF(dest);
     935                 :          0 :                 return NULL;
     936                 :            :             }
     937                 :       1525 :             Py_DECREF(item);
     938                 :            :         }
     939                 :            :     }
     940                 :      16082 :     Py_DECREF(sorted_keys);
     941                 :      16082 :     return dest;
     942                 :            : }
     943                 :            : 
     944                 :            : #ifndef NDEBUG
     945                 :            : static bool
     946                 :            : cfg_builder_check(cfg_builder *g)
     947                 :            : {
     948                 :            :     assert(g->g_entryblock->b_iused > 0);
     949                 :            :     for (basicblock *block = g->g_block_list; block != NULL; block = block->b_list) {
     950                 :            :         assert(!_PyMem_IsPtrFreed(block));
     951                 :            :         if (block->b_instr != NULL) {
     952                 :            :             assert(block->b_ialloc > 0);
     953                 :            :             assert(block->b_iused >= 0);
     954                 :            :             assert(block->b_ialloc >= block->b_iused);
     955                 :            :         }
     956                 :            :         else {
     957                 :            :             assert (block->b_iused == 0);
     958                 :            :             assert (block->b_ialloc == 0);
     959                 :            :         }
     960                 :            :     }
     961                 :            :     return true;
     962                 :            : }
     963                 :            : #endif
     964                 :            : 
     965                 :            : static basicblock *cfg_builder_new_block(cfg_builder *g);
     966                 :            : 
     967                 :            : static int
     968                 :       8041 : cfg_builder_init(cfg_builder *g)
     969                 :            : {
     970                 :       8041 :     g->g_block_list = NULL;
     971                 :       8041 :     basicblock *block = cfg_builder_new_block(g);
     972         [ -  + ]:       8041 :     if (block == NULL) {
     973                 :          0 :         return ERROR;
     974                 :            :     }
     975                 :       8041 :     g->g_curblock = g->g_entryblock = block;
     976                 :       8041 :     g->g_current_label = NO_LABEL;
     977                 :       8041 :     return SUCCESS;
     978                 :            : }
     979                 :            : 
     980                 :            : static void
     981                 :       8041 : cfg_builder_fini(cfg_builder* g)
     982                 :            : {
     983                 :            :     assert(cfg_builder_check(g));
     984                 :       8041 :     basicblock *b = g->g_block_list;
     985         [ +  + ]:      71160 :     while (b != NULL) {
     986         [ +  + ]:      63119 :         if (b->b_instr) {
     987                 :      60469 :             PyObject_Free((void *)b->b_instr);
     988                 :            :         }
     989                 :      63119 :         basicblock *next = b->b_list;
     990                 :      63119 :         PyObject_Free((void *)b);
     991                 :      63119 :         b = next;
     992                 :            :     }
     993                 :       8041 : }
     994                 :            : 
     995                 :            : static void
     996                 :       8041 : compiler_unit_free(struct compiler_unit *u)
     997                 :            : {
     998                 :       8041 :     instr_sequence_fini(&u->u_instr_sequence);
     999         [ +  - ]:       8041 :     Py_CLEAR(u->u_ste);
    1000         [ +  - ]:       8041 :     Py_CLEAR(u->u_name);
    1001         [ +  + ]:       8041 :     Py_CLEAR(u->u_qualname);
    1002         [ +  - ]:       8041 :     Py_CLEAR(u->u_consts);
    1003         [ +  - ]:       8041 :     Py_CLEAR(u->u_names);
    1004         [ +  - ]:       8041 :     Py_CLEAR(u->u_varnames);
    1005         [ +  - ]:       8041 :     Py_CLEAR(u->u_freevars);
    1006         [ +  - ]:       8041 :     Py_CLEAR(u->u_cellvars);
    1007         [ +  + ]:       8041 :     Py_CLEAR(u->u_private);
    1008                 :       8041 :     PyObject_Free(u);
    1009                 :       8041 : }
    1010                 :            : 
    1011                 :            : static int
    1012                 :       7722 : compiler_set_qualname(struct compiler *c)
    1013                 :            : {
    1014                 :            :     Py_ssize_t stack_size;
    1015                 :       7722 :     struct compiler_unit *u = c->u;
    1016                 :            :     PyObject *name, *base;
    1017                 :            : 
    1018                 :       7722 :     base = NULL;
    1019                 :       7722 :     stack_size = PyList_GET_SIZE(c->c_stack);
    1020                 :            :     assert(stack_size >= 1);
    1021         [ +  + ]:       7722 :     if (stack_size > 1) {
    1022                 :       4981 :         int scope, force_global = 0;
    1023                 :            :         struct compiler_unit *parent;
    1024                 :            :         PyObject *mangled, *capsule;
    1025                 :            : 
    1026                 :       4981 :         capsule = PyList_GET_ITEM(c->c_stack, stack_size - 1);
    1027                 :       4981 :         parent = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME);
    1028                 :            :         assert(parent);
    1029                 :            : 
    1030         [ +  + ]:       4981 :         if (u->u_scope_type == COMPILER_SCOPE_FUNCTION
    1031         [ +  + ]:        655 :             || u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION
    1032         [ +  + ]:        516 :             || u->u_scope_type == COMPILER_SCOPE_CLASS) {
    1033                 :            :             assert(u->u_name);
    1034                 :       4494 :             mangled = _Py_Mangle(parent->u_private, u->u_name);
    1035         [ -  + ]:       4494 :             if (!mangled) {
    1036                 :          0 :                 return ERROR;
    1037                 :            :             }
    1038                 :            : 
    1039                 :       4494 :             scope = _PyST_GetScope(parent->u_ste, mangled);
    1040                 :       4494 :             Py_DECREF(mangled);
    1041                 :            :             assert(scope != GLOBAL_IMPLICIT);
    1042         [ -  + ]:       4494 :             if (scope == GLOBAL_EXPLICIT)
    1043                 :          0 :                 force_global = 1;
    1044                 :            :         }
    1045                 :            : 
    1046         [ +  - ]:       4981 :         if (!force_global) {
    1047         [ +  + ]:       4981 :             if (parent->u_scope_type == COMPILER_SCOPE_FUNCTION
    1048         [ +  + ]:       4253 :                 || parent->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION
    1049         [ -  + ]:       4229 :                 || parent->u_scope_type == COMPILER_SCOPE_LAMBDA)
    1050                 :            :             {
    1051                 :            :                 _Py_DECLARE_STR(dot_locals, ".<locals>");
    1052                 :        752 :                 base = PyUnicode_Concat(parent->u_qualname,
    1053                 :            :                                         &_Py_STR(dot_locals));
    1054         [ -  + ]:        752 :                 if (base == NULL) {
    1055                 :          0 :                     return ERROR;
    1056                 :            :                 }
    1057                 :            :             }
    1058                 :            :             else {
    1059                 :       4229 :                 base = Py_NewRef(parent->u_qualname);
    1060                 :            :             }
    1061                 :            :         }
    1062                 :            :     }
    1063                 :            : 
    1064         [ +  + ]:       7722 :     if (base != NULL) {
    1065                 :            :         _Py_DECLARE_STR(dot, ".");
    1066                 :       4981 :         name = PyUnicode_Concat(base, &_Py_STR(dot));
    1067                 :       4981 :         Py_DECREF(base);
    1068         [ -  + ]:       4981 :         if (name == NULL) {
    1069                 :          0 :             return ERROR;
    1070                 :            :         }
    1071                 :       4981 :         PyUnicode_Append(&name, u->u_name);
    1072         [ -  + ]:       4981 :         if (name == NULL) {
    1073                 :          0 :             return ERROR;
    1074                 :            :         }
    1075                 :            :     }
    1076                 :            :     else {
    1077                 :       2741 :         name = Py_NewRef(u->u_name);
    1078                 :            :     }
    1079                 :       7722 :     u->u_qualname = name;
    1080                 :            : 
    1081                 :       7722 :     return SUCCESS;
    1082                 :            : }
    1083                 :            : 
    1084                 :            : /* Allocate a new block and return a pointer to it.
    1085                 :            :    Returns NULL on error.
    1086                 :            : */
    1087                 :            : static basicblock *
    1088                 :      63119 : cfg_builder_new_block(cfg_builder *g)
    1089                 :            : {
    1090                 :      63119 :     basicblock *b = (basicblock *)PyObject_Calloc(1, sizeof(basicblock));
    1091         [ -  + ]:      63119 :     if (b == NULL) {
    1092                 :          0 :         PyErr_NoMemory();
    1093                 :          0 :         return NULL;
    1094                 :            :     }
    1095                 :            :     /* Extend the singly linked list of blocks with new block. */
    1096                 :      63119 :     b->b_list = g->g_block_list;
    1097                 :      63119 :     g->g_block_list = b;
    1098                 :      63119 :     b->b_label = NO_LABEL;
    1099                 :      63119 :     return b;
    1100                 :            : }
    1101                 :            : 
    1102                 :            : static basicblock *
    1103                 :      53526 : cfg_builder_use_next_block(cfg_builder *g, basicblock *block)
    1104                 :            : {
    1105                 :            :     assert(block != NULL);
    1106                 :      53526 :     g->g_curblock->b_next = block;
    1107                 :      53526 :     g->g_curblock = block;
    1108                 :      53526 :     return block;
    1109                 :            : }
    1110                 :            : 
    1111                 :            : static inline int
    1112                 :       2669 : basicblock_append_instructions(basicblock *target, basicblock *source)
    1113                 :            : {
    1114         [ +  + ]:       7754 :     for (int i = 0; i < source->b_iused; i++) {
    1115                 :       5085 :         int n = basicblock_next_instr(target);
    1116         [ -  + ]:       5085 :         if (n < 0) {
    1117                 :          0 :             return ERROR;
    1118                 :            :         }
    1119                 :       5085 :         target->b_instr[n] = source->b_instr[i];
    1120                 :            :     }
    1121                 :       2669 :     return SUCCESS;
    1122                 :            : }
    1123                 :            : 
    1124                 :            : static basicblock *
    1125                 :        514 : copy_basicblock(cfg_builder *g, basicblock *block)
    1126                 :            : {
    1127                 :            :     /* Cannot copy a block if it has a fallthrough, since
    1128                 :            :      * a block can only have one fallthrough predecessor.
    1129                 :            :      */
    1130                 :            :     assert(BB_NO_FALLTHROUGH(block));
    1131                 :        514 :     basicblock *result = cfg_builder_new_block(g);
    1132         [ -  + ]:        514 :     if (result == NULL) {
    1133                 :          0 :         return NULL;
    1134                 :            :     }
    1135         [ -  + ]:        514 :     if (basicblock_append_instructions(result, block) < 0) {
    1136                 :          0 :         return NULL;
    1137                 :            :     }
    1138                 :        514 :     return result;
    1139                 :            : }
    1140                 :            : 
    1141                 :            : /* Returns the offset of the next instruction in the current block's
    1142                 :            :    b_instr array.  Resizes the b_instr as necessary.
    1143                 :            :    Returns -1 on failure.
    1144                 :            : */
    1145                 :            : 
    1146                 :            : static int
    1147                 :     395125 : basicblock_next_instr(basicblock *b)
    1148                 :            : {
    1149                 :            :     assert(b != NULL);
    1150                 :            : 
    1151         [ -  + ]:     395125 :     RETURN_IF_ERROR(
    1152                 :            :         ensure_array_large_enough(
    1153                 :            :             b->b_iused + 1,
    1154                 :            :             (void**)&b->b_instr,
    1155                 :            :             &b->b_ialloc,
    1156                 :            :             DEFAULT_BLOCK_SIZE,
    1157                 :            :             sizeof(struct cfg_instr)));
    1158                 :            : 
    1159                 :     395125 :     return b->b_iused++;
    1160                 :            : }
    1161                 :            : 
    1162                 :            : 
    1163                 :            : /* Return the stack effect of opcode with argument oparg.
    1164                 :            : 
    1165                 :            :    Some opcodes have different stack effect when jump to the target and
    1166                 :            :    when not jump. The 'jump' parameter specifies the case:
    1167                 :            : 
    1168                 :            :    * 0 -- when not jump
    1169                 :            :    * 1 -- when jump
    1170                 :            :    * -1 -- maximal
    1171                 :            :  */
    1172                 :            : static int
    1173                 :     374600 : stack_effect(int opcode, int oparg, int jump)
    1174                 :            : {
    1175   [ +  -  +  + ]:     374600 :     if (0 <= opcode && opcode <= MAX_REAL_OPCODE) {
    1176         [ -  + ]:     351088 :         if (_PyOpcode_Deopt[opcode] != opcode) {
    1177                 :            :             // Specialized instructions are not supported.
    1178                 :          0 :             return PY_INVALID_STACK_EFFECT;
    1179                 :            :         }
    1180                 :            :         int popped, pushed;
    1181         [ +  + ]:     351088 :         if (jump > 0) {
    1182                 :      15669 :             popped = _PyOpcode_num_popped(opcode, oparg, true);
    1183                 :      15669 :             pushed = _PyOpcode_num_pushed(opcode, oparg, true);
    1184                 :            :         }
    1185                 :            :         else {
    1186                 :     335419 :             popped = _PyOpcode_num_popped(opcode, oparg, false);
    1187                 :     335419 :             pushed = _PyOpcode_num_pushed(opcode, oparg, false);
    1188                 :            :         }
    1189   [ +  -  -  + ]:     351088 :         if (popped < 0 || pushed < 0) {
    1190                 :          0 :             return PY_INVALID_STACK_EFFECT;
    1191                 :            :         }
    1192         [ +  - ]:     351088 :         if (jump >= 0) {
    1193                 :     351088 :             return pushed - popped;
    1194                 :            :         }
    1195         [ #  # ]:          0 :         if (jump < 0) {
    1196                 :            :             // Compute max(pushed - popped, alt_pushed - alt_popped)
    1197                 :          0 :             int alt_popped = _PyOpcode_num_popped(opcode, oparg, true);
    1198                 :          0 :             int alt_pushed = _PyOpcode_num_pushed(opcode, oparg, true);
    1199   [ #  #  #  # ]:          0 :             if (alt_popped < 0 || alt_pushed < 0) {
    1200                 :          0 :                 return PY_INVALID_STACK_EFFECT;
    1201                 :            :             }
    1202                 :          0 :             int diff = pushed - popped;
    1203                 :          0 :             int alt_diff = alt_pushed - alt_popped;
    1204         [ #  # ]:          0 :             if (alt_diff > diff) {
    1205                 :          0 :                 return alt_diff;
    1206                 :            :             }
    1207                 :          0 :             return diff;
    1208                 :            :         }
    1209                 :            :     }
    1210                 :            : 
    1211                 :            :     // Pseudo ops
    1212   [ +  +  +  +  :      23512 :     switch (opcode) {
                   -  - ]
    1213                 :      14050 :         case POP_BLOCK:
    1214                 :            :         case JUMP:
    1215                 :            :         case JUMP_NO_INTERRUPT:
    1216                 :      14050 :             return 0;
    1217                 :            : 
    1218                 :            :         /* Exception handling pseudo-instructions */
    1219                 :       3352 :         case SETUP_FINALLY:
    1220                 :            :             /* 0 in the normal flow.
    1221                 :            :              * Restore the stack position and push 1 value before jumping to
    1222                 :            :              * the handler if an exception be raised. */
    1223                 :       3352 :             return jump ? 1 : 0;
    1224                 :       5332 :         case SETUP_CLEANUP:
    1225                 :            :             /* As SETUP_FINALLY, but pushes lasti as well */
    1226         [ +  + ]:       5332 :             return jump ? 2 : 0;
    1227                 :        778 :         case SETUP_WITH:
    1228                 :            :             /* 0 in the normal flow.
    1229                 :            :              * Restore the stack position to the position before the result
    1230                 :            :              * of __(a)enter__ and push 2 values before jumping to the handler
    1231                 :            :              * if an exception be raised. */
    1232                 :        778 :             return jump ? 1 : 0;
    1233                 :            : 
    1234                 :          0 :         case LOAD_METHOD:
    1235                 :          0 :             return 1;
    1236                 :          0 :         default:
    1237                 :          0 :             return PY_INVALID_STACK_EFFECT;
    1238                 :            :     }
    1239                 :            : 
    1240                 :            :     return PY_INVALID_STACK_EFFECT; /* not reachable */
    1241                 :            : }
    1242                 :            : 
    1243                 :            : int
    1244                 :          0 : PyCompile_OpcodeStackEffectWithJump(int opcode, int oparg, int jump)
    1245                 :            : {
    1246                 :          0 :     return stack_effect(opcode, oparg, jump);
    1247                 :            : }
    1248                 :            : 
    1249                 :            : int
    1250                 :          0 : PyCompile_OpcodeStackEffect(int opcode, int oparg)
    1251                 :            : {
    1252                 :          0 :     return stack_effect(opcode, oparg, -1);
    1253                 :            : }
    1254                 :            : 
    1255                 :            : static int
    1256                 :     387650 : basicblock_addop(basicblock *b, int opcode, int oparg, location loc)
    1257                 :            : {
    1258                 :            :     assert(IS_WITHIN_OPCODE_RANGE(opcode));
    1259                 :            :     assert(!IS_ASSEMBLER_OPCODE(opcode));
    1260                 :            :     assert(HAS_ARG(opcode) || HAS_TARGET(opcode) || oparg == 0);
    1261                 :            :     assert(0 <= oparg && oparg < (1 << 30));
    1262                 :            : 
    1263                 :     387650 :     int off = basicblock_next_instr(b);
    1264         [ -  + ]:     387650 :     if (off < 0) {
    1265                 :          0 :         return ERROR;
    1266                 :            :     }
    1267                 :     387650 :     struct cfg_instr *i = &b->b_instr[off];
    1268                 :     387650 :     i->i_opcode = opcode;
    1269                 :     387650 :     i->i_oparg = oparg;
    1270                 :     387650 :     i->i_target = NULL;
    1271                 :     387650 :     i->i_loc = loc;
    1272                 :            : 
    1273                 :     387650 :     return SUCCESS;
    1274                 :            : }
    1275                 :            : 
    1276                 :            : static bool
    1277                 :     420209 : cfg_builder_current_block_is_terminated(cfg_builder *g)
    1278                 :            : {
    1279                 :     420209 :     struct cfg_instr *last = basicblock_last_instr(g->g_curblock);
    1280   [ +  +  +  +  :     420209 :     if (last && IS_TERMINATOR_OPCODE(last->i_opcode)) {
          +  +  +  -  +  
                +  +  + ]
    1281                 :      39002 :         return true;
    1282                 :            :     }
    1283         [ +  + ]:     381207 :     if (IS_LABEL(g->g_current_label)) {
    1284   [ +  +  +  - ]:      14524 :         if (last || IS_LABEL(g->g_curblock->b_label)) {
    1285                 :      14524 :             return true;
    1286                 :            :         }
    1287                 :            :         else {
    1288                 :            :             /* current block is empty, label it */
    1289                 :          0 :             g->g_curblock->b_label = g->g_current_label;
    1290                 :          0 :             g->g_current_label = NO_LABEL;
    1291                 :            :         }
    1292                 :            :     }
    1293                 :     366683 :     return false;
    1294                 :            : }
    1295                 :            : 
    1296                 :            : static int
    1297                 :     420209 : cfg_builder_maybe_start_new_block(cfg_builder *g)
    1298                 :            : {
    1299         [ +  + ]:     420209 :     if (cfg_builder_current_block_is_terminated(g)) {
    1300                 :      53526 :         basicblock *b = cfg_builder_new_block(g);
    1301         [ -  + ]:      53526 :         if (b == NULL) {
    1302                 :          0 :             return ERROR;
    1303                 :            :         }
    1304                 :      53526 :         b->b_label = g->g_current_label;
    1305                 :      53526 :         g->g_current_label = NO_LABEL;
    1306                 :      53526 :         cfg_builder_use_next_block(g, b);
    1307                 :            :     }
    1308                 :     420209 :     return SUCCESS;
    1309                 :            : }
    1310                 :            : 
    1311                 :            : static int
    1312                 :      67751 : codegen_addop_noarg(instr_sequence *seq, int opcode, location loc)
    1313                 :            : {
    1314                 :            :     assert(!HAS_ARG(opcode));
    1315                 :      67751 :     return instr_sequence_addop(seq, opcode, 0, loc);
    1316                 :            : }
    1317                 :            : 
    1318                 :            : static Py_ssize_t
    1319                 :     213543 : dict_add_o(PyObject *dict, PyObject *o)
    1320                 :            : {
    1321                 :            :     PyObject *v;
    1322                 :            :     Py_ssize_t arg;
    1323                 :            : 
    1324                 :     213543 :     v = PyDict_GetItemWithError(dict, o);
    1325         [ +  + ]:     213543 :     if (!v) {
    1326         [ -  + ]:     102168 :         if (PyErr_Occurred()) {
    1327                 :          0 :             return ERROR;
    1328                 :            :         }
    1329                 :     102168 :         arg = PyDict_GET_SIZE(dict);
    1330                 :     102168 :         v = PyLong_FromSsize_t(arg);
    1331         [ -  + ]:     102168 :         if (!v) {
    1332                 :          0 :             return ERROR;
    1333                 :            :         }
    1334         [ -  + ]:     102168 :         if (PyDict_SetItem(dict, o, v) < 0) {
    1335                 :          0 :             Py_DECREF(v);
    1336                 :          0 :             return ERROR;
    1337                 :            :         }
    1338                 :     102168 :         Py_DECREF(v);
    1339                 :            :     }
    1340                 :            :     else
    1341                 :     111375 :         arg = PyLong_AsLong(v);
    1342                 :     213543 :     return arg;
    1343                 :            : }
    1344                 :            : 
    1345                 :            : // Merge const *o* recursively and return constant key object.
    1346                 :            : static PyObject*
    1347                 :      72196 : merge_consts_recursive(PyObject *const_cache, PyObject *o)
    1348                 :            : {
    1349                 :            :     assert(PyDict_CheckExact(const_cache));
    1350                 :            :     // None and Ellipsis are singleton, and key is the singleton.
    1351                 :            :     // No need to merge object and key.
    1352   [ +  +  +  + ]:      72196 :     if (o == Py_None || o == Py_Ellipsis) {
    1353                 :      22062 :         return Py_NewRef(o);
    1354                 :            :     }
    1355                 :            : 
    1356                 :      50134 :     PyObject *key = _PyCode_ConstantKey(o);
    1357         [ -  + ]:      50134 :     if (key == NULL) {
    1358                 :          0 :         return NULL;
    1359                 :            :     }
    1360                 :            : 
    1361                 :            :     // t is borrowed reference
    1362                 :      50134 :     PyObject *t = PyDict_SetDefault(const_cache, key, key);
    1363         [ +  + ]:      50134 :     if (t != key) {
    1364                 :            :         // o is registered in const_cache.  Just use it.
    1365                 :       8159 :         Py_XINCREF(t);
    1366                 :       8159 :         Py_DECREF(key);
    1367                 :       8159 :         return t;
    1368                 :            :     }
    1369                 :            : 
    1370                 :            :     // We registered o in const_cache.
    1371                 :            :     // When o is a tuple or frozenset, we want to merge its
    1372                 :            :     // items too.
    1373         [ +  + ]:      41975 :     if (PyTuple_CheckExact(o)) {
    1374                 :       2102 :         Py_ssize_t len = PyTuple_GET_SIZE(o);
    1375         [ +  + ]:       8890 :         for (Py_ssize_t i = 0; i < len; i++) {
    1376                 :       6788 :             PyObject *item = PyTuple_GET_ITEM(o, i);
    1377                 :       6788 :             PyObject *u = merge_consts_recursive(const_cache, item);
    1378         [ -  + ]:       6788 :             if (u == NULL) {
    1379                 :          0 :                 Py_DECREF(key);
    1380                 :          0 :                 return NULL;
    1381                 :            :             }
    1382                 :            : 
    1383                 :            :             // See _PyCode_ConstantKey()
    1384                 :            :             PyObject *v;  // borrowed
    1385         [ +  + ]:       6788 :             if (PyTuple_CheckExact(u)) {
    1386                 :        416 :                 v = PyTuple_GET_ITEM(u, 1);
    1387                 :            :             }
    1388                 :            :             else {
    1389                 :       6372 :                 v = u;
    1390                 :            :             }
    1391         [ +  + ]:       6788 :             if (v != item) {
    1392                 :        830 :                 PyTuple_SET_ITEM(o, i, Py_NewRef(v));
    1393                 :        830 :                 Py_DECREF(item);
    1394                 :            :             }
    1395                 :            : 
    1396                 :       6788 :             Py_DECREF(u);
    1397                 :            :         }
    1398                 :            :     }
    1399         [ +  + ]:      39873 :     else if (PyFrozenSet_CheckExact(o)) {
    1400                 :            :         // *key* is tuple. And its first item is frozenset of
    1401                 :            :         // constant keys.
    1402                 :            :         // See _PyCode_ConstantKey() for detail.
    1403                 :            :         assert(PyTuple_CheckExact(key));
    1404                 :            :         assert(PyTuple_GET_SIZE(key) == 2);
    1405                 :            : 
    1406                 :         36 :         Py_ssize_t len = PySet_GET_SIZE(o);
    1407         [ -  + ]:         36 :         if (len == 0) {  // empty frozenset should not be re-created.
    1408                 :          0 :             return key;
    1409                 :            :         }
    1410                 :         36 :         PyObject *tuple = PyTuple_New(len);
    1411         [ -  + ]:         36 :         if (tuple == NULL) {
    1412                 :          0 :             Py_DECREF(key);
    1413                 :          0 :             return NULL;
    1414                 :            :         }
    1415                 :         36 :         Py_ssize_t i = 0, pos = 0;
    1416                 :            :         PyObject *item;
    1417                 :            :         Py_hash_t hash;
    1418         [ +  + ]:        160 :         while (_PySet_NextEntry(o, &pos, &item, &hash)) {
    1419                 :        124 :             PyObject *k = merge_consts_recursive(const_cache, item);
    1420         [ -  + ]:        124 :             if (k == NULL) {
    1421                 :          0 :                 Py_DECREF(tuple);
    1422                 :          0 :                 Py_DECREF(key);
    1423                 :          0 :                 return NULL;
    1424                 :            :             }
    1425                 :            :             PyObject *u;
    1426         [ -  + ]:        124 :             if (PyTuple_CheckExact(k)) {
    1427                 :          0 :                 u = Py_NewRef(PyTuple_GET_ITEM(k, 1));
    1428                 :          0 :                 Py_DECREF(k);
    1429                 :            :             }
    1430                 :            :             else {
    1431                 :        124 :                 u = k;
    1432                 :            :             }
    1433                 :        124 :             PyTuple_SET_ITEM(tuple, i, u);  // Steals reference of u.
    1434                 :        124 :             i++;
    1435                 :            :         }
    1436                 :            : 
    1437                 :            :         // Instead of rewriting o, we create new frozenset and embed in the
    1438                 :            :         // key tuple.  Caller should get merged frozenset from the key tuple.
    1439                 :         36 :         PyObject *new = PyFrozenSet_New(tuple);
    1440                 :         36 :         Py_DECREF(tuple);
    1441         [ -  + ]:         36 :         if (new == NULL) {
    1442                 :          0 :             Py_DECREF(key);
    1443                 :          0 :             return NULL;
    1444                 :            :         }
    1445                 :            :         assert(PyTuple_GET_ITEM(key, 1) == o);
    1446                 :         36 :         Py_DECREF(o);
    1447                 :         36 :         PyTuple_SET_ITEM(key, 1, new);
    1448                 :            :     }
    1449                 :            : 
    1450                 :      41975 :     return key;
    1451                 :            : }
    1452                 :            : 
    1453                 :            : static Py_ssize_t
    1454                 :      65284 : compiler_add_const(PyObject *const_cache, struct compiler_unit *u, PyObject *o)
    1455                 :            : {
    1456                 :            :     assert(PyDict_CheckExact(const_cache));
    1457                 :      65284 :     PyObject *key = merge_consts_recursive(const_cache, o);
    1458         [ -  + ]:      65284 :     if (key == NULL) {
    1459                 :          0 :         return ERROR;
    1460                 :            :     }
    1461                 :            : 
    1462                 :      65284 :     Py_ssize_t arg = dict_add_o(u->u_consts, key);
    1463                 :      65284 :     Py_DECREF(key);
    1464                 :      65284 :     return arg;
    1465                 :            : }
    1466                 :            : 
    1467                 :            : static int
    1468                 :      57553 : compiler_addop_load_const(PyObject *const_cache, struct compiler_unit *u, location loc, PyObject *o)
    1469                 :            : {
    1470                 :      57553 :     Py_ssize_t arg = compiler_add_const(const_cache, u, o);
    1471         [ -  + ]:      57553 :     if (arg < 0) {
    1472                 :          0 :         return ERROR;
    1473                 :            :     }
    1474                 :      57553 :     return codegen_addop_i(&u->u_instr_sequence, LOAD_CONST, arg, loc);
    1475                 :            : }
    1476                 :            : 
    1477                 :            : static int
    1478                 :      71669 : compiler_addop_o(struct compiler_unit *u, location loc,
    1479                 :            :                  int opcode, PyObject *dict, PyObject *o)
    1480                 :            : {
    1481                 :      71669 :     Py_ssize_t arg = dict_add_o(dict, o);
    1482         [ -  + ]:      71669 :     if (arg < 0) {
    1483                 :          0 :         return ERROR;
    1484                 :            :     }
    1485                 :      71669 :     return codegen_addop_i(&u->u_instr_sequence, opcode, arg, loc);
    1486                 :            : }
    1487                 :            : 
    1488                 :            : static int
    1489                 :      32372 : compiler_addop_name(struct compiler_unit *u, location loc,
    1490                 :            :                     int opcode, PyObject *dict, PyObject *o)
    1491                 :            : {
    1492                 :      32372 :     PyObject *mangled = _Py_Mangle(u->u_private, o);
    1493         [ -  + ]:      32372 :     if (!mangled) {
    1494                 :          0 :         return ERROR;
    1495                 :            :     }
    1496                 :      32372 :     Py_ssize_t arg = dict_add_o(dict, mangled);
    1497                 :      32372 :     Py_DECREF(mangled);
    1498         [ -  + ]:      32372 :     if (arg < 0) {
    1499                 :          0 :         return ERROR;
    1500                 :            :     }
    1501         [ +  + ]:      32372 :     if (opcode == LOAD_ATTR) {
    1502                 :      16077 :         arg <<= 1;
    1503                 :            :     }
    1504         [ +  + ]:      32372 :     if (opcode == LOAD_METHOD) {
    1505                 :      11010 :         opcode = LOAD_ATTR;
    1506                 :      11010 :         arg <<= 1;
    1507                 :      11010 :         arg |= 1;
    1508                 :            :     }
    1509                 :      32372 :     return codegen_addop_i(&u->u_instr_sequence, opcode, arg, loc);
    1510                 :            : }
    1511                 :            : 
    1512                 :            : /* Add an opcode with an integer argument */
    1513                 :            : static int
    1514                 :     289336 : codegen_addop_i(instr_sequence *seq, int opcode, Py_ssize_t oparg, location loc)
    1515                 :            : {
    1516                 :            :     /* oparg value is unsigned, but a signed C int is usually used to store
    1517                 :            :        it in the C code (like Python/ceval.c).
    1518                 :            : 
    1519                 :            :        Limit to 32-bit signed C int (rather than INT_MAX) for portability.
    1520                 :            : 
    1521                 :            :        The argument of a concrete bytecode instruction is limited to 8-bit.
    1522                 :            :        EXTENDED_ARG is used for 16, 24, and 32-bit arguments. */
    1523                 :            : 
    1524                 :     289336 :     int oparg_ = Py_SAFE_DOWNCAST(oparg, Py_ssize_t, int);
    1525                 :     289336 :     return instr_sequence_addop(seq, opcode, oparg_, loc);
    1526                 :            : }
    1527                 :            : 
    1528                 :            : static int
    1529                 :      28995 : codegen_addop_j(instr_sequence *seq, location loc,
    1530                 :            :                 int opcode, jump_target_label target)
    1531                 :            : {
    1532                 :            :     assert(IS_LABEL(target));
    1533                 :            :     assert(IS_JUMP_OPCODE(opcode) || IS_BLOCK_PUSH_OPCODE(opcode));
    1534                 :      28995 :     return instr_sequence_addop(seq, opcode, target.id, loc);
    1535                 :            : }
    1536                 :            : 
    1537                 :            : #define ADDOP(C, LOC, OP) \
    1538                 :            :     RETURN_IF_ERROR(codegen_addop_noarg(INSTR_SEQUENCE(C), (OP), (LOC)))
    1539                 :            : 
    1540                 :            : #define ADDOP_IN_SCOPE(C, LOC, OP) { \
    1541                 :            :     if (codegen_addop_noarg(INSTR_SEQUENCE(C), (OP), (LOC)) < 0) { \
    1542                 :            :         compiler_exit_scope(C); \
    1543                 :            :         return ERROR; \
    1544                 :            :     } \
    1545                 :            : }
    1546                 :            : 
    1547                 :            : #define ADDOP_LOAD_CONST(C, LOC, O) \
    1548                 :            :     RETURN_IF_ERROR(compiler_addop_load_const((C)->c_const_cache, (C)->u, (LOC), (O)))
    1549                 :            : 
    1550                 :            : /* Same as ADDOP_LOAD_CONST, but steals a reference. */
    1551                 :            : #define ADDOP_LOAD_CONST_NEW(C, LOC, O) { \
    1552                 :            :     PyObject *__new_const = (O); \
    1553                 :            :     if (__new_const == NULL) { \
    1554                 :            :         return ERROR; \
    1555                 :            :     } \
    1556                 :            :     if (compiler_addop_load_const((C)->c_const_cache, (C)->u, (LOC), __new_const) < 0) { \
    1557                 :            :         Py_DECREF(__new_const); \
    1558                 :            :         return ERROR; \
    1559                 :            :     } \
    1560                 :            :     Py_DECREF(__new_const); \
    1561                 :            : }
    1562                 :            : 
    1563                 :            : #define ADDOP_N(C, LOC, OP, O, TYPE) { \
    1564                 :            :     assert(!HAS_CONST(OP)); /* use ADDOP_LOAD_CONST_NEW */ \
    1565                 :            :     if (compiler_addop_o((C)->u, (LOC), (OP), (C)->u->u_ ## TYPE, (O)) < 0) { \
    1566                 :            :         Py_DECREF((O)); \
    1567                 :            :         return ERROR; \
    1568                 :            :     } \
    1569                 :            :     Py_DECREF((O)); \
    1570                 :            : }
    1571                 :            : 
    1572                 :            : #define ADDOP_NAME(C, LOC, OP, O, TYPE) \
    1573                 :            :     RETURN_IF_ERROR(compiler_addop_name((C)->u, (LOC), (OP), (C)->u->u_ ## TYPE, (O)))
    1574                 :            : 
    1575                 :            : #define ADDOP_I(C, LOC, OP, O) \
    1576                 :            :     RETURN_IF_ERROR(codegen_addop_i(INSTR_SEQUENCE(C), (OP), (O), (LOC)))
    1577                 :            : 
    1578                 :            : #define ADDOP_JUMP(C, LOC, OP, O) \
    1579                 :            :     RETURN_IF_ERROR(codegen_addop_j(INSTR_SEQUENCE(C), (LOC), (OP), (O)))
    1580                 :            : 
    1581                 :            : #define ADDOP_COMPARE(C, LOC, CMP) \
    1582                 :            :     RETURN_IF_ERROR(compiler_addcompare((C), (LOC), (cmpop_ty)(CMP)))
    1583                 :            : 
    1584                 :            : #define ADDOP_BINARY(C, LOC, BINOP) \
    1585                 :            :     RETURN_IF_ERROR(addop_binary((C), (LOC), (BINOP), false))
    1586                 :            : 
    1587                 :            : #define ADDOP_INPLACE(C, LOC, BINOP) \
    1588                 :            :     RETURN_IF_ERROR(addop_binary((C), (LOC), (BINOP), true))
    1589                 :            : 
    1590                 :            : #define ADD_YIELD_FROM(C, LOC, await) \
    1591                 :            :     RETURN_IF_ERROR(compiler_add_yield_from((C), (LOC), (await)))
    1592                 :            : 
    1593                 :            : #define POP_EXCEPT_AND_RERAISE(C, LOC) \
    1594                 :            :     RETURN_IF_ERROR(compiler_pop_except_and_reraise((C), (LOC)))
    1595                 :            : 
    1596                 :            : #define ADDOP_YIELD(C, LOC) \
    1597                 :            :     RETURN_IF_ERROR(addop_yield((C), (LOC)))
    1598                 :            : 
    1599                 :            : /* VISIT and VISIT_SEQ takes an ASDL type as their second argument.  They use
    1600                 :            :    the ASDL name to synthesize the name of the C type and the visit function.
    1601                 :            : */
    1602                 :            : 
    1603                 :            : #define VISIT(C, TYPE, V) \
    1604                 :            :     RETURN_IF_ERROR(compiler_visit_ ## TYPE((C), (V)));
    1605                 :            : 
    1606                 :            : #define VISIT_IN_SCOPE(C, TYPE, V) {\
    1607                 :            :     if (compiler_visit_ ## TYPE((C), (V)) < 0) { \
    1608                 :            :         compiler_exit_scope(C); \
    1609                 :            :         return ERROR; \
    1610                 :            :     } \
    1611                 :            : }
    1612                 :            : 
    1613                 :            : #define VISIT_SEQ(C, TYPE, SEQ) { \
    1614                 :            :     int _i; \
    1615                 :            :     asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \
    1616                 :            :     for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \
    1617                 :            :         TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \
    1618                 :            :         RETURN_IF_ERROR(compiler_visit_ ## TYPE((C), elt)); \
    1619                 :            :     } \
    1620                 :            : }
    1621                 :            : 
    1622                 :            : #define VISIT_SEQ_IN_SCOPE(C, TYPE, SEQ) { \
    1623                 :            :     int _i; \
    1624                 :            :     asdl_ ## TYPE ## _seq *seq = (SEQ); /* avoid variable capture */ \
    1625                 :            :     for (_i = 0; _i < asdl_seq_LEN(seq); _i++) { \
    1626                 :            :         TYPE ## _ty elt = (TYPE ## _ty)asdl_seq_GET(seq, _i); \
    1627                 :            :         if (compiler_visit_ ## TYPE((C), elt) < 0) { \
    1628                 :            :             compiler_exit_scope(C); \
    1629                 :            :             return ERROR; \
    1630                 :            :         } \
    1631                 :            :     } \
    1632                 :            : }
    1633                 :            : 
    1634                 :            : 
    1635                 :            : static int
    1636                 :       8041 : compiler_enter_scope(struct compiler *c, identifier name,
    1637                 :            :                      int scope_type, void *key, int lineno)
    1638                 :            : {
    1639                 :       8041 :     location loc = LOCATION(lineno, lineno, 0, 0);
    1640                 :            : 
    1641                 :            :     struct compiler_unit *u;
    1642                 :            : 
    1643                 :       8041 :     u = (struct compiler_unit *)PyObject_Calloc(1, sizeof(
    1644                 :            :                                             struct compiler_unit));
    1645         [ -  + ]:       8041 :     if (!u) {
    1646                 :          0 :         PyErr_NoMemory();
    1647                 :          0 :         return ERROR;
    1648                 :            :     }
    1649                 :       8041 :     u->u_scope_type = scope_type;
    1650                 :       8041 :     u->u_argcount = 0;
    1651                 :       8041 :     u->u_posonlyargcount = 0;
    1652                 :       8041 :     u->u_kwonlyargcount = 0;
    1653                 :       8041 :     u->u_ste = PySymtable_Lookup(c->c_st, key);
    1654         [ -  + ]:       8041 :     if (!u->u_ste) {
    1655                 :          0 :         compiler_unit_free(u);
    1656                 :          0 :         return ERROR;
    1657                 :            :     }
    1658                 :       8041 :     u->u_name = Py_NewRef(name);
    1659                 :       8041 :     u->u_varnames = list2dict(u->u_ste->ste_varnames);
    1660                 :       8041 :     u->u_cellvars = dictbytype(u->u_ste->ste_symbols, CELL, 0, 0);
    1661   [ +  -  -  + ]:       8041 :     if (!u->u_varnames || !u->u_cellvars) {
    1662                 :          0 :         compiler_unit_free(u);
    1663                 :          0 :         return ERROR;
    1664                 :            :     }
    1665         [ +  + ]:       8041 :     if (u->u_ste->ste_needs_class_closure) {
    1666                 :            :         /* Cook up an implicit __class__ cell. */
    1667                 :            :         int res;
    1668                 :            :         assert(u->u_scope_type == COMPILER_SCOPE_CLASS);
    1669                 :            :         assert(PyDict_GET_SIZE(u->u_cellvars) == 0);
    1670                 :        112 :         res = PyDict_SetItem(u->u_cellvars, &_Py_ID(__class__),
    1671                 :            :                              _PyLong_GetZero());
    1672         [ -  + ]:        112 :         if (res < 0) {
    1673                 :          0 :             compiler_unit_free(u);
    1674                 :          0 :             return ERROR;
    1675                 :            :         }
    1676                 :            :     }
    1677                 :            : 
    1678                 :       8041 :     u->u_freevars = dictbytype(u->u_ste->ste_symbols, FREE, DEF_FREE_CLASS,
    1679                 :            :                                PyDict_GET_SIZE(u->u_cellvars));
    1680         [ -  + ]:       8041 :     if (!u->u_freevars) {
    1681                 :          0 :         compiler_unit_free(u);
    1682                 :          0 :         return ERROR;
    1683                 :            :     }
    1684                 :            : 
    1685                 :       8041 :     u->u_nfblocks = 0;
    1686                 :       8041 :     u->u_firstlineno = lineno;
    1687                 :       8041 :     u->u_consts = PyDict_New();
    1688         [ -  + ]:       8041 :     if (!u->u_consts) {
    1689                 :          0 :         compiler_unit_free(u);
    1690                 :          0 :         return ERROR;
    1691                 :            :     }
    1692                 :       8041 :     u->u_names = PyDict_New();
    1693         [ -  + ]:       8041 :     if (!u->u_names) {
    1694                 :          0 :         compiler_unit_free(u);
    1695                 :          0 :         return ERROR;
    1696                 :            :     }
    1697                 :            : 
    1698                 :       8041 :     u->u_private = NULL;
    1699                 :            : 
    1700                 :            :     /* Push the old compiler_unit on the stack. */
    1701         [ +  + ]:       8041 :     if (c->u) {
    1702                 :       7722 :         PyObject *capsule = PyCapsule_New(c->u, CAPSULE_NAME, NULL);
    1703   [ +  -  -  + ]:       7722 :         if (!capsule || PyList_Append(c->c_stack, capsule) < 0) {
    1704                 :          0 :             Py_XDECREF(capsule);
    1705                 :          0 :             compiler_unit_free(u);
    1706                 :          0 :             return ERROR;
    1707                 :            :         }
    1708                 :       7722 :         Py_DECREF(capsule);
    1709                 :       7722 :         u->u_private = Py_XNewRef(c->u->u_private);
    1710                 :            :     }
    1711                 :       8041 :     c->u = u;
    1712                 :            : 
    1713                 :       8041 :     c->c_nestlevel++;
    1714                 :            : 
    1715         [ +  + ]:       8041 :     if (u->u_scope_type == COMPILER_SCOPE_MODULE) {
    1716                 :        319 :         loc.lineno = 0;
    1717                 :            :     }
    1718                 :            :     else {
    1719         [ -  + ]:       7722 :         RETURN_IF_ERROR(compiler_set_qualname(c));
    1720                 :            :     }
    1721         [ -  + ]:       8041 :     ADDOP_I(c, loc, RESUME, 0);
    1722                 :            : 
    1723         [ +  + ]:       8041 :     if (u->u_scope_type == COMPILER_SCOPE_MODULE) {
    1724                 :        319 :         loc.lineno = -1;
    1725                 :            :     }
    1726                 :       8041 :     return SUCCESS;
    1727                 :            : }
    1728                 :            : 
    1729                 :            : static void
    1730                 :       8041 : compiler_exit_scope(struct compiler *c)
    1731                 :            : {
    1732                 :            :     // Don't call PySequence_DelItem() with an exception raised
    1733                 :       8041 :     PyObject *exc = PyErr_GetRaisedException();
    1734                 :            : 
    1735                 :       8041 :     c->c_nestlevel--;
    1736                 :       8041 :     compiler_unit_free(c->u);
    1737                 :            :     /* Restore c->u to the parent unit. */
    1738                 :       8041 :     Py_ssize_t n = PyList_GET_SIZE(c->c_stack) - 1;
    1739         [ +  + ]:       8041 :     if (n >= 0) {
    1740                 :       7722 :         PyObject *capsule = PyList_GET_ITEM(c->c_stack, n);
    1741                 :       7722 :         c->u = (struct compiler_unit *)PyCapsule_GetPointer(capsule, CAPSULE_NAME);
    1742                 :            :         assert(c->u);
    1743                 :            :         /* we are deleting from a list so this really shouldn't fail */
    1744         [ -  + ]:       7722 :         if (PySequence_DelItem(c->c_stack, n) < 0) {
    1745                 :          0 :             _PyErr_WriteUnraisableMsg("on removing the last compiler "
    1746                 :            :                                       "stack item", NULL);
    1747                 :            :         }
    1748                 :            :     }
    1749                 :            :     else {
    1750                 :        319 :         c->u = NULL;
    1751                 :            :     }
    1752                 :            : 
    1753                 :       8041 :     PyErr_SetRaisedException(exc);
    1754                 :       8041 : }
    1755                 :            : 
    1756                 :            : /* Search if variable annotations are present statically in a block. */
    1757                 :            : 
    1758                 :            : static bool
    1759                 :       2106 : find_ann(asdl_stmt_seq *stmts)
    1760                 :            : {
    1761                 :       2106 :     int i, j, res = 0;
    1762                 :            :     stmt_ty st;
    1763                 :            : 
    1764   [ +  +  +  + ]:      14783 :     for (i = 0; i < asdl_seq_LEN(stmts); i++) {
    1765                 :      12678 :         st = (stmt_ty)asdl_seq_GET(stmts, i);
    1766   [ +  +  -  +  :      12678 :         switch (st->kind) {
          +  +  -  +  -  
                      + ]
    1767                 :          1 :         case AnnAssign_kind:
    1768                 :          1 :             return true;
    1769                 :         34 :         case For_kind:
    1770   [ +  -  -  + ]:         68 :             res = find_ann(st->v.For.body) ||
    1771                 :         34 :                   find_ann(st->v.For.orelse);
    1772                 :         34 :             break;
    1773                 :          0 :         case AsyncFor_kind:
    1774   [ #  #  #  # ]:          0 :             res = find_ann(st->v.AsyncFor.body) ||
    1775                 :          0 :                   find_ann(st->v.AsyncFor.orelse);
    1776                 :          0 :             break;
    1777                 :          1 :         case While_kind:
    1778   [ +  -  -  + ]:          2 :             res = find_ann(st->v.While.body) ||
    1779                 :          1 :                   find_ann(st->v.While.orelse);
    1780                 :          1 :             break;
    1781                 :        310 :         case If_kind:
    1782   [ +  -  -  + ]:        620 :             res = find_ann(st->v.If.body) ||
    1783                 :        310 :                   find_ann(st->v.If.orelse);
    1784                 :        310 :             break;
    1785                 :          1 :         case With_kind:
    1786                 :          1 :             res = find_ann(st->v.With.body);
    1787                 :          1 :             break;
    1788                 :          0 :         case AsyncWith_kind:
    1789                 :          0 :             res = find_ann(st->v.AsyncWith.body);
    1790                 :          0 :             break;
    1791                 :        105 :         case Try_kind:
    1792   [ +  +  +  + ]:        210 :             for (j = 0; j < asdl_seq_LEN(st->v.Try.handlers); j++) {
    1793                 :        105 :                 excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
    1794                 :            :                     st->v.Try.handlers, j);
    1795         [ -  + ]:        105 :                 if (find_ann(handler->v.ExceptHandler.body)) {
    1796                 :          0 :                     return true;
    1797                 :            :                 }
    1798                 :            :             }
    1799         [ +  - ]:        210 :             res = find_ann(st->v.Try.body) ||
    1800   [ +  -  -  + ]:        210 :                   find_ann(st->v.Try.finalbody) ||
    1801                 :        105 :                   find_ann(st->v.Try.orelse);
    1802                 :        105 :             break;
    1803                 :          0 :         case TryStar_kind:
    1804   [ #  #  #  # ]:          0 :             for (j = 0; j < asdl_seq_LEN(st->v.TryStar.handlers); j++) {
    1805                 :          0 :                 excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
    1806                 :            :                     st->v.TryStar.handlers, j);
    1807         [ #  # ]:          0 :                 if (find_ann(handler->v.ExceptHandler.body)) {
    1808                 :          0 :                     return true;
    1809                 :            :                 }
    1810                 :            :             }
    1811         [ #  # ]:          0 :             res = find_ann(st->v.TryStar.body) ||
    1812   [ #  #  #  # ]:          0 :                   find_ann(st->v.TryStar.finalbody) ||
    1813                 :          0 :                   find_ann(st->v.TryStar.orelse);
    1814                 :          0 :             break;
    1815                 :      12226 :         default:
    1816                 :      12226 :             res = false;
    1817                 :            :         }
    1818         [ -  + ]:      12677 :         if (res) {
    1819                 :          0 :             break;
    1820                 :            :         }
    1821                 :            :     }
    1822                 :       2105 :     return res;
    1823                 :            : }
    1824                 :            : 
    1825                 :            : /*
    1826                 :            :  * Frame block handling functions
    1827                 :            :  */
    1828                 :            : 
    1829                 :            : static int
    1830                 :       6394 : compiler_push_fblock(struct compiler *c, location loc,
    1831                 :            :                      enum fblocktype t, jump_target_label block_label,
    1832                 :            :                      jump_target_label exit, void *datum)
    1833                 :            : {
    1834                 :            :     struct fblockinfo *f;
    1835         [ -  + ]:       6394 :     if (c->u->u_nfblocks >= CO_MAXBLOCKS) {
    1836                 :          0 :         return compiler_error(c, loc, "too many statically nested blocks");
    1837                 :            :     }
    1838                 :       6394 :     f = &c->u->u_fblock[c->u->u_nfblocks++];
    1839                 :       6394 :     f->fb_type = t;
    1840                 :       6394 :     f->fb_block = block_label;
    1841                 :       6394 :     f->fb_exit = exit;
    1842                 :       6394 :     f->fb_datum = datum;
    1843                 :       6394 :     return SUCCESS;
    1844                 :            : }
    1845                 :            : 
    1846                 :            : static void
    1847                 :       6394 : compiler_pop_fblock(struct compiler *c, enum fblocktype t, jump_target_label block_label)
    1848                 :            : {
    1849                 :       6394 :     struct compiler_unit *u = c->u;
    1850                 :            :     assert(u->u_nfblocks > 0);
    1851                 :       6394 :     u->u_nfblocks--;
    1852                 :            :     assert(u->u_fblock[u->u_nfblocks].fb_type == t);
    1853                 :            :     assert(SAME_LABEL(u->u_fblock[u->u_nfblocks].fb_block, block_label));
    1854                 :       6394 : }
    1855                 :            : 
    1856                 :            : static int
    1857                 :        481 : compiler_call_exit_with_nones(struct compiler *c, location loc)
    1858                 :            : {
    1859         [ -  + ]:        481 :     ADDOP_LOAD_CONST(c, loc, Py_None);
    1860         [ -  + ]:        481 :     ADDOP_LOAD_CONST(c, loc, Py_None);
    1861         [ -  + ]:        481 :     ADDOP_LOAD_CONST(c, loc, Py_None);
    1862         [ -  + ]:        481 :     ADDOP_I(c, loc, CALL, 2);
    1863                 :        481 :     return SUCCESS;
    1864                 :            : }
    1865                 :            : 
    1866                 :            : static int
    1867                 :        195 : compiler_add_yield_from(struct compiler *c, location loc, int await)
    1868                 :            : {
    1869         [ -  + ]:        195 :     NEW_JUMP_TARGET_LABEL(c, send);
    1870         [ -  + ]:        195 :     NEW_JUMP_TARGET_LABEL(c, fail);
    1871         [ -  + ]:        195 :     NEW_JUMP_TARGET_LABEL(c, exit);
    1872                 :            : 
    1873         [ -  + ]:        195 :     USE_LABEL(c, send);
    1874         [ -  + ]:        195 :     ADDOP_JUMP(c, loc, SEND, exit);
    1875                 :            :     // Set up a virtual try/except to handle when StopIteration is raised during
    1876                 :            :     // a close or throw call. The only way YIELD_VALUE raises if they do!
    1877         [ -  + ]:        195 :     ADDOP_JUMP(c, loc, SETUP_FINALLY, fail);
    1878         [ -  + ]:        195 :     ADDOP_I(c, loc, YIELD_VALUE, 0);
    1879         [ -  + ]:        195 :     ADDOP(c, NO_LOCATION, POP_BLOCK);
    1880   [ +  +  -  + ]:        195 :     ADDOP_I(c, loc, RESUME, await ? 3 : 2);
    1881         [ -  + ]:        195 :     ADDOP_JUMP(c, loc, JUMP_NO_INTERRUPT, send);
    1882                 :            : 
    1883         [ -  + ]:        195 :     USE_LABEL(c, fail);
    1884         [ -  + ]:        195 :     ADDOP(c, loc, CLEANUP_THROW);
    1885                 :            : 
    1886         [ -  + ]:        195 :     USE_LABEL(c, exit);
    1887         [ -  + ]:        195 :     ADDOP_I(c, loc, SWAP, 2);
    1888         [ -  + ]:        195 :     ADDOP(c, loc, POP_TOP);
    1889                 :        195 :     return SUCCESS;
    1890                 :            : }
    1891                 :            : 
    1892                 :            : static int
    1893                 :       1878 : compiler_pop_except_and_reraise(struct compiler *c, location loc)
    1894                 :            : {
    1895                 :            :     /* Stack contents
    1896                 :            :      * [exc_info, lasti, exc]            COPY        3
    1897                 :            :      * [exc_info, lasti, exc, exc_info]  POP_EXCEPT
    1898                 :            :      * [exc_info, lasti, exc]            RERAISE      1
    1899                 :            :      * (exception_unwind clears the stack)
    1900                 :            :      */
    1901                 :            : 
    1902         [ -  + ]:       1878 :     ADDOP_I(c, loc, COPY, 3);
    1903         [ -  + ]:       1878 :     ADDOP(c, loc, POP_EXCEPT);
    1904         [ -  + ]:       1878 :     ADDOP_I(c, loc, RERAISE, 1);
    1905                 :       1878 :     return SUCCESS;
    1906                 :            : }
    1907                 :            : 
    1908                 :            : /* Unwind a frame block.  If preserve_tos is true, the TOS before
    1909                 :            :  * popping the blocks will be restored afterwards, unless another
    1910                 :            :  * return, break or continue is found. In which case, the TOS will
    1911                 :            :  * be popped.
    1912                 :            :  */
    1913                 :            : static int
    1914                 :       1586 : compiler_unwind_fblock(struct compiler *c, location *ploc,
    1915                 :            :                        struct fblockinfo *info, int preserve_tos)
    1916                 :            : {
    1917   [ +  +  +  +  :       1586 :     switch (info->fb_type) {
             +  +  +  -  
                      - ]
    1918                 :        606 :         case WHILE_LOOP:
    1919                 :            :         case EXCEPTION_HANDLER:
    1920                 :            :         case EXCEPTION_GROUP_HANDLER:
    1921                 :            :         case ASYNC_COMPREHENSION_GENERATOR:
    1922                 :        606 :             return SUCCESS;
    1923                 :            : 
    1924                 :        224 :         case FOR_LOOP:
    1925                 :            :             /* Pop the iterator */
    1926         [ +  + ]:        224 :             if (preserve_tos) {
    1927         [ -  + ]:         71 :                 ADDOP_I(c, *ploc, SWAP, 2);
    1928                 :            :             }
    1929         [ -  + ]:        224 :             ADDOP(c, *ploc, POP_TOP);
    1930                 :        224 :             return SUCCESS;
    1931                 :            : 
    1932                 :        223 :         case TRY_EXCEPT:
    1933         [ -  + ]:        223 :             ADDOP(c, *ploc, POP_BLOCK);
    1934                 :        223 :             return SUCCESS;
    1935                 :            : 
    1936                 :         49 :         case FINALLY_TRY:
    1937                 :            :             /* This POP_BLOCK gets the line number of the unwinding statement */
    1938         [ -  + ]:         49 :             ADDOP(c, *ploc, POP_BLOCK);
    1939         [ +  + ]:         49 :             if (preserve_tos) {
    1940         [ -  + ]:         44 :                 RETURN_IF_ERROR(
    1941                 :            :                     compiler_push_fblock(c, *ploc, POP_VALUE, NO_LABEL, NO_LABEL, NULL));
    1942                 :            :             }
    1943                 :            :             /* Emit the finally block */
    1944   [ -  +  +  -  :        122 :             VISIT_SEQ(c, stmt, info->fb_datum);
                   +  + ]
    1945         [ +  + ]:         49 :             if (preserve_tos) {
    1946                 :         44 :                 compiler_pop_fblock(c, POP_VALUE, NO_LABEL);
    1947                 :            :             }
    1948                 :            :             /* The finally block should appear to execute after the
    1949                 :            :              * statement causing the unwinding, so make the unwinding
    1950                 :            :              * instruction artificial */
    1951                 :         49 :             *ploc = NO_LOCATION;
    1952                 :         49 :             return SUCCESS;
    1953                 :            : 
    1954                 :          1 :         case FINALLY_END:
    1955         [ -  + ]:          1 :             if (preserve_tos) {
    1956         [ #  # ]:          0 :                 ADDOP_I(c, *ploc, SWAP, 2);
    1957                 :            :             }
    1958         [ -  + ]:          1 :             ADDOP(c, *ploc, POP_TOP); /* exc_value */
    1959         [ -  + ]:          1 :             if (preserve_tos) {
    1960         [ #  # ]:          0 :                 ADDOP_I(c, *ploc, SWAP, 2);
    1961                 :            :             }
    1962         [ -  + ]:          1 :             ADDOP(c, *ploc, POP_BLOCK);
    1963         [ -  + ]:          1 :             ADDOP(c, *ploc, POP_EXCEPT);
    1964                 :          1 :             return SUCCESS;
    1965                 :            : 
    1966                 :         92 :         case WITH:
    1967                 :            :         case ASYNC_WITH:
    1968                 :         92 :             *ploc = LOC((stmt_ty)info->fb_datum);
    1969         [ -  + ]:         92 :             ADDOP(c, *ploc, POP_BLOCK);
    1970         [ +  + ]:         92 :             if (preserve_tos) {
    1971         [ -  + ]:         76 :                 ADDOP_I(c, *ploc, SWAP, 2);
    1972                 :            :             }
    1973         [ -  + ]:         92 :             RETURN_IF_ERROR(compiler_call_exit_with_nones(c, *ploc));
    1974         [ +  + ]:         92 :             if (info->fb_type == ASYNC_WITH) {
    1975         [ -  + ]:          3 :                 ADDOP_I(c, *ploc, GET_AWAITABLE, 2);
    1976         [ -  + ]:          3 :                 ADDOP_LOAD_CONST(c, *ploc, Py_None);
    1977         [ -  + ]:          3 :                 ADD_YIELD_FROM(c, *ploc, 1);
    1978                 :            :             }
    1979         [ -  + ]:         92 :             ADDOP(c, *ploc, POP_TOP);
    1980                 :            :             /* The exit block should appear to execute after the
    1981                 :            :              * statement causing the unwinding, so make the unwinding
    1982                 :            :              * instruction artificial */
    1983                 :         92 :             *ploc = NO_LOCATION;
    1984                 :         92 :             return SUCCESS;
    1985                 :            : 
    1986                 :        391 :         case HANDLER_CLEANUP: {
    1987         [ +  + ]:        391 :             if (info->fb_datum) {
    1988         [ -  + ]:         74 :                 ADDOP(c, *ploc, POP_BLOCK);
    1989                 :            :             }
    1990         [ +  + ]:        391 :             if (preserve_tos) {
    1991         [ -  + ]:        121 :                 ADDOP_I(c, *ploc, SWAP, 2);
    1992                 :            :             }
    1993         [ -  + ]:        391 :             ADDOP(c, *ploc, POP_BLOCK);
    1994         [ -  + ]:        391 :             ADDOP(c, *ploc, POP_EXCEPT);
    1995         [ +  + ]:        391 :             if (info->fb_datum) {
    1996         [ -  + ]:         74 :                 ADDOP_LOAD_CONST(c, *ploc, Py_None);
    1997         [ -  + ]:         74 :                 RETURN_IF_ERROR(compiler_nameop(c, *ploc, info->fb_datum, Store));
    1998         [ -  + ]:         74 :                 RETURN_IF_ERROR(compiler_nameop(c, *ploc, info->fb_datum, Del));
    1999                 :            :             }
    2000                 :        391 :             return SUCCESS;
    2001                 :            :         }
    2002                 :          0 :         case POP_VALUE: {
    2003         [ #  # ]:          0 :             if (preserve_tos) {
    2004         [ #  # ]:          0 :                 ADDOP_I(c, *ploc, SWAP, 2);
    2005                 :            :             }
    2006         [ #  # ]:          0 :             ADDOP(c, *ploc, POP_TOP);
    2007                 :          0 :             return SUCCESS;
    2008                 :            :         }
    2009                 :            :     }
    2010                 :          0 :     Py_UNREACHABLE();
    2011                 :            : }
    2012                 :            : 
    2013                 :            : /** Unwind block stack. If loop is not NULL, then stop when the first loop is encountered. */
    2014                 :            : static int
    2015                 :       7659 : compiler_unwind_fblock_stack(struct compiler *c, location *ploc,
    2016                 :            :                              int preserve_tos, struct fblockinfo **loop)
    2017                 :            : {
    2018         [ +  + ]:       7659 :     if (c->u->u_nfblocks == 0) {
    2019                 :       5842 :         return SUCCESS;
    2020                 :            :     }
    2021                 :       1817 :     struct fblockinfo *top = &c->u->u_fblock[c->u->u_nfblocks-1];
    2022         [ -  + ]:       1817 :     if (top->fb_type == EXCEPTION_GROUP_HANDLER) {
    2023                 :          0 :         return compiler_error(
    2024                 :            :             c, *ploc, "'break', 'continue' and 'return' cannot appear in an except* block");
    2025                 :            :     }
    2026   [ +  +  +  +  :       1817 :     if (loop != NULL && (top->fb_type == WHILE_LOOP || top->fb_type == FOR_LOOP)) {
                   +  + ]
    2027                 :        506 :         *loop = top;
    2028                 :        506 :         return SUCCESS;
    2029                 :            :     }
    2030                 :       1311 :     struct fblockinfo copy = *top;
    2031                 :       1311 :     c->u->u_nfblocks--;
    2032         [ -  + ]:       1311 :     RETURN_IF_ERROR(compiler_unwind_fblock(c, ploc, &copy, preserve_tos));
    2033         [ -  + ]:       1311 :     RETURN_IF_ERROR(compiler_unwind_fblock_stack(c, ploc, preserve_tos, loop));
    2034                 :       1311 :     c->u->u_fblock[c->u->u_nfblocks] = copy;
    2035                 :       1311 :     c->u->u_nfblocks++;
    2036                 :       1311 :     return SUCCESS;
    2037                 :            : }
    2038                 :            : 
    2039                 :            : /* Compile a sequence of statements, checking for a docstring
    2040                 :            :    and for annotations. */
    2041                 :            : 
    2042                 :            : static int
    2043                 :        939 : compiler_body(struct compiler *c, location loc, asdl_stmt_seq *stmts)
    2044                 :            : {
    2045                 :        939 :     int i = 0;
    2046                 :            :     stmt_ty st;
    2047                 :            :     PyObject *docstring;
    2048                 :            : 
    2049                 :            :     /* Set current line number to the line number of first statement.
    2050                 :            :        This way line number for SETUP_ANNOTATIONS will always
    2051                 :            :        coincide with the line number of first "real" statement in module.
    2052                 :            :        If body is empty, then lineno will be set later in assemble. */
    2053   [ +  +  +  +  :        939 :     if (c->u->u_scope_type == COMPILER_SCOPE_MODULE && asdl_seq_LEN(stmts)) {
                   +  - ]
    2054                 :        200 :         st = (stmt_ty)asdl_seq_GET(stmts, 0);
    2055                 :        200 :         loc = LOC(st);
    2056                 :            :     }
    2057                 :            :     /* Every annotated class and module should have __annotations__. */
    2058         [ +  + ]:        939 :     if (find_ann(stmts)) {
    2059         [ -  + ]:          1 :         ADDOP(c, loc, SETUP_ANNOTATIONS);
    2060                 :            :     }
    2061   [ +  +  -  + ]:        939 :     if (!asdl_seq_LEN(stmts)) {
    2062                 :          6 :         return SUCCESS;
    2063                 :            :     }
    2064                 :            :     /* if not -OO mode, set docstring */
    2065         [ +  - ]:        933 :     if (c->c_optimize < 2) {
    2066                 :        933 :         docstring = _PyAST_GetDocString(stmts);
    2067         [ +  + ]:        933 :         if (docstring) {
    2068                 :        564 :             i = 1;
    2069                 :        564 :             st = (stmt_ty)asdl_seq_GET(stmts, 0);
    2070                 :            :             assert(st->kind == Expr_kind);
    2071         [ -  + ]:        564 :             VISIT(c, expr, st->v.Expr.value);
    2072         [ -  + ]:        564 :             RETURN_IF_ERROR(compiler_nameop(c, NO_LOCATION, &_Py_ID(__doc__), Store));
    2073                 :            :         }
    2074                 :            :     }
    2075   [ +  -  +  + ]:      11662 :     for (; i < asdl_seq_LEN(stmts); i++) {
    2076         [ -  + ]:      10729 :         VISIT(c, stmt, (stmt_ty)asdl_seq_GET(stmts, i));
    2077                 :            :     }
    2078                 :        933 :     return SUCCESS;
    2079                 :            : }
    2080                 :            : 
    2081                 :            : static int
    2082                 :        319 : compiler_codegen(struct compiler *c, mod_ty mod)
    2083                 :            : {
    2084                 :            :     _Py_DECLARE_STR(anon_module, "<module>");
    2085         [ -  + ]:        319 :     RETURN_IF_ERROR(
    2086                 :            :         compiler_enter_scope(c, &_Py_STR(anon_module), COMPILER_SCOPE_MODULE,
    2087                 :            :                              mod, 1));
    2088                 :            : 
    2089                 :        319 :     location loc = LOCATION(1, 1, 0, 0);
    2090   [ +  +  +  - ]:        319 :     switch (mod->kind) {
    2091                 :        206 :     case Module_kind:
    2092         [ -  + ]:        206 :         if (compiler_body(c, loc, mod->v.Module.body) < 0) {
    2093                 :          0 :             compiler_exit_scope(c);
    2094                 :          0 :             return ERROR;
    2095                 :            :         }
    2096                 :        206 :         break;
    2097                 :         56 :     case Interactive_kind:
    2098         [ -  + ]:         56 :         if (find_ann(mod->v.Interactive.body)) {
    2099         [ #  # ]:          0 :             ADDOP(c, loc, SETUP_ANNOTATIONS);
    2100                 :            :         }
    2101                 :         56 :         c->c_interactive = 1;
    2102   [ -  +  +  -  :        112 :         VISIT_SEQ_IN_SCOPE(c, stmt, mod->v.Interactive.body);
                   +  + ]
    2103                 :         56 :         break;
    2104                 :         57 :     case Expression_kind:
    2105         [ -  + ]:         57 :         VISIT_IN_SCOPE(c, expr, mod->v.Expression.body);
    2106                 :         57 :         break;
    2107                 :          0 :     default:
    2108                 :          0 :         PyErr_Format(PyExc_SystemError,
    2109                 :            :                      "module kind %d should not be possible",
    2110                 :          0 :                      mod->kind);
    2111                 :          0 :         return ERROR;
    2112                 :            :     }
    2113                 :        319 :     return SUCCESS;
    2114                 :            : }
    2115                 :            : 
    2116                 :            : static PyCodeObject *
    2117                 :        319 : compiler_mod(struct compiler *c, mod_ty mod)
    2118                 :            : {
    2119                 :        319 :     int addNone = mod->kind != Expression_kind;
    2120         [ -  + ]:        319 :     if (compiler_codegen(c, mod) < 0) {
    2121                 :          0 :         return NULL;
    2122                 :            :     }
    2123                 :        319 :     PyCodeObject *co = assemble(c, addNone);
    2124                 :        319 :     compiler_exit_scope(c);
    2125                 :        319 :     return co;
    2126                 :            : }
    2127                 :            : 
    2128                 :            : /* The test for LOCAL must come before the test for FREE in order to
    2129                 :            :    handle classes where name is both local and free.  The local var is
    2130                 :            :    a method and the free var is a free var referenced within a method.
    2131                 :            : */
    2132                 :            : 
    2133                 :            : static int
    2134                 :        938 : get_ref_type(struct compiler *c, PyObject *name)
    2135                 :            : {
    2136                 :            :     int scope;
    2137   [ +  +  +  + ]:       1160 :     if (c->u->u_scope_type == COMPILER_SCOPE_CLASS &&
    2138                 :        222 :         _PyUnicode_EqualToASCIIString(name, "__class__"))
    2139                 :        208 :         return CELL;
    2140                 :        730 :     scope = _PyST_GetScope(c->u->u_ste, name);
    2141         [ -  + ]:        730 :     if (scope == 0) {
    2142                 :          0 :         PyErr_Format(PyExc_SystemError,
    2143                 :            :                      "_PyST_GetScope(name=%R) failed: "
    2144                 :            :                      "unknown scope in unit %S (%R); "
    2145                 :            :                      "symbols: %R; locals: %R; globals: %R",
    2146                 :            :                      name,
    2147                 :          0 :                      c->u->u_name, c->u->u_ste->ste_id,
    2148                 :          0 :                      c->u->u_ste->ste_symbols, c->u->u_varnames, c->u->u_names);
    2149                 :          0 :         return ERROR;
    2150                 :            :     }
    2151                 :        730 :     return scope;
    2152                 :            : }
    2153                 :            : 
    2154                 :            : static int
    2155                 :       1050 : compiler_lookup_arg(PyObject *dict, PyObject *name)
    2156                 :            : {
    2157                 :       1050 :     PyObject *v = PyDict_GetItemWithError(dict, name);
    2158         [ -  + ]:       1050 :     if (v == NULL) {
    2159                 :          0 :         return ERROR;
    2160                 :            :     }
    2161                 :       1050 :     return PyLong_AS_LONG(v);
    2162                 :            : }
    2163                 :            : 
    2164                 :            : static int
    2165                 :       7722 : compiler_make_closure(struct compiler *c, location loc,
    2166                 :            :                       PyCodeObject *co, Py_ssize_t flags)
    2167                 :            : {
    2168         [ +  + ]:       7722 :     if (co->co_nfreevars) {
    2169                 :        627 :         int i = PyCode_GetFirstFree(co);
    2170         [ +  + ]:       1565 :         for (; i < co->co_nlocalsplus; ++i) {
    2171                 :            :             /* Bypass com_addop_varname because it will generate
    2172                 :            :                LOAD_DEREF but LOAD_CLOSURE is needed.
    2173                 :            :             */
    2174                 :        938 :             PyObject *name = PyTuple_GET_ITEM(co->co_localsplusnames, i);
    2175                 :            : 
    2176                 :            :             /* Special case: If a class contains a method with a
    2177                 :            :                free variable that has the same name as a method,
    2178                 :            :                the name will be considered free *and* local in the
    2179                 :            :                class.  It should be handled by the closure, as
    2180                 :            :                well as by the normal name lookup logic.
    2181                 :            :             */
    2182                 :        938 :             int reftype = get_ref_type(c, name);
    2183         [ -  + ]:        938 :             if (reftype == -1) {
    2184                 :          0 :                 return ERROR;
    2185                 :            :             }
    2186                 :            :             int arg;
    2187         [ +  + ]:        938 :             if (reftype == CELL) {
    2188                 :        902 :                 arg = compiler_lookup_arg(c->u->u_cellvars, name);
    2189                 :            :             }
    2190                 :            :             else {
    2191                 :         36 :                 arg = compiler_lookup_arg(c->u->u_freevars, name);
    2192                 :            :             }
    2193         [ -  + ]:        938 :             if (arg == -1) {
    2194                 :          0 :                 PyObject *freevars = _PyCode_GetFreevars(co);
    2195         [ #  # ]:          0 :                 if (freevars == NULL) {
    2196                 :          0 :                     PyErr_Clear();
    2197                 :            :                 }
    2198                 :          0 :                 PyErr_Format(PyExc_SystemError,
    2199                 :            :                     "compiler_lookup_arg(name=%R) with reftype=%d failed in %S; "
    2200                 :            :                     "freevars of code %S: %R",
    2201                 :            :                     name,
    2202                 :            :                     reftype,
    2203                 :          0 :                     c->u->u_name,
    2204                 :            :                     co->co_name,
    2205                 :            :                     freevars);
    2206                 :          0 :                 Py_DECREF(freevars);
    2207                 :          0 :                 return ERROR;
    2208                 :            :             }
    2209         [ -  + ]:        938 :             ADDOP_I(c, loc, LOAD_CLOSURE, arg);
    2210                 :            :         }
    2211                 :        627 :         flags |= 0x08;
    2212         [ -  + ]:        627 :         ADDOP_I(c, loc, BUILD_TUPLE, co->co_nfreevars);
    2213                 :            :     }
    2214         [ -  + ]:       7722 :     ADDOP_LOAD_CONST(c, loc, (PyObject*)co);
    2215         [ -  + ]:       7722 :     ADDOP_I(c, loc, MAKE_FUNCTION, flags);
    2216                 :       7722 :     return SUCCESS;
    2217                 :            : }
    2218                 :            : 
    2219                 :            : static int
    2220                 :       7134 : compiler_decorators(struct compiler *c, asdl_expr_seq* decos)
    2221                 :            : {
    2222         [ +  + ]:       7134 :     if (!decos) {
    2223                 :       6544 :         return SUCCESS;
    2224                 :            :     }
    2225                 :            : 
    2226   [ +  -  +  + ]:       1211 :     for (Py_ssize_t i = 0; i < asdl_seq_LEN(decos); i++) {
    2227         [ -  + ]:        621 :         VISIT(c, expr, (expr_ty)asdl_seq_GET(decos, i));
    2228                 :            :     }
    2229                 :        590 :     return SUCCESS;
    2230                 :            : }
    2231                 :            : 
    2232                 :            : static int
    2233                 :       7134 : compiler_apply_decorators(struct compiler *c, asdl_expr_seq* decos)
    2234                 :            : {
    2235         [ +  + ]:       7134 :     if (!decos) {
    2236                 :       6544 :         return SUCCESS;
    2237                 :            :     }
    2238                 :            : 
    2239   [ +  -  +  + ]:       1211 :     for (Py_ssize_t i = asdl_seq_LEN(decos) - 1; i > -1; i--) {
    2240                 :        621 :         location loc = LOC((expr_ty)asdl_seq_GET(decos, i));
    2241         [ -  + ]:        621 :         ADDOP_I(c, loc, CALL, 0);
    2242                 :            :     }
    2243                 :        590 :     return SUCCESS;
    2244                 :            : }
    2245                 :            : 
    2246                 :            : static int
    2247                 :       6536 : compiler_visit_kwonlydefaults(struct compiler *c, location loc,
    2248                 :            :                               asdl_arg_seq *kwonlyargs, asdl_expr_seq *kw_defaults)
    2249                 :            : {
    2250                 :            :     /* Push a dict of keyword-only default values.
    2251                 :            : 
    2252                 :            :        Return -1 on error, 0 if no dict pushed, 1 if a dict is pushed.
    2253                 :            :        */
    2254                 :            :     int i;
    2255                 :       6536 :     PyObject *keys = NULL;
    2256                 :            : 
    2257   [ +  -  +  + ]:       7109 :     for (i = 0; i < asdl_seq_LEN(kwonlyargs); i++) {
    2258                 :        573 :         arg_ty arg = asdl_seq_GET(kwonlyargs, i);
    2259                 :        573 :         expr_ty default_ = asdl_seq_GET(kw_defaults, i);
    2260         [ +  + ]:        573 :         if (default_) {
    2261                 :        563 :             PyObject *mangled = _Py_Mangle(c->u->u_private, arg->arg);
    2262         [ -  + ]:        563 :             if (!mangled) {
    2263                 :          0 :                 goto error;
    2264                 :            :             }
    2265         [ +  + ]:        563 :             if (keys == NULL) {
    2266                 :        221 :                 keys = PyList_New(1);
    2267         [ -  + ]:        221 :                 if (keys == NULL) {
    2268                 :          0 :                     Py_DECREF(mangled);
    2269                 :          0 :                     return ERROR;
    2270                 :            :                 }
    2271                 :        221 :                 PyList_SET_ITEM(keys, 0, mangled);
    2272                 :            :             }
    2273                 :            :             else {
    2274                 :        342 :                 int res = PyList_Append(keys, mangled);
    2275                 :        342 :                 Py_DECREF(mangled);
    2276         [ -  + ]:        342 :                 if (res == -1) {
    2277                 :          0 :                     goto error;
    2278                 :            :                 }
    2279                 :            :             }
    2280         [ -  + ]:        563 :             if (compiler_visit_expr(c, default_) < 0) {
    2281                 :          0 :                 goto error;
    2282                 :            :             }
    2283                 :            :         }
    2284                 :            :     }
    2285         [ +  + ]:       6536 :     if (keys != NULL) {
    2286                 :        221 :         Py_ssize_t default_count = PyList_GET_SIZE(keys);
    2287                 :        221 :         PyObject *keys_tuple = PyList_AsTuple(keys);
    2288                 :        221 :         Py_DECREF(keys);
    2289   [ -  +  -  + ]:        221 :         ADDOP_LOAD_CONST_NEW(c, loc, keys_tuple);
    2290         [ -  + ]:        221 :         ADDOP_I(c, loc, BUILD_CONST_KEY_MAP, default_count);
    2291                 :            :         assert(default_count > 0);
    2292                 :        221 :         return 1;
    2293                 :            :     }
    2294                 :            :     else {
    2295                 :       6315 :         return 0;
    2296                 :            :     }
    2297                 :            : 
    2298                 :          0 : error:
    2299                 :          0 :     Py_XDECREF(keys);
    2300                 :          0 :     return ERROR;
    2301                 :            : }
    2302                 :            : 
    2303                 :            : static int
    2304                 :          0 : compiler_visit_annexpr(struct compiler *c, expr_ty annotation)
    2305                 :            : {
    2306                 :          0 :     location loc = LOC(annotation);
    2307   [ #  #  #  # ]:          0 :     ADDOP_LOAD_CONST_NEW(c, loc, _PyAST_ExprAsUnicode(annotation));
    2308                 :          0 :     return SUCCESS;
    2309                 :            : }
    2310                 :            : 
    2311                 :            : static int
    2312                 :      19050 : compiler_visit_argannotation(struct compiler *c, identifier id,
    2313                 :            :     expr_ty annotation, Py_ssize_t *annotations_len, location loc)
    2314                 :            : {
    2315         [ +  + ]:      19050 :     if (!annotation) {
    2316                 :      18453 :         return SUCCESS;
    2317                 :            :     }
    2318                 :        597 :     PyObject *mangled = _Py_Mangle(c->u->u_private, id);
    2319         [ -  + ]:        597 :     if (!mangled) {
    2320                 :          0 :         return ERROR;
    2321                 :            :     }
    2322         [ -  + ]:        597 :     ADDOP_LOAD_CONST(c, loc, mangled);
    2323                 :        597 :     Py_DECREF(mangled);
    2324                 :            : 
    2325         [ -  + ]:        597 :     if (c->c_future.ff_features & CO_FUTURE_ANNOTATIONS) {
    2326         [ #  # ]:          0 :         VISIT(c, annexpr, annotation);
    2327                 :            :     }
    2328                 :            :     else {
    2329         [ -  + ]:        597 :         if (annotation->kind == Starred_kind) {
    2330                 :            :             // *args: *Ts (where Ts is a TypeVarTuple).
    2331                 :            :             // Do [annotation_value] = [*Ts].
    2332                 :            :             // (Note that in theory we could end up here even for an argument
    2333                 :            :             // other than *args, but in practice the grammar doesn't allow it.)
    2334         [ #  # ]:          0 :             VISIT(c, expr, annotation->v.Starred.value);
    2335         [ #  # ]:          0 :             ADDOP_I(c, loc, UNPACK_SEQUENCE, (Py_ssize_t) 1);
    2336                 :            :         }
    2337                 :            :         else {
    2338         [ -  + ]:        597 :             VISIT(c, expr, annotation);
    2339                 :            :         }
    2340                 :            :     }
    2341                 :        597 :     *annotations_len += 2;
    2342                 :        597 :     return SUCCESS;
    2343                 :            : }
    2344                 :            : 
    2345                 :            : static int
    2346                 :      19203 : compiler_visit_argannotations(struct compiler *c, asdl_arg_seq* args,
    2347                 :            :                               Py_ssize_t *annotations_len, location loc)
    2348                 :            : {
    2349                 :            :     int i;
    2350   [ +  -  +  + ]:      31849 :     for (i = 0; i < asdl_seq_LEN(args); i++) {
    2351                 :      12646 :         arg_ty arg = (arg_ty)asdl_seq_GET(args, i);
    2352         [ -  + ]:      12646 :         RETURN_IF_ERROR(
    2353                 :            :             compiler_visit_argannotation(
    2354                 :            :                         c,
    2355                 :            :                         arg->arg,
    2356                 :            :                         arg->annotation,
    2357                 :            :                         annotations_len,
    2358                 :            :                         loc));
    2359                 :            :     }
    2360                 :      19203 :     return SUCCESS;
    2361                 :            : }
    2362                 :            : 
    2363                 :            : static int
    2364                 :       6401 : compiler_visit_annotations(struct compiler *c, location loc,
    2365                 :            :                            arguments_ty args, expr_ty returns)
    2366                 :            : {
    2367                 :            :     /* Push arg annotation names and values.
    2368                 :            :        The expressions are evaluated out-of-order wrt the source code.
    2369                 :            : 
    2370                 :            :        Return -1 on error, 0 if no annotations pushed, 1 if a annotations is pushed.
    2371                 :            :        */
    2372                 :       6401 :     Py_ssize_t annotations_len = 0;
    2373                 :            : 
    2374         [ -  + ]:       6401 :     RETURN_IF_ERROR(
    2375                 :            :         compiler_visit_argannotations(c, args->args, &annotations_len, loc));
    2376                 :            : 
    2377         [ -  + ]:       6401 :     RETURN_IF_ERROR(
    2378                 :            :         compiler_visit_argannotations(c, args->posonlyargs, &annotations_len, loc));
    2379                 :            : 
    2380   [ +  +  +  + ]:       6401 :     if (args->vararg && args->vararg->annotation) {
    2381         [ -  + ]:          1 :         RETURN_IF_ERROR(
    2382                 :            :             compiler_visit_argannotation(c, args->vararg->arg,
    2383                 :            :                                          args->vararg->annotation, &annotations_len, loc));
    2384                 :            :     }
    2385                 :            : 
    2386         [ -  + ]:       6401 :     RETURN_IF_ERROR(
    2387                 :            :         compiler_visit_argannotations(c, args->kwonlyargs, &annotations_len, loc));
    2388                 :            : 
    2389   [ +  +  +  + ]:       6401 :     if (args->kwarg && args->kwarg->annotation) {
    2390         [ -  + ]:          2 :         RETURN_IF_ERROR(
    2391                 :            :             compiler_visit_argannotation(c, args->kwarg->arg,
    2392                 :            :                                          args->kwarg->annotation, &annotations_len, loc));
    2393                 :            :     }
    2394                 :            : 
    2395         [ -  + ]:       6401 :     RETURN_IF_ERROR(
    2396                 :            :         compiler_visit_argannotation(c, &_Py_ID(return), returns, &annotations_len, loc));
    2397                 :            : 
    2398         [ +  + ]:       6401 :     if (annotations_len) {
    2399         [ -  + ]:        254 :         ADDOP_I(c, loc, BUILD_TUPLE, annotations_len);
    2400                 :        254 :         return 1;
    2401                 :            :     }
    2402                 :            : 
    2403                 :       6147 :     return 0;
    2404                 :            : }
    2405                 :            : 
    2406                 :            : static int
    2407                 :        998 : compiler_visit_defaults(struct compiler *c, arguments_ty args,
    2408                 :            :                         location loc)
    2409                 :            : {
    2410   [ -  +  +  -  :       2774 :     VISIT_SEQ(c, expr, args->defaults);
                   +  + ]
    2411   [ +  -  -  + ]:        998 :     ADDOP_I(c, loc, BUILD_TUPLE, asdl_seq_LEN(args->defaults));
    2412                 :        998 :     return SUCCESS;
    2413                 :            : }
    2414                 :            : 
    2415                 :            : static Py_ssize_t
    2416                 :       6536 : compiler_default_arguments(struct compiler *c, location loc,
    2417                 :            :                            arguments_ty args)
    2418                 :            : {
    2419                 :       6536 :     Py_ssize_t funcflags = 0;
    2420   [ +  -  +  -  :       6536 :     if (args->defaults && asdl_seq_LEN(args->defaults) > 0) {
                   +  + ]
    2421         [ -  + ]:        998 :         RETURN_IF_ERROR(compiler_visit_defaults(c, args, loc));
    2422                 :        998 :         funcflags |= 0x01;
    2423                 :            :     }
    2424         [ +  - ]:       6536 :     if (args->kwonlyargs) {
    2425                 :       6536 :         int res = compiler_visit_kwonlydefaults(c, loc,
    2426                 :            :                                                 args->kwonlyargs,
    2427                 :            :                                                 args->kw_defaults);
    2428         [ -  + ]:       6536 :         RETURN_IF_ERROR(res);
    2429         [ +  + ]:       6536 :         if (res > 0) {
    2430                 :        221 :             funcflags |= 0x02;
    2431                 :            :         }
    2432                 :            :     }
    2433                 :       6536 :     return funcflags;
    2434                 :            : }
    2435                 :            : 
    2436                 :            : static bool
    2437                 :     135505 : forbidden_name(struct compiler *c, location loc, identifier name,
    2438                 :            :                expr_context_ty ctx)
    2439                 :            : {
    2440   [ +  +  -  + ]:     135505 :     if (ctx == Store && _PyUnicode_EqualToASCIIString(name, "__debug__")) {
    2441                 :          0 :         compiler_error(c, loc, "cannot assign to __debug__");
    2442                 :          0 :         return true;
    2443                 :            :     }
    2444   [ +  +  -  + ]:     135505 :     if (ctx == Del && _PyUnicode_EqualToASCIIString(name, "__debug__")) {
    2445                 :          0 :         compiler_error(c, loc, "cannot delete __debug__");
    2446                 :          0 :         return true;
    2447                 :            :     }
    2448                 :     135505 :     return false;
    2449                 :            : }
    2450                 :            : 
    2451                 :            : static int
    2452                 :      26067 : compiler_check_debug_one_arg(struct compiler *c, arg_ty arg)
    2453                 :            : {
    2454         [ +  + ]:      26067 :     if (arg != NULL) {
    2455         [ -  + ]:      13520 :         if (forbidden_name(c, LOC(arg), arg->arg, Store)) {
    2456                 :          0 :             return ERROR;
    2457                 :            :         }
    2458                 :            :     }
    2459                 :      26067 :     return SUCCESS;
    2460                 :            : }
    2461                 :            : 
    2462                 :            : static int
    2463                 :      19608 : compiler_check_debug_args_seq(struct compiler *c, asdl_arg_seq *args)
    2464                 :            : {
    2465         [ +  - ]:      19608 :     if (args != NULL) {
    2466   [ +  -  +  + ]:      32603 :         for (Py_ssize_t i = 0, n = asdl_seq_LEN(args); i < n; i++) {
    2467         [ -  + ]:      12995 :             RETURN_IF_ERROR(
    2468                 :            :                 compiler_check_debug_one_arg(c, asdl_seq_GET(args, i)));
    2469                 :            :         }
    2470                 :            :     }
    2471                 :      19608 :     return SUCCESS;
    2472                 :            : }
    2473                 :            : 
    2474                 :            : static int
    2475                 :       6536 : compiler_check_debug_args(struct compiler *c, arguments_ty args)
    2476                 :            : {
    2477         [ -  + ]:       6536 :     RETURN_IF_ERROR(compiler_check_debug_args_seq(c, args->posonlyargs));
    2478         [ -  + ]:       6536 :     RETURN_IF_ERROR(compiler_check_debug_args_seq(c, args->args));
    2479         [ -  + ]:       6536 :     RETURN_IF_ERROR(compiler_check_debug_one_arg(c, args->vararg));
    2480         [ -  + ]:       6536 :     RETURN_IF_ERROR(compiler_check_debug_args_seq(c, args->kwonlyargs));
    2481         [ -  + ]:       6536 :     RETURN_IF_ERROR(compiler_check_debug_one_arg(c, args->kwarg));
    2482                 :       6536 :     return SUCCESS;
    2483                 :            : }
    2484                 :            : 
    2485                 :            : static inline int
    2486                 :       2390 : insert_instruction(basicblock *block, int pos, struct cfg_instr *instr) {
    2487         [ -  + ]:       2390 :     RETURN_IF_ERROR(basicblock_next_instr(block));
    2488         [ +  + ]:      31932 :     for (int i = block->b_iused - 1; i > pos; i--) {
    2489                 :      29542 :         block->b_instr[i] = block->b_instr[i-1];
    2490                 :            :     }
    2491                 :       2390 :     block->b_instr[pos] = *instr;
    2492                 :       2390 :     return SUCCESS;
    2493                 :            : }
    2494                 :            : 
    2495                 :            : static int
    2496                 :        530 : wrap_in_stopiteration_handler(struct compiler *c)
    2497                 :            : {
    2498         [ -  + ]:        530 :     NEW_JUMP_TARGET_LABEL(c, handler);
    2499                 :            : 
    2500                 :            :     /* Insert SETUP_CLEANUP at start */
    2501         [ -  + ]:        530 :     RETURN_IF_ERROR(
    2502                 :            :         instr_sequence_insert_instruction(
    2503                 :            :             INSTR_SEQUENCE(c), 0,
    2504                 :            :             SETUP_CLEANUP, handler.id, NO_LOCATION));
    2505                 :            : 
    2506         [ -  + ]:        530 :     ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
    2507         [ -  + ]:        530 :     ADDOP(c, NO_LOCATION, RETURN_VALUE);
    2508         [ -  + ]:        530 :     USE_LABEL(c, handler);
    2509         [ -  + ]:        530 :     ADDOP_I(c, NO_LOCATION, CALL_INTRINSIC_1, INTRINSIC_STOPITERATION_ERROR);
    2510         [ -  + ]:        530 :     ADDOP_I(c, NO_LOCATION, RERAISE, 1);
    2511                 :        530 :     return SUCCESS;
    2512                 :            : }
    2513                 :            : 
    2514                 :            : static int
    2515                 :       6401 : compiler_function(struct compiler *c, stmt_ty s, int is_async)
    2516                 :            : {
    2517                 :            :     PyCodeObject *co;
    2518                 :       6401 :     PyObject *docstring = NULL;
    2519                 :            :     arguments_ty args;
    2520                 :            :     expr_ty returns;
    2521                 :            :     identifier name;
    2522                 :            :     asdl_expr_seq* decos;
    2523                 :            :     asdl_stmt_seq *body;
    2524                 :            :     Py_ssize_t i, funcflags;
    2525                 :            :     int annotations;
    2526                 :            :     int scope_type;
    2527                 :            :     int firstlineno;
    2528                 :            : 
    2529         [ +  + ]:       6401 :     if (is_async) {
    2530                 :            :         assert(s->kind == AsyncFunctionDef_kind);
    2531                 :            : 
    2532                 :        158 :         args = s->v.AsyncFunctionDef.args;
    2533                 :        158 :         returns = s->v.AsyncFunctionDef.returns;
    2534                 :        158 :         decos = s->v.AsyncFunctionDef.decorator_list;
    2535                 :        158 :         name = s->v.AsyncFunctionDef.name;
    2536                 :        158 :         body = s->v.AsyncFunctionDef.body;
    2537                 :            : 
    2538                 :        158 :         scope_type = COMPILER_SCOPE_ASYNC_FUNCTION;
    2539                 :            :     } else {
    2540                 :            :         assert(s->kind == FunctionDef_kind);
    2541                 :            : 
    2542                 :       6243 :         args = s->v.FunctionDef.args;
    2543                 :       6243 :         returns = s->v.FunctionDef.returns;
    2544                 :       6243 :         decos = s->v.FunctionDef.decorator_list;
    2545                 :       6243 :         name = s->v.FunctionDef.name;
    2546                 :       6243 :         body = s->v.FunctionDef.body;
    2547                 :            : 
    2548                 :       6243 :         scope_type = COMPILER_SCOPE_FUNCTION;
    2549                 :            :     }
    2550                 :            : 
    2551         [ -  + ]:       6401 :     RETURN_IF_ERROR(compiler_check_debug_args(c, args));
    2552         [ -  + ]:       6401 :     RETURN_IF_ERROR(compiler_decorators(c, decos));
    2553                 :            : 
    2554                 :       6401 :     firstlineno = s->lineno;
    2555   [ +  +  +  - ]:       6401 :     if (asdl_seq_LEN(decos)) {
    2556                 :        573 :         firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
    2557                 :            :     }
    2558                 :            : 
    2559                 :       6401 :     location loc = LOC(s);
    2560                 :       6401 :     funcflags = compiler_default_arguments(c, loc, args);
    2561         [ -  + ]:       6401 :     if (funcflags == -1) {
    2562                 :          0 :         return ERROR;
    2563                 :            :     }
    2564                 :       6401 :     annotations = compiler_visit_annotations(c, loc, args, returns);
    2565         [ -  + ]:       6401 :     RETURN_IF_ERROR(annotations);
    2566         [ +  + ]:       6401 :     if (annotations > 0) {
    2567                 :        254 :         funcflags |= 0x04;
    2568                 :            :     }
    2569                 :            : 
    2570         [ -  + ]:       6401 :     RETURN_IF_ERROR(
    2571                 :            :         compiler_enter_scope(c, name, scope_type, (void *)s, firstlineno));
    2572                 :            : 
    2573                 :            :     /* if not -OO mode, add docstring */
    2574         [ +  - ]:       6401 :     if (c->c_optimize < 2) {
    2575                 :       6401 :         docstring = _PyAST_GetDocString(body);
    2576                 :            :     }
    2577   [ +  +  -  + ]:       6401 :     if (compiler_add_const(c->c_const_cache, c->u, docstring ? docstring : Py_None) < 0) {
    2578                 :          0 :         compiler_exit_scope(c);
    2579                 :          0 :         return ERROR;
    2580                 :            :     }
    2581                 :            : 
    2582         [ +  - ]:       6401 :     c->u->u_argcount = asdl_seq_LEN(args->args);
    2583         [ +  - ]:       6401 :     c->u->u_posonlyargcount = asdl_seq_LEN(args->posonlyargs);
    2584         [ +  - ]:       6401 :     c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs);
    2585   [ +  -  +  + ]:      25786 :     for (i = docstring ? 1 : 0; i < asdl_seq_LEN(body); i++) {
    2586         [ -  + ]:      19385 :         VISIT_IN_SCOPE(c, stmt, (stmt_ty)asdl_seq_GET(body, i));
    2587                 :            :     }
    2588   [ +  +  +  + ]:       6401 :     if (c->u->u_ste->ste_coroutine || c->u->u_ste->ste_generator) {
    2589         [ -  + ]:        333 :         if (wrap_in_stopiteration_handler(c) < 0) {
    2590                 :          0 :             compiler_exit_scope(c);
    2591                 :          0 :             return ERROR;
    2592                 :            :         }
    2593                 :            :     }
    2594                 :       6401 :     co = assemble(c, 1);
    2595                 :       6401 :     compiler_exit_scope(c);
    2596         [ -  + ]:       6401 :     if (co == NULL) {
    2597                 :          0 :         Py_XDECREF(co);
    2598                 :          0 :         return ERROR;
    2599                 :            :     }
    2600         [ -  + ]:       6401 :     if (compiler_make_closure(c, loc, co, funcflags) < 0) {
    2601                 :          0 :         Py_DECREF(co);
    2602                 :          0 :         return ERROR;
    2603                 :            :     }
    2604                 :       6401 :     Py_DECREF(co);
    2605                 :            : 
    2606         [ -  + ]:       6401 :     RETURN_IF_ERROR(compiler_apply_decorators(c, decos));
    2607                 :       6401 :     return compiler_nameop(c, loc, name, Store);
    2608                 :            : }
    2609                 :            : 
    2610                 :            : static int
    2611                 :        733 : compiler_class(struct compiler *c, stmt_ty s)
    2612                 :            : {
    2613                 :            :     PyCodeObject *co;
    2614                 :            :     int i, firstlineno;
    2615                 :        733 :     asdl_expr_seq *decos = s->v.ClassDef.decorator_list;
    2616                 :            : 
    2617         [ -  + ]:        733 :     RETURN_IF_ERROR(compiler_decorators(c, decos));
    2618                 :            : 
    2619                 :        733 :     firstlineno = s->lineno;
    2620   [ +  +  +  - ]:        733 :     if (asdl_seq_LEN(decos)) {
    2621                 :         17 :         firstlineno = ((expr_ty)asdl_seq_GET(decos, 0))->lineno;
    2622                 :            :     }
    2623                 :            : 
    2624                 :            :     /* ultimately generate code for:
    2625                 :            :          <name> = __build_class__(<func>, <name>, *<bases>, **<keywords>)
    2626                 :            :        where:
    2627                 :            :          <func> is a zero arg function/closure created from the class body.
    2628                 :            :             It mutates its locals to build the class namespace.
    2629                 :            :          <name> is the class name
    2630                 :            :          <bases> is the positional arguments and *varargs argument
    2631                 :            :          <keywords> is the keyword arguments and **kwds argument
    2632                 :            :        This borrows from compiler_call.
    2633                 :            :     */
    2634                 :            :     /* 1. compile the class body into a code object */
    2635         [ -  + ]:        733 :     RETURN_IF_ERROR(
    2636                 :            :         compiler_enter_scope(c, s->v.ClassDef.name,
    2637                 :            :                              COMPILER_SCOPE_CLASS, (void *)s, firstlineno));
    2638                 :            : 
    2639                 :            :     /* this block represents what we do in the new scope */
    2640                 :            :     {
    2641                 :        733 :         location loc = LOCATION(firstlineno, firstlineno, 0, 0);
    2642                 :            :         /* use the class name for name mangling */
    2643                 :        733 :         Py_XSETREF(c->u->u_private, Py_NewRef(s->v.ClassDef.name));
    2644                 :            :         /* load (global) __name__ ... */
    2645         [ -  + ]:        733 :         if (compiler_nameop(c, loc, &_Py_ID(__name__), Load) < 0) {
    2646                 :          0 :             compiler_exit_scope(c);
    2647                 :          0 :             return ERROR;
    2648                 :            :         }
    2649                 :            :         /* ... and store it as __module__ */
    2650         [ -  + ]:        733 :         if (compiler_nameop(c, loc, &_Py_ID(__module__), Store) < 0) {
    2651                 :          0 :             compiler_exit_scope(c);
    2652                 :          0 :             return ERROR;
    2653                 :            :         }
    2654                 :            :         assert(c->u->u_qualname);
    2655         [ -  + ]:        733 :         ADDOP_LOAD_CONST(c, loc, c->u->u_qualname);
    2656         [ -  + ]:        733 :         if (compiler_nameop(c, loc, &_Py_ID(__qualname__), Store) < 0) {
    2657                 :          0 :             compiler_exit_scope(c);
    2658                 :          0 :             return ERROR;
    2659                 :            :         }
    2660                 :            :         /* compile the body proper */
    2661         [ -  + ]:        733 :         if (compiler_body(c, loc, s->v.ClassDef.body) < 0) {
    2662                 :          0 :             compiler_exit_scope(c);
    2663                 :          0 :             return ERROR;
    2664                 :            :         }
    2665                 :            :         /* The following code is artificial */
    2666                 :            :         /* Return __classcell__ if it is referenced, otherwise return None */
    2667         [ +  + ]:        733 :         if (c->u->u_ste->ste_needs_class_closure) {
    2668                 :            :             /* Store __classcell__ into class namespace & return it */
    2669                 :        112 :             i = compiler_lookup_arg(c->u->u_cellvars, &_Py_ID(__class__));
    2670         [ -  + ]:        112 :             if (i < 0) {
    2671                 :          0 :                 compiler_exit_scope(c);
    2672                 :          0 :                 return ERROR;
    2673                 :            :             }
    2674                 :            :             assert(i == 0);
    2675         [ -  + ]:        112 :             ADDOP_I(c, NO_LOCATION, LOAD_CLOSURE, i);
    2676         [ -  + ]:        112 :             ADDOP_I(c, NO_LOCATION, COPY, 1);
    2677         [ -  + ]:        112 :             if (compiler_nameop(c, NO_LOCATION, &_Py_ID(__classcell__), Store) < 0) {
    2678                 :          0 :                 compiler_exit_scope(c);
    2679                 :          0 :                 return ERROR;
    2680                 :            :             }
    2681                 :            :         }
    2682                 :            :         else {
    2683                 :            :             /* No methods referenced __class__, so just return None */
    2684                 :            :             assert(PyDict_GET_SIZE(c->u->u_cellvars) == 0);
    2685         [ -  + ]:        621 :             ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
    2686                 :            :         }
    2687         [ -  + ]:        733 :         ADDOP_IN_SCOPE(c, NO_LOCATION, RETURN_VALUE);
    2688                 :            :         /* create the code object */
    2689                 :        733 :         co = assemble(c, 1);
    2690                 :            :     }
    2691                 :            :     /* leave the new scope */
    2692                 :        733 :     compiler_exit_scope(c);
    2693         [ -  + ]:        733 :     if (co == NULL) {
    2694                 :          0 :         return ERROR;
    2695                 :            :     }
    2696                 :            : 
    2697                 :        733 :     location loc = LOC(s);
    2698                 :            :     /* 2. load the 'build_class' function */
    2699         [ -  + ]:        733 :     ADDOP(c, loc, PUSH_NULL);
    2700         [ -  + ]:        733 :     ADDOP(c, loc, LOAD_BUILD_CLASS);
    2701                 :            : 
    2702                 :            :     /* 3. load a function (or closure) made from the code object */
    2703         [ -  + ]:        733 :     if (compiler_make_closure(c, loc, co, 0) < 0) {
    2704                 :          0 :         Py_DECREF(co);
    2705                 :          0 :         return ERROR;
    2706                 :            :     }
    2707                 :        733 :     Py_DECREF(co);
    2708                 :            : 
    2709                 :            :     /* 4. load class name */
    2710         [ -  + ]:        733 :     ADDOP_LOAD_CONST(c, loc, s->v.ClassDef.name);
    2711                 :            : 
    2712                 :            :     /* 5. generate the rest of the code for the call */
    2713         [ -  + ]:        733 :     RETURN_IF_ERROR(compiler_call_helper(c, loc, 2,
    2714                 :            :                                          s->v.ClassDef.bases,
    2715                 :            :                                          s->v.ClassDef.keywords));
    2716                 :            : 
    2717                 :            :     /* 6. apply decorators */
    2718         [ -  + ]:        733 :     RETURN_IF_ERROR(compiler_apply_decorators(c, decos));
    2719                 :            : 
    2720                 :            :     /* 7. store into <name> */
    2721         [ -  + ]:        733 :     RETURN_IF_ERROR(compiler_nameop(c, loc, s->v.ClassDef.name, Store));
    2722                 :        733 :     return SUCCESS;
    2723                 :            : }
    2724                 :            : 
    2725                 :            : /* Return false if the expression is a constant value except named singletons.
    2726                 :            :    Return true otherwise. */
    2727                 :            : static bool
    2728                 :      12784 : check_is_arg(expr_ty e)
    2729                 :            : {
    2730         [ +  + ]:      12784 :     if (e->kind != Constant_kind) {
    2731                 :       8880 :         return true;
    2732                 :            :     }
    2733                 :       3904 :     PyObject *value = e->v.Constant.value;
    2734                 :            :     return (value == Py_None
    2735         [ +  + ]:       2093 :          || value == Py_False
    2736         [ +  + ]:       2085 :          || value == Py_True
    2737   [ +  +  +  + ]:       5997 :          || value == Py_Ellipsis);
    2738                 :            : }
    2739                 :            : 
    2740                 :            : /* Check operands of identity checks ("is" and "is not").
    2741                 :            :    Emit a warning if any operand is a constant except named singletons.
    2742                 :            :  */
    2743                 :            : static int
    2744                 :       6367 : check_compare(struct compiler *c, expr_ty e)
    2745                 :            : {
    2746                 :            :     Py_ssize_t i, n;
    2747                 :       6367 :     bool left = check_is_arg(e->v.Compare.left);
    2748         [ +  - ]:       6367 :     n = asdl_seq_LEN(e->v.Compare.ops);
    2749         [ +  + ]:      12784 :     for (i = 0; i < n; i++) {
    2750                 :       6417 :         cmpop_ty op = (cmpop_ty)asdl_seq_GET(e->v.Compare.ops, i);
    2751                 :       6417 :         bool right = check_is_arg((expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
    2752   [ +  +  +  + ]:       6417 :         if (op == Is || op == IsNot) {
    2753   [ +  -  -  + ]:       2359 :             if (!right || !left) {
    2754                 :          0 :                 const char *msg = (op == Is)
    2755                 :            :                         ? "\"is\" with a literal. Did you mean \"==\"?"
    2756         [ #  # ]:          0 :                         : "\"is not\" with a literal. Did you mean \"!=\"?";
    2757                 :          0 :                 return compiler_warn(c, LOC(e), msg);
    2758                 :            :             }
    2759                 :            :         }
    2760                 :       6417 :         left = right;
    2761                 :            :     }
    2762                 :       6367 :     return SUCCESS;
    2763                 :            : }
    2764                 :            : 
    2765                 :       6426 : static int compiler_addcompare(struct compiler *c, location loc,
    2766                 :            :                                cmpop_ty op)
    2767                 :            : {
    2768                 :            :     int cmp;
    2769   [ +  +  +  +  :       6426 :     switch (op) {
          +  +  +  +  +  
                   +  - ]
    2770                 :       1615 :     case Eq:
    2771                 :       1615 :         cmp = Py_EQ;
    2772                 :       1615 :         break;
    2773                 :        441 :     case NotEq:
    2774                 :        441 :         cmp = Py_NE;
    2775                 :        441 :         break;
    2776                 :        368 :     case Lt:
    2777                 :        368 :         cmp = Py_LT;
    2778                 :        368 :         break;
    2779                 :        187 :     case LtE:
    2780                 :        187 :         cmp = Py_LE;
    2781                 :        187 :         break;
    2782                 :        308 :     case Gt:
    2783                 :        308 :         cmp = Py_GT;
    2784                 :        308 :         break;
    2785                 :        156 :     case GtE:
    2786                 :        156 :         cmp = Py_GE;
    2787                 :        156 :         break;
    2788                 :       1337 :     case Is:
    2789         [ -  + ]:       1337 :         ADDOP_I(c, loc, IS_OP, 0);
    2790                 :       1337 :         return SUCCESS;
    2791                 :       1023 :     case IsNot:
    2792         [ -  + ]:       1023 :         ADDOP_I(c, loc, IS_OP, 1);
    2793                 :       1023 :         return SUCCESS;
    2794                 :        703 :     case In:
    2795         [ -  + ]:        703 :         ADDOP_I(c, loc, CONTAINS_OP, 0);
    2796                 :        703 :         return SUCCESS;
    2797                 :        288 :     case NotIn:
    2798         [ -  + ]:        288 :         ADDOP_I(c, loc, CONTAINS_OP, 1);
    2799                 :        288 :         return SUCCESS;
    2800                 :          0 :     default:
    2801                 :          0 :         Py_UNREACHABLE();
    2802                 :            :     }
    2803                 :            :     /* cmp goes in top bits of the oparg, while the low bits are used by quickened
    2804                 :            :      * versions of this opcode to store the comparison mask. */
    2805         [ -  + ]:       3075 :     ADDOP_I(c, loc, COMPARE_OP, cmp << 4);
    2806                 :       3075 :     return SUCCESS;
    2807                 :            : }
    2808                 :            : 
    2809                 :            : 
    2810                 :            : 
    2811                 :            : static int
    2812                 :      14708 : compiler_jump_if(struct compiler *c, location loc,
    2813                 :            :                  expr_ty e, jump_target_label next, int cond)
    2814                 :            : {
    2815   [ +  +  +  +  :      14708 :     switch (e->kind) {
                      + ]
    2816                 :       1538 :     case UnaryOp_kind:
    2817         [ +  - ]:       1538 :         if (e->v.UnaryOp.op == Not) {
    2818                 :       1538 :             return compiler_jump_if(c, loc, e->v.UnaryOp.operand, next, !cond);
    2819                 :            :         }
    2820                 :            :         /* fallback to general implementation */
    2821                 :          0 :         break;
    2822                 :       1429 :     case BoolOp_kind: {
    2823                 :       1429 :         asdl_expr_seq *s = e->v.BoolOp.values;
    2824         [ +  - ]:       1429 :         Py_ssize_t i, n = asdl_seq_LEN(s) - 1;
    2825                 :            :         assert(n >= 0);
    2826                 :       1429 :         int cond2 = e->v.BoolOp.op == Or;
    2827                 :       1429 :         jump_target_label next2 = next;
    2828         [ +  + ]:       1429 :         if (!cond2 != !cond) {
    2829         [ -  + ]:        469 :             NEW_JUMP_TARGET_LABEL(c, new_next2);
    2830                 :        469 :             next2 = new_next2;
    2831                 :            :         }
    2832         [ +  + ]:       3067 :         for (i = 0; i < n; ++i) {
    2833         [ -  + ]:       1638 :             RETURN_IF_ERROR(
    2834                 :            :                 compiler_jump_if(c, loc, (expr_ty)asdl_seq_GET(s, i), next2, cond2));
    2835                 :            :         }
    2836         [ -  + ]:       1429 :         RETURN_IF_ERROR(
    2837                 :            :             compiler_jump_if(c, loc, (expr_ty)asdl_seq_GET(s, n), next, cond));
    2838         [ +  + ]:       1429 :         if (!SAME_LABEL(next2, next)) {
    2839         [ -  + ]:        469 :             USE_LABEL(c, next2);
    2840                 :            :         }
    2841                 :       1429 :         return SUCCESS;
    2842                 :            :     }
    2843                 :          2 :     case IfExp_kind: {
    2844         [ -  + ]:          2 :         NEW_JUMP_TARGET_LABEL(c, end);
    2845         [ -  + ]:          2 :         NEW_JUMP_TARGET_LABEL(c, next2);
    2846         [ -  + ]:          2 :         RETURN_IF_ERROR(
    2847                 :            :             compiler_jump_if(c, loc, e->v.IfExp.test, next2, 0));
    2848         [ -  + ]:          2 :         RETURN_IF_ERROR(
    2849                 :            :             compiler_jump_if(c, loc, e->v.IfExp.body, next, cond));
    2850         [ -  + ]:          2 :         ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
    2851                 :            : 
    2852         [ -  + ]:          2 :         USE_LABEL(c, next2);
    2853         [ -  + ]:          2 :         RETURN_IF_ERROR(
    2854                 :            :             compiler_jump_if(c, loc, e->v.IfExp.orelse, next, cond));
    2855                 :            : 
    2856         [ -  + ]:          2 :         USE_LABEL(c, end);
    2857                 :          2 :         return SUCCESS;
    2858                 :            :     }
    2859                 :       5835 :     case Compare_kind: {
    2860         [ +  - ]:       5835 :         Py_ssize_t n = asdl_seq_LEN(e->v.Compare.ops) - 1;
    2861         [ +  + ]:       5835 :         if (n > 0) {
    2862         [ -  + ]:         46 :             RETURN_IF_ERROR(check_compare(c, e));
    2863         [ -  + ]:         46 :             NEW_JUMP_TARGET_LABEL(c, cleanup);
    2864         [ -  + ]:         46 :             VISIT(c, expr, e->v.Compare.left);
    2865         [ +  + ]:         92 :             for (Py_ssize_t i = 0; i < n; i++) {
    2866         [ -  + ]:         46 :                 VISIT(c, expr,
    2867                 :            :                     (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
    2868         [ -  + ]:         46 :                 ADDOP_I(c, LOC(e), SWAP, 2);
    2869         [ -  + ]:         46 :                 ADDOP_I(c, LOC(e), COPY, 2);
    2870         [ -  + ]:         46 :                 ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, i));
    2871         [ -  + ]:         46 :                 ADDOP_JUMP(c, LOC(e), POP_JUMP_IF_FALSE, cleanup);
    2872                 :            :             }
    2873         [ -  + ]:         46 :             VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
    2874         [ -  + ]:         46 :             ADDOP_COMPARE(c, LOC(e), asdl_seq_GET(e->v.Compare.ops, n));
    2875   [ +  +  -  + ]:         46 :             ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
    2876         [ -  + ]:         46 :             NEW_JUMP_TARGET_LABEL(c, end);
    2877         [ -  + ]:         46 :             ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
    2878                 :            : 
    2879         [ -  + ]:         46 :             USE_LABEL(c, cleanup);
    2880         [ -  + ]:         46 :             ADDOP(c, LOC(e), POP_TOP);
    2881         [ +  + ]:         46 :             if (!cond) {
    2882         [ -  + ]:         15 :                 ADDOP_JUMP(c, NO_LOCATION, JUMP, next);
    2883                 :            :             }
    2884                 :            : 
    2885         [ -  + ]:         46 :             USE_LABEL(c, end);
    2886                 :         46 :             return SUCCESS;
    2887                 :            :         }
    2888                 :            :         /* fallback to general implementation */
    2889                 :       5789 :         break;
    2890                 :            :     }
    2891                 :       5904 :     default:
    2892                 :            :         /* fallback to general implementation */
    2893                 :       5904 :         break;
    2894                 :            :     }
    2895                 :            : 
    2896                 :            :     /* general implementation */
    2897         [ -  + ]:      11693 :     VISIT(c, expr, e);
    2898   [ +  +  -  + ]:      11693 :     ADDOP_JUMP(c, LOC(e), cond ? POP_JUMP_IF_TRUE : POP_JUMP_IF_FALSE, next);
    2899                 :      11693 :     return SUCCESS;
    2900                 :            : }
    2901                 :            : 
    2902                 :            : static int
    2903                 :        231 : compiler_ifexp(struct compiler *c, expr_ty e)
    2904                 :            : {
    2905                 :            :     assert(e->kind == IfExp_kind);
    2906         [ -  + ]:        231 :     NEW_JUMP_TARGET_LABEL(c, end);
    2907         [ -  + ]:        231 :     NEW_JUMP_TARGET_LABEL(c, next);
    2908                 :            : 
    2909         [ -  + ]:        231 :     RETURN_IF_ERROR(
    2910                 :            :         compiler_jump_if(c, LOC(e), e->v.IfExp.test, next, 0));
    2911                 :            : 
    2912         [ -  + ]:        231 :     VISIT(c, expr, e->v.IfExp.body);
    2913         [ -  + ]:        231 :     ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
    2914                 :            : 
    2915         [ -  + ]:        231 :     USE_LABEL(c, next);
    2916         [ -  + ]:        231 :     VISIT(c, expr, e->v.IfExp.orelse);
    2917                 :            : 
    2918         [ -  + ]:        231 :     USE_LABEL(c, end);
    2919                 :        231 :     return SUCCESS;
    2920                 :            : }
    2921                 :            : 
    2922                 :            : static int
    2923                 :        135 : compiler_lambda(struct compiler *c, expr_ty e)
    2924                 :            : {
    2925                 :            :     PyCodeObject *co;
    2926                 :            :     Py_ssize_t funcflags;
    2927                 :        135 :     arguments_ty args = e->v.Lambda.args;
    2928                 :            :     assert(e->kind == Lambda_kind);
    2929                 :            : 
    2930         [ -  + ]:        135 :     RETURN_IF_ERROR(compiler_check_debug_args(c, args));
    2931                 :            : 
    2932                 :        135 :     location loc = LOC(e);
    2933                 :        135 :     funcflags = compiler_default_arguments(c, loc, args);
    2934         [ -  + ]:        135 :     if (funcflags == -1) {
    2935                 :          0 :         return ERROR;
    2936                 :            :     }
    2937                 :            : 
    2938                 :            :     _Py_DECLARE_STR(anon_lambda, "<lambda>");
    2939         [ -  + ]:        135 :     RETURN_IF_ERROR(
    2940                 :            :         compiler_enter_scope(c, &_Py_STR(anon_lambda), COMPILER_SCOPE_LAMBDA,
    2941                 :            :                              (void *)e, e->lineno));
    2942                 :            : 
    2943                 :            :     /* Make None the first constant, so the lambda can't have a
    2944                 :            :        docstring. */
    2945         [ -  + ]:        135 :     RETURN_IF_ERROR(compiler_add_const(c->c_const_cache, c->u, Py_None));
    2946                 :            : 
    2947         [ +  - ]:        135 :     c->u->u_argcount = asdl_seq_LEN(args->args);
    2948         [ +  - ]:        135 :     c->u->u_posonlyargcount = asdl_seq_LEN(args->posonlyargs);
    2949         [ +  - ]:        135 :     c->u->u_kwonlyargcount = asdl_seq_LEN(args->kwonlyargs);
    2950         [ -  + ]:        135 :     VISIT_IN_SCOPE(c, expr, e->v.Lambda.body);
    2951         [ +  + ]:        135 :     if (c->u->u_ste->ste_generator) {
    2952                 :          2 :         co = assemble(c, 0);
    2953                 :            :     }
    2954                 :            :     else {
    2955                 :        133 :         location loc = LOCATION(e->lineno, e->lineno, 0, 0);
    2956         [ -  + ]:        133 :         ADDOP_IN_SCOPE(c, loc, RETURN_VALUE);
    2957                 :        133 :         co = assemble(c, 1);
    2958                 :            :     }
    2959                 :        135 :     compiler_exit_scope(c);
    2960         [ -  + ]:        135 :     if (co == NULL) {
    2961                 :          0 :         return ERROR;
    2962                 :            :     }
    2963                 :            : 
    2964         [ -  + ]:        135 :     if (compiler_make_closure(c, loc, co, funcflags) < 0) {
    2965                 :          0 :         Py_DECREF(co);
    2966                 :          0 :         return ERROR;
    2967                 :            :     }
    2968                 :        135 :     Py_DECREF(co);
    2969                 :            : 
    2970                 :        135 :     return SUCCESS;
    2971                 :            : }
    2972                 :            : 
    2973                 :            : static int
    2974                 :       8896 : compiler_if(struct compiler *c, stmt_ty s)
    2975                 :            : {
    2976                 :            :     jump_target_label next;
    2977                 :            :     assert(s->kind == If_kind);
    2978         [ -  + ]:       8896 :     NEW_JUMP_TARGET_LABEL(c, end);
    2979   [ +  +  +  - ]:       8896 :     if (asdl_seq_LEN(s->v.If.orelse)) {
    2980         [ -  + ]:       2430 :         NEW_JUMP_TARGET_LABEL(c, orelse);
    2981                 :       2430 :         next = orelse;
    2982                 :            :     }
    2983                 :            :     else {
    2984                 :       6466 :         next = end;
    2985                 :            :     }
    2986         [ -  + ]:       8896 :     RETURN_IF_ERROR(
    2987                 :            :         compiler_jump_if(c, LOC(s), s->v.If.test, next, 0));
    2988                 :            : 
    2989   [ -  +  +  -  :      22071 :     VISIT_SEQ(c, stmt, s->v.If.body);
                   +  + ]
    2990   [ +  +  +  - ]:       8896 :     if (asdl_seq_LEN(s->v.If.orelse)) {
    2991         [ -  + ]:       2430 :         ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
    2992                 :            : 
    2993         [ -  + ]:       2430 :         USE_LABEL(c, next);
    2994   [ -  +  +  -  :       5605 :         VISIT_SEQ(c, stmt, s->v.If.orelse);
                   +  + ]
    2995                 :            :     }
    2996                 :            : 
    2997         [ -  + ]:       8896 :     USE_LABEL(c, end);
    2998                 :       8896 :     return SUCCESS;
    2999                 :            : }
    3000                 :            : 
    3001                 :            : static int
    3002                 :       1236 : compiler_for(struct compiler *c, stmt_ty s)
    3003                 :            : {
    3004                 :       1236 :     location loc = LOC(s);
    3005         [ -  + ]:       1236 :     NEW_JUMP_TARGET_LABEL(c, start);
    3006         [ -  + ]:       1236 :     NEW_JUMP_TARGET_LABEL(c, body);
    3007         [ -  + ]:       1236 :     NEW_JUMP_TARGET_LABEL(c, cleanup);
    3008         [ -  + ]:       1236 :     NEW_JUMP_TARGET_LABEL(c, end);
    3009                 :            : 
    3010         [ -  + ]:       1236 :     RETURN_IF_ERROR(compiler_push_fblock(c, loc, FOR_LOOP, start, end, NULL));
    3011                 :            : 
    3012         [ -  + ]:       1236 :     VISIT(c, expr, s->v.For.iter);
    3013         [ -  + ]:       1236 :     ADDOP(c, loc, GET_ITER);
    3014                 :            : 
    3015         [ -  + ]:       1236 :     USE_LABEL(c, start);
    3016         [ -  + ]:       1236 :     ADDOP_JUMP(c, loc, FOR_ITER, cleanup);
    3017                 :            : 
    3018         [ -  + ]:       1236 :     USE_LABEL(c, body);
    3019         [ -  + ]:       1236 :     VISIT(c, expr, s->v.For.target);
    3020   [ -  +  +  -  :       3601 :     VISIT_SEQ(c, stmt, s->v.For.body);
                   +  + ]
    3021                 :            :     /* Mark jump as artificial */
    3022         [ -  + ]:       1236 :     ADDOP_JUMP(c, NO_LOCATION, JUMP, start);
    3023                 :            : 
    3024         [ -  + ]:       1236 :     USE_LABEL(c, cleanup);
    3025         [ -  + ]:       1236 :     ADDOP(c, NO_LOCATION, END_FOR);
    3026                 :            : 
    3027                 :       1236 :     compiler_pop_fblock(c, FOR_LOOP, start);
    3028                 :            : 
    3029   [ -  +  +  +  :       1299 :     VISIT_SEQ(c, stmt, s->v.For.orelse);
                   +  + ]
    3030                 :            : 
    3031         [ -  + ]:       1236 :     USE_LABEL(c, end);
    3032                 :       1236 :     return SUCCESS;
    3033                 :            : }
    3034                 :            : 
    3035                 :            : 
    3036                 :            : static int
    3037                 :          0 : compiler_async_for(struct compiler *c, stmt_ty s)
    3038                 :            : {
    3039                 :          0 :     location loc = LOC(s);
    3040   [ #  #  #  # ]:          0 :     if (IS_TOP_LEVEL_AWAIT(c)){
    3041                 :          0 :         c->u->u_ste->ste_coroutine = 1;
    3042         [ #  # ]:          0 :     } else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION) {
    3043                 :          0 :         return compiler_error(c, loc, "'async for' outside async function");
    3044                 :            :     }
    3045                 :            : 
    3046         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, start);
    3047         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, except);
    3048         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, end);
    3049                 :            : 
    3050         [ #  # ]:          0 :     VISIT(c, expr, s->v.AsyncFor.iter);
    3051         [ #  # ]:          0 :     ADDOP(c, loc, GET_AITER);
    3052                 :            : 
    3053         [ #  # ]:          0 :     USE_LABEL(c, start);
    3054         [ #  # ]:          0 :     RETURN_IF_ERROR(compiler_push_fblock(c, loc, FOR_LOOP, start, end, NULL));
    3055                 :            : 
    3056                 :            :     /* SETUP_FINALLY to guard the __anext__ call */
    3057         [ #  # ]:          0 :     ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
    3058         [ #  # ]:          0 :     ADDOP(c, loc, GET_ANEXT);
    3059         [ #  # ]:          0 :     ADDOP_LOAD_CONST(c, loc, Py_None);
    3060         [ #  # ]:          0 :     ADD_YIELD_FROM(c, loc, 1);
    3061         [ #  # ]:          0 :     ADDOP(c, loc, POP_BLOCK);  /* for SETUP_FINALLY */
    3062                 :            : 
    3063                 :            :     /* Success block for __anext__ */
    3064         [ #  # ]:          0 :     VISIT(c, expr, s->v.AsyncFor.target);
    3065   [ #  #  #  #  :          0 :     VISIT_SEQ(c, stmt, s->v.AsyncFor.body);
                   #  # ]
    3066                 :            :     /* Mark jump as artificial */
    3067         [ #  # ]:          0 :     ADDOP_JUMP(c, NO_LOCATION, JUMP, start);
    3068                 :            : 
    3069                 :          0 :     compiler_pop_fblock(c, FOR_LOOP, start);
    3070                 :            : 
    3071                 :            :     /* Except block for __anext__ */
    3072         [ #  # ]:          0 :     USE_LABEL(c, except);
    3073                 :            : 
    3074                 :            :     /* Use same line number as the iterator,
    3075                 :            :      * as the END_ASYNC_FOR succeeds the `for`, not the body. */
    3076                 :          0 :     loc = LOC(s->v.AsyncFor.iter);
    3077         [ #  # ]:          0 :     ADDOP(c, loc, END_ASYNC_FOR);
    3078                 :            : 
    3079                 :            :     /* `else` block */
    3080   [ #  #  #  #  :          0 :     VISIT_SEQ(c, stmt, s->v.For.orelse);
                   #  # ]
    3081                 :            : 
    3082         [ #  # ]:          0 :     USE_LABEL(c, end);
    3083                 :          0 :     return SUCCESS;
    3084                 :            : }
    3085                 :            : 
    3086                 :            : static int
    3087                 :        305 : compiler_while(struct compiler *c, stmt_ty s)
    3088                 :            : {
    3089         [ -  + ]:        305 :     NEW_JUMP_TARGET_LABEL(c, loop);
    3090         [ -  + ]:        305 :     NEW_JUMP_TARGET_LABEL(c, body);
    3091         [ -  + ]:        305 :     NEW_JUMP_TARGET_LABEL(c, end);
    3092         [ -  + ]:        305 :     NEW_JUMP_TARGET_LABEL(c, anchor);
    3093                 :            : 
    3094         [ -  + ]:        305 :     USE_LABEL(c, loop);
    3095                 :            : 
    3096         [ -  + ]:        305 :     RETURN_IF_ERROR(compiler_push_fblock(c, LOC(s), WHILE_LOOP, loop, end, NULL));
    3097         [ -  + ]:        305 :     RETURN_IF_ERROR(compiler_jump_if(c, LOC(s), s->v.While.test, anchor, 0));
    3098                 :            : 
    3099         [ -  + ]:        305 :     USE_LABEL(c, body);
    3100   [ -  +  +  -  :       1214 :     VISIT_SEQ(c, stmt, s->v.While.body);
                   +  + ]
    3101         [ -  + ]:        305 :     RETURN_IF_ERROR(compiler_jump_if(c, LOC(s), s->v.While.test, body, 1));
    3102                 :            : 
    3103                 :        305 :     compiler_pop_fblock(c, WHILE_LOOP, loop);
    3104                 :            : 
    3105         [ -  + ]:        305 :     USE_LABEL(c, anchor);
    3106         [ +  + ]:        305 :     if (s->v.While.orelse) {
    3107   [ -  +  +  -  :         10 :         VISIT_SEQ(c, stmt, s->v.While.orelse);
                   +  + ]
    3108                 :            :     }
    3109                 :            : 
    3110         [ -  + ]:        305 :     USE_LABEL(c, end);
    3111                 :        305 :     return SUCCESS;
    3112                 :            : }
    3113                 :            : 
    3114                 :            : static int
    3115                 :       5842 : compiler_return(struct compiler *c, stmt_ty s)
    3116                 :            : {
    3117                 :       5842 :     location loc = LOC(s);
    3118         [ +  + ]:      11356 :     int preserve_tos = ((s->v.Return.value != NULL) &&
    3119         [ +  + ]:       5514 :                         (s->v.Return.value->kind != Constant_kind));
    3120         [ -  + ]:       5842 :     if (c->u->u_ste->ste_type != FunctionBlock) {
    3121                 :          0 :         return compiler_error(c, loc, "'return' outside function");
    3122                 :            :     }
    3123         [ +  + ]:       5842 :     if (s->v.Return.value != NULL &&
    3124   [ +  +  -  + ]:       5514 :         c->u->u_ste->ste_coroutine && c->u->u_ste->ste_generator)
    3125                 :            :     {
    3126                 :          0 :         return compiler_error(c, loc, "'return' with value in async generator");
    3127                 :            :     }
    3128                 :            : 
    3129         [ +  + ]:       5842 :     if (preserve_tos) {
    3130         [ -  + ]:       4825 :         VISIT(c, expr, s->v.Return.value);
    3131                 :            :     } else {
    3132                 :            :         /* Emit instruction with line number for return value */
    3133         [ +  + ]:       1017 :         if (s->v.Return.value != NULL) {
    3134                 :        689 :             loc = LOC(s->v.Return.value);
    3135         [ -  + ]:        689 :             ADDOP(c, loc, NOP);
    3136                 :            :         }
    3137                 :            :     }
    3138   [ +  +  +  + ]:       5842 :     if (s->v.Return.value == NULL || s->v.Return.value->lineno != s->lineno) {
    3139                 :        338 :         loc = LOC(s);
    3140         [ -  + ]:        338 :         ADDOP(c, loc, NOP);
    3141                 :            :     }
    3142                 :            : 
    3143         [ -  + ]:       5842 :     RETURN_IF_ERROR(compiler_unwind_fblock_stack(c, &loc, preserve_tos, NULL));
    3144         [ +  + ]:       5842 :     if (s->v.Return.value == NULL) {
    3145         [ -  + ]:        328 :         ADDOP_LOAD_CONST(c, loc, Py_None);
    3146                 :            :     }
    3147         [ +  + ]:       5514 :     else if (!preserve_tos) {
    3148         [ -  + ]:        689 :         ADDOP_LOAD_CONST(c, loc, s->v.Return.value->v.Constant.value);
    3149                 :            :     }
    3150         [ -  + ]:       5842 :     ADDOP(c, loc, RETURN_VALUE);
    3151                 :            : 
    3152                 :       5842 :     return SUCCESS;
    3153                 :            : }
    3154                 :            : 
    3155                 :            : static int
    3156                 :        275 : compiler_break(struct compiler *c, location loc)
    3157                 :            : {
    3158                 :        275 :     struct fblockinfo *loop = NULL;
    3159                 :        275 :     location origin_loc = loc;
    3160                 :            :     /* Emit instruction with line number */
    3161         [ -  + ]:        275 :     ADDOP(c, loc, NOP);
    3162         [ -  + ]:        275 :     RETURN_IF_ERROR(compiler_unwind_fblock_stack(c, &loc, 0, &loop));
    3163         [ -  + ]:        275 :     if (loop == NULL) {
    3164                 :          0 :         return compiler_error(c, origin_loc, "'break' outside loop");
    3165                 :            :     }
    3166         [ -  + ]:        275 :     RETURN_IF_ERROR(compiler_unwind_fblock(c, &loc, loop, 0));
    3167         [ -  + ]:        275 :     ADDOP_JUMP(c, loc, JUMP, loop->fb_exit);
    3168                 :        275 :     return SUCCESS;
    3169                 :            : }
    3170                 :            : 
    3171                 :            : static int
    3172                 :        231 : compiler_continue(struct compiler *c, location loc)
    3173                 :            : {
    3174                 :        231 :     struct fblockinfo *loop = NULL;
    3175                 :        231 :     location origin_loc = loc;
    3176                 :            :     /* Emit instruction with line number */
    3177         [ -  + ]:        231 :     ADDOP(c, loc, NOP);
    3178         [ -  + ]:        231 :     RETURN_IF_ERROR(compiler_unwind_fblock_stack(c, &loc, 0, &loop));
    3179         [ -  + ]:        231 :     if (loop == NULL) {
    3180                 :          0 :         return compiler_error(c, origin_loc, "'continue' not properly in loop");
    3181                 :            :     }
    3182         [ -  + ]:        231 :     ADDOP_JUMP(c, loc, JUMP, loop->fb_block);
    3183                 :        231 :     return SUCCESS;
    3184                 :            : }
    3185                 :            : 
    3186                 :            : 
    3187                 :            : static location
    3188                 :        192 : location_of_last_executing_statement(asdl_stmt_seq *stmts)
    3189                 :            : {
    3190   [ +  -  +  - ]:        192 :     for (Py_ssize_t i = asdl_seq_LEN(stmts) - 1; i >= 0; i++) {
    3191                 :        192 :         location loc = LOC((stmt_ty)asdl_seq_GET(stmts, i));
    3192         [ +  - ]:        192 :         if (loc.lineno > 0) {
    3193                 :        192 :             return loc;
    3194                 :            :         }
    3195                 :            :     }
    3196                 :          0 :     return NO_LOCATION;
    3197                 :            : }
    3198                 :            : 
    3199                 :            : /* Code generated for "try: <body> finally: <finalbody>" is as follows:
    3200                 :            : 
    3201                 :            :         SETUP_FINALLY           L
    3202                 :            :         <code for body>
    3203                 :            :         POP_BLOCK
    3204                 :            :         <code for finalbody>
    3205                 :            :         JUMP E
    3206                 :            :     L:
    3207                 :            :         <code for finalbody>
    3208                 :            :     E:
    3209                 :            : 
    3210                 :            :    The special instructions use the block stack.  Each block
    3211                 :            :    stack entry contains the instruction that created it (here
    3212                 :            :    SETUP_FINALLY), the level of the value stack at the time the
    3213                 :            :    block stack entry was created, and a label (here L).
    3214                 :            : 
    3215                 :            :    SETUP_FINALLY:
    3216                 :            :     Pushes the current value stack level and the label
    3217                 :            :     onto the block stack.
    3218                 :            :    POP_BLOCK:
    3219                 :            :     Pops en entry from the block stack.
    3220                 :            : 
    3221                 :            :    The block stack is unwound when an exception is raised:
    3222                 :            :    when a SETUP_FINALLY entry is found, the raised and the caught
    3223                 :            :    exceptions are pushed onto the value stack (and the exception
    3224                 :            :    condition is cleared), and the interpreter jumps to the label
    3225                 :            :    gotten from the block stack.
    3226                 :            : */
    3227                 :            : 
    3228                 :            : static int
    3229                 :        192 : compiler_try_finally(struct compiler *c, stmt_ty s)
    3230                 :            : {
    3231                 :        192 :     location loc = LOC(s);
    3232                 :            : 
    3233         [ -  + ]:        192 :     NEW_JUMP_TARGET_LABEL(c, body);
    3234         [ -  + ]:        192 :     NEW_JUMP_TARGET_LABEL(c, end);
    3235         [ -  + ]:        192 :     NEW_JUMP_TARGET_LABEL(c, exit);
    3236         [ -  + ]:        192 :     NEW_JUMP_TARGET_LABEL(c, cleanup);
    3237                 :            : 
    3238                 :            :     /* `try` block */
    3239         [ -  + ]:        192 :     ADDOP_JUMP(c, loc, SETUP_FINALLY, end);
    3240                 :            : 
    3241         [ -  + ]:        192 :     USE_LABEL(c, body);
    3242         [ -  + ]:        192 :     RETURN_IF_ERROR(
    3243                 :            :         compiler_push_fblock(c, loc, FINALLY_TRY, body, end,
    3244                 :            :                              s->v.Try.finalbody));
    3245                 :            : 
    3246   [ +  +  +  -  :        192 :     if (s->v.Try.handlers && asdl_seq_LEN(s->v.Try.handlers)) {
                   +  - ]
    3247         [ -  + ]:         20 :         RETURN_IF_ERROR(compiler_try_except(c, s));
    3248                 :            :     }
    3249                 :            :     else {
    3250   [ -  +  +  -  :        511 :         VISIT_SEQ(c, stmt, s->v.Try.body);
                   +  + ]
    3251                 :            :     }
    3252         [ -  + ]:        192 :     ADDOP(c, NO_LOCATION, POP_BLOCK);
    3253                 :        192 :     compiler_pop_fblock(c, FINALLY_TRY, body);
    3254   [ -  +  +  -  :        461 :     VISIT_SEQ(c, stmt, s->v.Try.finalbody);
                   +  + ]
    3255                 :            : 
    3256         [ -  + ]:        192 :     ADDOP_JUMP(c, NO_LOCATION, JUMP, exit);
    3257                 :            :     /* `finally` block */
    3258                 :            : 
    3259         [ -  + ]:        192 :     USE_LABEL(c, end);
    3260                 :            : 
    3261                 :        192 :     loc = NO_LOCATION;
    3262         [ -  + ]:        192 :     ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
    3263         [ -  + ]:        192 :     ADDOP(c, loc, PUSH_EXC_INFO);
    3264         [ -  + ]:        192 :     RETURN_IF_ERROR(
    3265                 :            :         compiler_push_fblock(c, loc, FINALLY_END, end, NO_LABEL, NULL));
    3266   [ -  +  +  -  :        461 :     VISIT_SEQ(c, stmt, s->v.Try.finalbody);
                   +  + ]
    3267                 :        192 :     loc = location_of_last_executing_statement(s->v.Try.finalbody);
    3268                 :        192 :     compiler_pop_fblock(c, FINALLY_END, end);
    3269                 :            : 
    3270         [ -  + ]:        192 :     ADDOP_I(c, loc, RERAISE, 0);
    3271                 :            : 
    3272         [ -  + ]:        192 :     USE_LABEL(c, cleanup);
    3273         [ -  + ]:        192 :     POP_EXCEPT_AND_RERAISE(c, loc);
    3274                 :            : 
    3275         [ -  + ]:        192 :     USE_LABEL(c, exit);
    3276                 :        192 :     return SUCCESS;
    3277                 :            : }
    3278                 :            : 
    3279                 :            : static int
    3280                 :          0 : compiler_try_star_finally(struct compiler *c, stmt_ty s)
    3281                 :            : {
    3282                 :          0 :     location loc = LOC(s);
    3283                 :            : 
    3284         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, body);
    3285         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, end);
    3286         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, exit);
    3287         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, cleanup);
    3288                 :            :     /* `try` block */
    3289         [ #  # ]:          0 :     ADDOP_JUMP(c, loc, SETUP_FINALLY, end);
    3290                 :            : 
    3291         [ #  # ]:          0 :     USE_LABEL(c, body);
    3292         [ #  # ]:          0 :     RETURN_IF_ERROR(
    3293                 :            :         compiler_push_fblock(c, loc, FINALLY_TRY, body, end,
    3294                 :            :                              s->v.TryStar.finalbody));
    3295                 :            : 
    3296   [ #  #  #  #  :          0 :     if (s->v.TryStar.handlers && asdl_seq_LEN(s->v.TryStar.handlers)) {
                   #  # ]
    3297         [ #  # ]:          0 :         RETURN_IF_ERROR(compiler_try_star_except(c, s));
    3298                 :            :     }
    3299                 :            :     else {
    3300   [ #  #  #  #  :          0 :         VISIT_SEQ(c, stmt, s->v.TryStar.body);
                   #  # ]
    3301                 :            :     }
    3302         [ #  # ]:          0 :     ADDOP(c, NO_LOCATION, POP_BLOCK);
    3303                 :          0 :     compiler_pop_fblock(c, FINALLY_TRY, body);
    3304   [ #  #  #  #  :          0 :     VISIT_SEQ(c, stmt, s->v.TryStar.finalbody);
                   #  # ]
    3305                 :            : 
    3306         [ #  # ]:          0 :     ADDOP_JUMP(c, NO_LOCATION, JUMP, exit);
    3307                 :            : 
    3308                 :            :     /* `finally` block */
    3309         [ #  # ]:          0 :     USE_LABEL(c, end);
    3310                 :            : 
    3311                 :          0 :     loc = NO_LOCATION;
    3312         [ #  # ]:          0 :     ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
    3313         [ #  # ]:          0 :     ADDOP(c, loc, PUSH_EXC_INFO);
    3314         [ #  # ]:          0 :     RETURN_IF_ERROR(
    3315                 :            :         compiler_push_fblock(c, loc, FINALLY_END, end, NO_LABEL, NULL));
    3316                 :            : 
    3317   [ #  #  #  #  :          0 :     VISIT_SEQ(c, stmt, s->v.TryStar.finalbody);
                   #  # ]
    3318                 :          0 :     loc = location_of_last_executing_statement(s->v.Try.finalbody);
    3319                 :            : 
    3320                 :          0 :     compiler_pop_fblock(c, FINALLY_END, end);
    3321         [ #  # ]:          0 :     ADDOP_I(c, loc, RERAISE, 0);
    3322                 :            : 
    3323         [ #  # ]:          0 :     USE_LABEL(c, cleanup);
    3324         [ #  # ]:          0 :     POP_EXCEPT_AND_RERAISE(c, loc);
    3325                 :            : 
    3326         [ #  # ]:          0 :     USE_LABEL(c, exit);
    3327                 :          0 :     return SUCCESS;
    3328                 :            : }
    3329                 :            : 
    3330                 :            : 
    3331                 :            : /*
    3332                 :            :    Code generated for "try: S except E1 as V1: S1 except E2 as V2: S2 ...":
    3333                 :            :    (The contents of the value stack is shown in [], with the top
    3334                 :            :    at the right; 'tb' is trace-back info, 'val' the exception's
    3335                 :            :    associated value, and 'exc' the exception.)
    3336                 :            : 
    3337                 :            :    Value stack          Label   Instruction     Argument
    3338                 :            :    []                           SETUP_FINALLY   L1
    3339                 :            :    []                           <code for S>
    3340                 :            :    []                           POP_BLOCK
    3341                 :            :    []                           JUMP            L0
    3342                 :            : 
    3343                 :            :    [exc]                L1:     <evaluate E1>           )
    3344                 :            :    [exc, E1]                    CHECK_EXC_MATCH         )
    3345                 :            :    [exc, bool]                  POP_JUMP_IF_FALSE L2    ) only if E1
    3346                 :            :    [exc]                        <assign to V1>  (or POP if no V1)
    3347                 :            :    []                           <code for S1>
    3348                 :            :                                 JUMP            L0
    3349                 :            : 
    3350                 :            :    [exc]                L2:     <evaluate E2>
    3351                 :            :    .............................etc.......................
    3352                 :            : 
    3353                 :            :    [exc]                Ln+1:   RERAISE     # re-raise exception
    3354                 :            : 
    3355                 :            :    []                   L0:     <next statement>
    3356                 :            : 
    3357                 :            :    Of course, parts are not generated if Vi or Ei is not present.
    3358                 :            : */
    3359                 :            : static int
    3360                 :       1297 : compiler_try_except(struct compiler *c, stmt_ty s)
    3361                 :            : {
    3362                 :       1297 :     location loc = LOC(s);
    3363                 :            :     Py_ssize_t i, n;
    3364                 :            : 
    3365         [ -  + ]:       1297 :     NEW_JUMP_TARGET_LABEL(c, body);
    3366         [ -  + ]:       1297 :     NEW_JUMP_TARGET_LABEL(c, except);
    3367         [ -  + ]:       1297 :     NEW_JUMP_TARGET_LABEL(c, end);
    3368         [ -  + ]:       1297 :     NEW_JUMP_TARGET_LABEL(c, cleanup);
    3369                 :            : 
    3370         [ -  + ]:       1297 :     ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
    3371                 :            : 
    3372         [ -  + ]:       1297 :     USE_LABEL(c, body);
    3373         [ -  + ]:       1297 :     RETURN_IF_ERROR(
    3374                 :            :         compiler_push_fblock(c, loc, TRY_EXCEPT, body, NO_LABEL, NULL));
    3375   [ -  +  +  -  :       3050 :     VISIT_SEQ(c, stmt, s->v.Try.body);
                   +  + ]
    3376                 :       1297 :     compiler_pop_fblock(c, TRY_EXCEPT, body);
    3377         [ -  + ]:       1297 :     ADDOP(c, NO_LOCATION, POP_BLOCK);
    3378   [ +  +  +  -  :       1297 :     if (s->v.Try.orelse && asdl_seq_LEN(s->v.Try.orelse)) {
                   +  - ]
    3379   [ -  +  +  -  :        622 :         VISIT_SEQ(c, stmt, s->v.Try.orelse);
                   +  + ]
    3380                 :            :     }
    3381         [ -  + ]:       1297 :     ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
    3382         [ +  - ]:       1297 :     n = asdl_seq_LEN(s->v.Try.handlers);
    3383                 :            : 
    3384         [ -  + ]:       1297 :     USE_LABEL(c, except);
    3385                 :            : 
    3386         [ -  + ]:       1297 :     ADDOP_JUMP(c, NO_LOCATION, SETUP_CLEANUP, cleanup);
    3387         [ -  + ]:       1297 :     ADDOP(c, NO_LOCATION, PUSH_EXC_INFO);
    3388                 :            : 
    3389                 :            :     /* Runtime will push a block here, so we need to account for that */
    3390         [ -  + ]:       1297 :     RETURN_IF_ERROR(
    3391                 :            :         compiler_push_fblock(c, loc, EXCEPTION_HANDLER, NO_LABEL, NO_LABEL, NULL));
    3392                 :            : 
    3393         [ +  + ]:       2739 :     for (i = 0; i < n; i++) {
    3394                 :       1442 :         excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
    3395                 :            :             s->v.Try.handlers, i);
    3396                 :       1442 :         location loc = LOC(handler);
    3397   [ +  +  -  + ]:       1442 :         if (!handler->v.ExceptHandler.type && i < n-1) {
    3398                 :          0 :             return compiler_error(c, loc, "default 'except:' must be last");
    3399                 :            :         }
    3400         [ -  + ]:       1442 :         NEW_JUMP_TARGET_LABEL(c, next_except);
    3401                 :       1442 :         except = next_except;
    3402         [ +  + ]:       1442 :         if (handler->v.ExceptHandler.type) {
    3403         [ -  + ]:       1375 :             VISIT(c, expr, handler->v.ExceptHandler.type);
    3404         [ -  + ]:       1375 :             ADDOP(c, loc, CHECK_EXC_MATCH);
    3405         [ -  + ]:       1375 :             ADDOP_JUMP(c, loc, POP_JUMP_IF_FALSE, except);
    3406                 :            :         }
    3407         [ +  + ]:       1442 :         if (handler->v.ExceptHandler.name) {
    3408         [ -  + ]:        261 :             NEW_JUMP_TARGET_LABEL(c, cleanup_end);
    3409         [ -  + ]:        261 :             NEW_JUMP_TARGET_LABEL(c, cleanup_body);
    3410                 :            : 
    3411         [ -  + ]:        261 :             RETURN_IF_ERROR(
    3412                 :            :                 compiler_nameop(c, loc, handler->v.ExceptHandler.name, Store));
    3413                 :            : 
    3414                 :            :             /*
    3415                 :            :               try:
    3416                 :            :                   # body
    3417                 :            :               except type as name:
    3418                 :            :                   try:
    3419                 :            :                       # body
    3420                 :            :                   finally:
    3421                 :            :                       name = None # in case body contains "del name"
    3422                 :            :                       del name
    3423                 :            :             */
    3424                 :            : 
    3425                 :            :             /* second try: */
    3426         [ -  + ]:        261 :             ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup_end);
    3427                 :            : 
    3428         [ -  + ]:        261 :             USE_LABEL(c, cleanup_body);
    3429         [ -  + ]:        261 :             RETURN_IF_ERROR(
    3430                 :            :                 compiler_push_fblock(c, loc, HANDLER_CLEANUP, cleanup_body,
    3431                 :            :                                      NO_LABEL, handler->v.ExceptHandler.name));
    3432                 :            : 
    3433                 :            :             /* second # body */
    3434   [ -  +  +  -  :        704 :             VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
                   +  + ]
    3435                 :        261 :             compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body);
    3436                 :            :             /* name = None; del name; # Mark as artificial */
    3437         [ -  + ]:        261 :             ADDOP(c, NO_LOCATION, POP_BLOCK);
    3438         [ -  + ]:        261 :             ADDOP(c, NO_LOCATION, POP_BLOCK);
    3439         [ -  + ]:        261 :             ADDOP(c, NO_LOCATION, POP_EXCEPT);
    3440         [ -  + ]:        261 :             ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
    3441         [ -  + ]:        261 :             RETURN_IF_ERROR(
    3442                 :            :                 compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
    3443         [ -  + ]:        261 :             RETURN_IF_ERROR(
    3444                 :            :                 compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
    3445         [ -  + ]:        261 :             ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
    3446                 :            : 
    3447                 :            :             /* except: */
    3448         [ -  + ]:        261 :             USE_LABEL(c, cleanup_end);
    3449                 :            : 
    3450                 :            :             /* name = None; del name; # artificial */
    3451         [ -  + ]:        261 :             ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
    3452         [ -  + ]:        261 :             RETURN_IF_ERROR(
    3453                 :            :                 compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
    3454         [ -  + ]:        261 :             RETURN_IF_ERROR(
    3455                 :            :                 compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
    3456                 :            : 
    3457         [ -  + ]:        261 :             ADDOP_I(c, NO_LOCATION, RERAISE, 1);
    3458                 :            :         }
    3459                 :            :         else {
    3460         [ -  + ]:       1181 :             NEW_JUMP_TARGET_LABEL(c, cleanup_body);
    3461                 :            : 
    3462         [ -  + ]:       1181 :             ADDOP(c, loc, POP_TOP); /* exc_value */
    3463                 :            : 
    3464         [ -  + ]:       1181 :             USE_LABEL(c, cleanup_body);
    3465         [ -  + ]:       1181 :             RETURN_IF_ERROR(
    3466                 :            :                 compiler_push_fblock(c, loc, HANDLER_CLEANUP, cleanup_body,
    3467                 :            :                                      NO_LABEL, NULL));
    3468                 :            : 
    3469   [ -  +  +  -  :       2665 :             VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
                   +  + ]
    3470                 :       1181 :             compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body);
    3471         [ -  + ]:       1181 :             ADDOP(c, NO_LOCATION, POP_BLOCK);
    3472         [ -  + ]:       1181 :             ADDOP(c, NO_LOCATION, POP_EXCEPT);
    3473         [ -  + ]:       1181 :             ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
    3474                 :            :         }
    3475                 :            : 
    3476         [ -  + ]:       1442 :         USE_LABEL(c, except);
    3477                 :            :     }
    3478                 :            :     /* artificial */
    3479                 :       1297 :     compiler_pop_fblock(c, EXCEPTION_HANDLER, NO_LABEL);
    3480         [ -  + ]:       1297 :     ADDOP_I(c, NO_LOCATION, RERAISE, 0);
    3481                 :            : 
    3482         [ -  + ]:       1297 :     USE_LABEL(c, cleanup);
    3483         [ -  + ]:       1297 :     POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
    3484                 :            : 
    3485         [ -  + ]:       1297 :     USE_LABEL(c, end);
    3486                 :       1297 :     return SUCCESS;
    3487                 :            : }
    3488                 :            : 
    3489                 :            : /*
    3490                 :            :    Code generated for "try: S except* E1 as V1: S1 except* E2 as V2: S2 ...":
    3491                 :            :    (The contents of the value stack is shown in [], with the top
    3492                 :            :    at the right; 'tb' is trace-back info, 'val' the exception instance,
    3493                 :            :    and 'typ' the exception's type.)
    3494                 :            : 
    3495                 :            :    Value stack                   Label         Instruction     Argument
    3496                 :            :    []                                         SETUP_FINALLY         L1
    3497                 :            :    []                                         <code for S>
    3498                 :            :    []                                         POP_BLOCK
    3499                 :            :    []                                         JUMP                  L0
    3500                 :            : 
    3501                 :            :    [exc]                            L1:       BUILD_LIST   )  list for raised/reraised excs ("result")
    3502                 :            :    [orig, res]                                COPY 2       )  make a copy of the original EG
    3503                 :            : 
    3504                 :            :    [orig, res, exc]                           <evaluate E1>
    3505                 :            :    [orig, res, exc, E1]                       CHECK_EG_MATCH
    3506                 :            :    [orig, res, rest/exc, match?]              COPY 1
    3507                 :            :    [orig, res, rest/exc, match?, match?]      POP_JUMP_IF_NOT_NONE  H1
    3508                 :            :    [orig, res, exc, None]                     POP_TOP
    3509                 :            :    [orig, res, exc]                           JUMP L2
    3510                 :            : 
    3511                 :            :    [orig, res, rest, match]         H1:       <assign to V1>  (or POP if no V1)
    3512                 :            : 
    3513                 :            :    [orig, res, rest]                          SETUP_FINALLY         R1
    3514                 :            :    [orig, res, rest]                          <code for S1>
    3515                 :            :    [orig, res, rest]                          JUMP                  L2
    3516                 :            : 
    3517                 :            :    [orig, res, rest, i, v]          R1:       LIST_APPEND   3 ) exc raised in except* body - add to res
    3518                 :            :    [orig, res, rest, i]                       POP
    3519                 :            : 
    3520                 :            :    [orig, res, rest]                L2:       <evaluate E2>
    3521                 :            :    .............................etc.......................
    3522                 :            : 
    3523                 :            :    [orig, res, rest]                Ln+1:     LIST_APPEND 1  ) add unhandled exc to res (could be None)
    3524                 :            : 
    3525                 :            :    [orig, res]                                CALL_INTRINSIC_2 PREP_RERAISE_STAR
    3526                 :            :    [exc]                                      COPY 1
    3527                 :            :    [exc, exc]                                 POP_JUMP_IF_NOT_NONE  RER
    3528                 :            :    [exc]                                      POP_TOP
    3529                 :            :    []                                         JUMP                  L0
    3530                 :            : 
    3531                 :            :    [exc]                            RER:      SWAP 2
    3532                 :            :    [exc, prev_exc_info]                       POP_EXCEPT
    3533                 :            :    [exc]                                      RERAISE               0
    3534                 :            : 
    3535                 :            :    []                               L0:       <next statement>
    3536                 :            : */
    3537                 :            : static int
    3538                 :          0 : compiler_try_star_except(struct compiler *c, stmt_ty s)
    3539                 :            : {
    3540                 :          0 :     location loc = LOC(s);
    3541                 :            : 
    3542         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, body);
    3543         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, except);
    3544         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, orelse);
    3545         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, end);
    3546         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, cleanup);
    3547         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, reraise_star);
    3548                 :            : 
    3549         [ #  # ]:          0 :     ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
    3550                 :            : 
    3551         [ #  # ]:          0 :     USE_LABEL(c, body);
    3552         [ #  # ]:          0 :     RETURN_IF_ERROR(
    3553                 :            :         compiler_push_fblock(c, loc, TRY_EXCEPT, body, NO_LABEL, NULL));
    3554   [ #  #  #  #  :          0 :     VISIT_SEQ(c, stmt, s->v.TryStar.body);
                   #  # ]
    3555                 :          0 :     compiler_pop_fblock(c, TRY_EXCEPT, body);
    3556         [ #  # ]:          0 :     ADDOP(c, NO_LOCATION, POP_BLOCK);
    3557         [ #  # ]:          0 :     ADDOP_JUMP(c, NO_LOCATION, JUMP, orelse);
    3558         [ #  # ]:          0 :     Py_ssize_t n = asdl_seq_LEN(s->v.TryStar.handlers);
    3559                 :            : 
    3560         [ #  # ]:          0 :     USE_LABEL(c, except);
    3561                 :            : 
    3562         [ #  # ]:          0 :     ADDOP_JUMP(c, NO_LOCATION, SETUP_CLEANUP, cleanup);
    3563         [ #  # ]:          0 :     ADDOP(c, NO_LOCATION, PUSH_EXC_INFO);
    3564                 :            : 
    3565                 :            :     /* Runtime will push a block here, so we need to account for that */
    3566         [ #  # ]:          0 :     RETURN_IF_ERROR(
    3567                 :            :         compiler_push_fblock(c, loc, EXCEPTION_GROUP_HANDLER,
    3568                 :            :                              NO_LABEL, NO_LABEL, "except handler"));
    3569                 :            : 
    3570         [ #  # ]:          0 :     for (Py_ssize_t i = 0; i < n; i++) {
    3571                 :          0 :         excepthandler_ty handler = (excepthandler_ty)asdl_seq_GET(
    3572                 :            :             s->v.TryStar.handlers, i);
    3573                 :          0 :         location loc = LOC(handler);
    3574         [ #  # ]:          0 :         NEW_JUMP_TARGET_LABEL(c, next_except);
    3575                 :          0 :         except = next_except;
    3576         [ #  # ]:          0 :         NEW_JUMP_TARGET_LABEL(c, handle_match);
    3577         [ #  # ]:          0 :         if (i == 0) {
    3578                 :            :             /* create empty list for exceptions raised/reraise in the except* blocks */
    3579                 :            :             /*
    3580                 :            :                [orig]       BUILD_LIST
    3581                 :            :             */
    3582                 :            :             /* Create a copy of the original EG */
    3583                 :            :             /*
    3584                 :            :                [orig, []]   COPY 2
    3585                 :            :                [orig, [], exc]
    3586                 :            :             */
    3587         [ #  # ]:          0 :             ADDOP_I(c, loc, BUILD_LIST, 0);
    3588         [ #  # ]:          0 :             ADDOP_I(c, loc, COPY, 2);
    3589                 :            :         }
    3590         [ #  # ]:          0 :         if (handler->v.ExceptHandler.type) {
    3591         [ #  # ]:          0 :             VISIT(c, expr, handler->v.ExceptHandler.type);
    3592         [ #  # ]:          0 :             ADDOP(c, loc, CHECK_EG_MATCH);
    3593         [ #  # ]:          0 :             ADDOP_I(c, loc, COPY, 1);
    3594         [ #  # ]:          0 :             ADDOP_JUMP(c, loc, POP_JUMP_IF_NOT_NONE, handle_match);
    3595         [ #  # ]:          0 :             ADDOP(c, loc, POP_TOP);  // match
    3596         [ #  # ]:          0 :             ADDOP_JUMP(c, loc, JUMP, except);
    3597                 :            :         }
    3598                 :            : 
    3599         [ #  # ]:          0 :         USE_LABEL(c, handle_match);
    3600                 :            : 
    3601         [ #  # ]:          0 :         NEW_JUMP_TARGET_LABEL(c, cleanup_end);
    3602         [ #  # ]:          0 :         NEW_JUMP_TARGET_LABEL(c, cleanup_body);
    3603                 :            : 
    3604         [ #  # ]:          0 :         if (handler->v.ExceptHandler.name) {
    3605         [ #  # ]:          0 :             RETURN_IF_ERROR(
    3606                 :            :                 compiler_nameop(c, loc, handler->v.ExceptHandler.name, Store));
    3607                 :            :         }
    3608                 :            :         else {
    3609         [ #  # ]:          0 :             ADDOP(c, loc, POP_TOP);  // match
    3610                 :            :         }
    3611                 :            : 
    3612                 :            :         /*
    3613                 :            :           try:
    3614                 :            :               # body
    3615                 :            :           except type as name:
    3616                 :            :               try:
    3617                 :            :                   # body
    3618                 :            :               finally:
    3619                 :            :                   name = None # in case body contains "del name"
    3620                 :            :                   del name
    3621                 :            :         */
    3622                 :            :         /* second try: */
    3623         [ #  # ]:          0 :         ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup_end);
    3624                 :            : 
    3625         [ #  # ]:          0 :         USE_LABEL(c, cleanup_body);
    3626         [ #  # ]:          0 :         RETURN_IF_ERROR(
    3627                 :            :             compiler_push_fblock(c, loc, HANDLER_CLEANUP, cleanup_body,
    3628                 :            :                                  NO_LABEL, handler->v.ExceptHandler.name));
    3629                 :            : 
    3630                 :            :         /* second # body */
    3631   [ #  #  #  #  :          0 :         VISIT_SEQ(c, stmt, handler->v.ExceptHandler.body);
                   #  # ]
    3632                 :          0 :         compiler_pop_fblock(c, HANDLER_CLEANUP, cleanup_body);
    3633                 :            :         /* name = None; del name; # artificial */
    3634         [ #  # ]:          0 :         ADDOP(c, NO_LOCATION, POP_BLOCK);
    3635         [ #  # ]:          0 :         if (handler->v.ExceptHandler.name) {
    3636         [ #  # ]:          0 :             ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
    3637         [ #  # ]:          0 :             RETURN_IF_ERROR(
    3638                 :            :                 compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
    3639         [ #  # ]:          0 :             RETURN_IF_ERROR(
    3640                 :            :                 compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
    3641                 :            :         }
    3642         [ #  # ]:          0 :         ADDOP_JUMP(c, NO_LOCATION, JUMP, except);
    3643                 :            : 
    3644                 :            :         /* except: */
    3645         [ #  # ]:          0 :         USE_LABEL(c, cleanup_end);
    3646                 :            : 
    3647                 :            :         /* name = None; del name; # artificial */
    3648         [ #  # ]:          0 :         if (handler->v.ExceptHandler.name) {
    3649         [ #  # ]:          0 :             ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
    3650         [ #  # ]:          0 :             RETURN_IF_ERROR(
    3651                 :            :                 compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Store));
    3652         [ #  # ]:          0 :             RETURN_IF_ERROR(
    3653                 :            :                 compiler_nameop(c, NO_LOCATION, handler->v.ExceptHandler.name, Del));
    3654                 :            :         }
    3655                 :            : 
    3656                 :            :         /* add exception raised to the res list */
    3657         [ #  # ]:          0 :         ADDOP_I(c, NO_LOCATION, LIST_APPEND, 3); // exc
    3658         [ #  # ]:          0 :         ADDOP(c, NO_LOCATION, POP_TOP); // lasti
    3659         [ #  # ]:          0 :         ADDOP_JUMP(c, NO_LOCATION, JUMP, except);
    3660                 :            : 
    3661         [ #  # ]:          0 :         USE_LABEL(c, except);
    3662                 :            : 
    3663         [ #  # ]:          0 :         if (i == n - 1) {
    3664                 :            :             /* Add exc to the list (if not None it's the unhandled part of the EG) */
    3665         [ #  # ]:          0 :             ADDOP_I(c, NO_LOCATION, LIST_APPEND, 1);
    3666         [ #  # ]:          0 :             ADDOP_JUMP(c, NO_LOCATION, JUMP, reraise_star);
    3667                 :            :         }
    3668                 :            :     }
    3669                 :            :     /* artificial */
    3670                 :          0 :     compiler_pop_fblock(c, EXCEPTION_GROUP_HANDLER, NO_LABEL);
    3671         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, reraise);
    3672                 :            : 
    3673         [ #  # ]:          0 :     USE_LABEL(c, reraise_star);
    3674         [ #  # ]:          0 :     ADDOP_I(c, NO_LOCATION, CALL_INTRINSIC_2, INTRINSIC_PREP_RERAISE_STAR);
    3675         [ #  # ]:          0 :     ADDOP_I(c, NO_LOCATION, COPY, 1);
    3676         [ #  # ]:          0 :     ADDOP_JUMP(c, NO_LOCATION, POP_JUMP_IF_NOT_NONE, reraise);
    3677                 :            : 
    3678                 :            :     /* Nothing to reraise */
    3679         [ #  # ]:          0 :     ADDOP(c, NO_LOCATION, POP_TOP);
    3680         [ #  # ]:          0 :     ADDOP(c, NO_LOCATION, POP_BLOCK);
    3681         [ #  # ]:          0 :     ADDOP(c, NO_LOCATION, POP_EXCEPT);
    3682         [ #  # ]:          0 :     ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
    3683                 :            : 
    3684         [ #  # ]:          0 :     USE_LABEL(c, reraise);
    3685         [ #  # ]:          0 :     ADDOP(c, NO_LOCATION, POP_BLOCK);
    3686         [ #  # ]:          0 :     ADDOP_I(c, NO_LOCATION, SWAP, 2);
    3687         [ #  # ]:          0 :     ADDOP(c, NO_LOCATION, POP_EXCEPT);
    3688         [ #  # ]:          0 :     ADDOP_I(c, NO_LOCATION, RERAISE, 0);
    3689                 :            : 
    3690         [ #  # ]:          0 :     USE_LABEL(c, cleanup);
    3691         [ #  # ]:          0 :     POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
    3692                 :            : 
    3693         [ #  # ]:          0 :     USE_LABEL(c, orelse);
    3694   [ #  #  #  #  :          0 :     VISIT_SEQ(c, stmt, s->v.TryStar.orelse);
                   #  # ]
    3695                 :            : 
    3696         [ #  # ]:          0 :     USE_LABEL(c, end);
    3697                 :          0 :     return SUCCESS;
    3698                 :            : }
    3699                 :            : 
    3700                 :            : static int
    3701                 :       1469 : compiler_try(struct compiler *c, stmt_ty s) {
    3702   [ +  +  +  -  :       1469 :     if (s->v.Try.finalbody && asdl_seq_LEN(s->v.Try.finalbody))
                   +  - ]
    3703                 :        192 :         return compiler_try_finally(c, s);
    3704                 :            :     else
    3705                 :       1277 :         return compiler_try_except(c, s);
    3706                 :            : }
    3707                 :            : 
    3708                 :            : static int
    3709                 :          0 : compiler_try_star(struct compiler *c, stmt_ty s)
    3710                 :            : {
    3711   [ #  #  #  #  :          0 :     if (s->v.TryStar.finalbody && asdl_seq_LEN(s->v.TryStar.finalbody)) {
                   #  # ]
    3712                 :          0 :         return compiler_try_star_finally(c, s);
    3713                 :            :     }
    3714                 :            :     else {
    3715                 :          0 :         return compiler_try_star_except(c, s);
    3716                 :            :     }
    3717                 :            : }
    3718                 :            : 
    3719                 :            : static int
    3720                 :         50 : compiler_import_as(struct compiler *c, location loc,
    3721                 :            :                    identifier name, identifier asname)
    3722                 :            : {
    3723                 :            :     /* The IMPORT_NAME opcode was already generated.  This function
    3724                 :            :        merely needs to bind the result to a name.
    3725                 :            : 
    3726                 :            :        If there is a dot in name, we need to split it and emit a
    3727                 :            :        IMPORT_FROM for each name.
    3728                 :            :     */
    3729                 :         50 :     Py_ssize_t len = PyUnicode_GET_LENGTH(name);
    3730                 :         50 :     Py_ssize_t dot = PyUnicode_FindChar(name, '.', 0, len, 1);
    3731         [ -  + ]:         50 :     if (dot == -2) {
    3732                 :          0 :         return ERROR;
    3733                 :            :     }
    3734         [ +  + ]:         50 :     if (dot != -1) {
    3735                 :            :         /* Consume the base module name to get the first attribute */
    3736                 :          4 :         while (1) {
    3737                 :          8 :             Py_ssize_t pos = dot + 1;
    3738                 :            :             PyObject *attr;
    3739                 :          8 :             dot = PyUnicode_FindChar(name, '.', pos, len, 1);
    3740         [ -  + ]:          8 :             if (dot == -2) {
    3741                 :          0 :                 return ERROR;
    3742                 :            :             }
    3743         [ +  + ]:          8 :             attr = PyUnicode_Substring(name, pos, (dot != -1) ? dot : len);
    3744         [ -  + ]:          8 :             if (!attr) {
    3745                 :          0 :                 return ERROR;
    3746                 :            :             }
    3747         [ -  + ]:          8 :             ADDOP_N(c, loc, IMPORT_FROM, attr, names);
    3748         [ +  + ]:          8 :             if (dot == -1) {
    3749                 :          4 :                 break;
    3750                 :            :             }
    3751         [ -  + ]:          4 :             ADDOP_I(c, loc, SWAP, 2);
    3752         [ -  + ]:          4 :             ADDOP(c, loc, POP_TOP);
    3753                 :            :         }
    3754         [ -  + ]:          4 :         RETURN_IF_ERROR(compiler_nameop(c, loc, asname, Store));
    3755         [ -  + ]:          4 :         ADDOP(c, loc, POP_TOP);
    3756                 :          4 :         return SUCCESS;
    3757                 :            :     }
    3758                 :         46 :     return compiler_nameop(c, loc, asname, Store);
    3759                 :            : }
    3760                 :            : 
    3761                 :            : static int
    3762                 :        899 : compiler_import(struct compiler *c, stmt_ty s)
    3763                 :            : {
    3764                 :        899 :     location loc = LOC(s);
    3765                 :            :     /* The Import node stores a module name like a.b.c as a single
    3766                 :            :        string.  This is convenient for all cases except
    3767                 :            :          import a.b.c as d
    3768                 :            :        where we need to parse that string to extract the individual
    3769                 :            :        module names.
    3770                 :            :        XXX Perhaps change the representation to make this case simpler?
    3771                 :            :      */
    3772         [ +  - ]:        899 :     Py_ssize_t i, n = asdl_seq_LEN(s->v.Import.names);
    3773                 :            : 
    3774                 :        899 :     PyObject *zero = _PyLong_GetZero();  // borrowed reference
    3775         [ +  + ]:       1819 :     for (i = 0; i < n; i++) {
    3776                 :        920 :         alias_ty alias = (alias_ty)asdl_seq_GET(s->v.Import.names, i);
    3777                 :            :         int r;
    3778                 :            : 
    3779         [ -  + ]:        920 :         ADDOP_LOAD_CONST(c, loc, zero);
    3780         [ -  + ]:        920 :         ADDOP_LOAD_CONST(c, loc, Py_None);
    3781         [ -  + ]:        920 :         ADDOP_NAME(c, loc, IMPORT_NAME, alias->name, names);
    3782                 :            : 
    3783         [ +  + ]:        920 :         if (alias->asname) {
    3784                 :         50 :             r = compiler_import_as(c, loc, alias->name, alias->asname);
    3785         [ -  + ]:         50 :             RETURN_IF_ERROR(r);
    3786                 :            :         }
    3787                 :            :         else {
    3788                 :        870 :             identifier tmp = alias->name;
    3789                 :        870 :             Py_ssize_t dot = PyUnicode_FindChar(
    3790                 :        870 :                 alias->name, '.', 0, PyUnicode_GET_LENGTH(alias->name), 1);
    3791         [ +  + ]:        870 :             if (dot != -1) {
    3792                 :         22 :                 tmp = PyUnicode_Substring(alias->name, 0, dot);
    3793         [ -  + ]:         22 :                 if (tmp == NULL) {
    3794                 :          0 :                     return ERROR;
    3795                 :            :                 }
    3796                 :            :             }
    3797                 :        870 :             r = compiler_nameop(c, loc, tmp, Store);
    3798         [ +  + ]:        870 :             if (dot != -1) {
    3799                 :         22 :                 Py_DECREF(tmp);
    3800                 :            :             }
    3801         [ -  + ]:        870 :             RETURN_IF_ERROR(r);
    3802                 :            :         }
    3803                 :            :     }
    3804                 :        899 :     return SUCCESS;
    3805                 :            : }
    3806                 :            : 
    3807                 :            : static int
    3808                 :        524 : compiler_from_import(struct compiler *c, stmt_ty s)
    3809                 :            : {
    3810         [ +  - ]:        524 :     Py_ssize_t n = asdl_seq_LEN(s->v.ImportFrom.names);
    3811                 :            : 
    3812   [ -  +  -  + ]:        524 :     ADDOP_LOAD_CONST_NEW(c, LOC(s), PyLong_FromLong(s->v.ImportFrom.level));
    3813                 :            : 
    3814                 :        524 :     PyObject *names = PyTuple_New(n);
    3815         [ -  + ]:        524 :     if (!names) {
    3816                 :          0 :         return ERROR;
    3817                 :            :     }
    3818                 :            : 
    3819                 :            :     /* build up the names */
    3820         [ +  + ]:       1347 :     for (Py_ssize_t i = 0; i < n; i++) {
    3821                 :        823 :         alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
    3822                 :        823 :         PyTuple_SET_ITEM(names, i, Py_NewRef(alias->name));
    3823                 :            :     }
    3824                 :            : 
    3825         [ +  - ]:        524 :     if (location_is_after(LOC(s), c->c_future.ff_location) &&
    3826   [ +  +  -  + ]:        953 :         s->v.ImportFrom.module &&
    3827                 :        429 :         _PyUnicode_EqualToASCIIString(s->v.ImportFrom.module, "__future__"))
    3828                 :            :     {
    3829                 :          0 :         Py_DECREF(names);
    3830                 :          0 :         return compiler_error(c, LOC(s), "from __future__ imports must occur "
    3831                 :            :                               "at the beginning of the file");
    3832                 :            :     }
    3833   [ -  +  -  + ]:        524 :     ADDOP_LOAD_CONST_NEW(c, LOC(s), names);
    3834                 :            : 
    3835         [ +  + ]:        524 :     if (s->v.ImportFrom.module) {
    3836         [ -  + ]:        429 :         ADDOP_NAME(c, LOC(s), IMPORT_NAME, s->v.ImportFrom.module, names);
    3837                 :            :     }
    3838                 :            :     else {
    3839                 :            :         _Py_DECLARE_STR(empty, "");
    3840         [ -  + ]:         95 :         ADDOP_NAME(c, LOC(s), IMPORT_NAME, &_Py_STR(empty), names);
    3841                 :            :     }
    3842         [ +  + ]:       1299 :     for (Py_ssize_t i = 0; i < n; i++) {
    3843                 :        823 :         alias_ty alias = (alias_ty)asdl_seq_GET(s->v.ImportFrom.names, i);
    3844                 :            :         identifier store_name;
    3845                 :            : 
    3846   [ +  +  +  + ]:        823 :         if (i == 0 && PyUnicode_READ_CHAR(alias->name, 0) == '*') {
    3847                 :            :             assert(n == 1);
    3848         [ -  + ]:         48 :             ADDOP_I(c, LOC(s), CALL_INTRINSIC_1, INTRINSIC_IMPORT_STAR);
    3849         [ -  + ]:         48 :             ADDOP(c, NO_LOCATION, POP_TOP);
    3850                 :         48 :             return SUCCESS;
    3851                 :            :         }
    3852                 :            : 
    3853         [ -  + ]:        775 :         ADDOP_NAME(c, LOC(s), IMPORT_FROM, alias->name, names);
    3854                 :        775 :         store_name = alias->name;
    3855         [ +  + ]:        775 :         if (alias->asname) {
    3856                 :         90 :             store_name = alias->asname;
    3857                 :            :         }
    3858                 :            : 
    3859         [ -  + ]:        775 :         RETURN_IF_ERROR(compiler_nameop(c, LOC(s), store_name, Store));
    3860                 :            :     }
    3861                 :            :     /* remove imported module */
    3862         [ -  + ]:        476 :     ADDOP(c, LOC(s), POP_TOP);
    3863                 :        476 :     return SUCCESS;
    3864                 :            : }
    3865                 :            : 
    3866                 :            : static int
    3867                 :        239 : compiler_assert(struct compiler *c, stmt_ty s)
    3868                 :            : {
    3869                 :            :     /* Always emit a warning if the test is a non-zero length tuple */
    3870         [ -  + ]:        239 :     if ((s->v.Assert.test->kind == Tuple_kind &&
    3871   [ #  #  #  # ]:          0 :         asdl_seq_LEN(s->v.Assert.test->v.Tuple.elts) > 0) ||
    3872   [ +  +  -  + ]:        242 :         (s->v.Assert.test->kind == Constant_kind &&
    3873         [ -  - ]:          3 :          PyTuple_Check(s->v.Assert.test->v.Constant.value) &&
    3874                 :          0 :          PyTuple_Size(s->v.Assert.test->v.Constant.value) > 0))
    3875                 :            :     {
    3876         [ #  # ]:          0 :         RETURN_IF_ERROR(
    3877                 :            :             compiler_warn(c, LOC(s), "assertion is always true, "
    3878                 :            :                                      "perhaps remove parentheses?"));
    3879                 :            :     }
    3880         [ -  + ]:        239 :     if (c->c_optimize) {
    3881                 :          0 :         return SUCCESS;
    3882                 :            :     }
    3883         [ -  + ]:        239 :     NEW_JUMP_TARGET_LABEL(c, end);
    3884         [ -  + ]:        239 :     RETURN_IF_ERROR(compiler_jump_if(c, LOC(s), s->v.Assert.test, end, 1));
    3885         [ -  + ]:        239 :     ADDOP(c, LOC(s), LOAD_ASSERTION_ERROR);
    3886         [ +  + ]:        239 :     if (s->v.Assert.msg) {
    3887         [ -  + ]:         71 :         VISIT(c, expr, s->v.Assert.msg);
    3888         [ -  + ]:         71 :         ADDOP_I(c, LOC(s), CALL, 0);
    3889                 :            :     }
    3890         [ -  + ]:        239 :     ADDOP_I(c, LOC(s), RAISE_VARARGS, 1);
    3891                 :            : 
    3892         [ -  + ]:        239 :     USE_LABEL(c, end);
    3893                 :        239 :     return SUCCESS;
    3894                 :            : }
    3895                 :            : 
    3896                 :            : static int
    3897                 :       8026 : compiler_stmt_expr(struct compiler *c, location loc, expr_ty value)
    3898                 :            : {
    3899   [ +  +  +  - ]:       8026 :     if (c->c_interactive && c->c_nestlevel <= 1) {
    3900         [ -  + ]:         47 :         VISIT(c, expr, value);
    3901         [ -  + ]:         47 :         ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_PRINT);
    3902         [ -  + ]:         47 :         ADDOP(c, NO_LOCATION, POP_TOP);
    3903                 :         47 :         return SUCCESS;
    3904                 :            :     }
    3905                 :            : 
    3906         [ +  + ]:       7979 :     if (value->kind == Constant_kind) {
    3907                 :            :         /* ignore constant statement */
    3908         [ -  + ]:          1 :         ADDOP(c, loc, NOP);
    3909                 :          1 :         return SUCCESS;
    3910                 :            :     }
    3911                 :            : 
    3912         [ -  + ]:       7978 :     VISIT(c, expr, value);
    3913         [ -  + ]:       7978 :     ADDOP(c, NO_LOCATION, POP_TOP); /* artificial */
    3914                 :       7978 :     return SUCCESS;
    3915                 :            : }
    3916                 :            : 
    3917                 :            : static int
    3918                 :      55660 : compiler_visit_stmt(struct compiler *c, stmt_ty s)
    3919                 :            : {
    3920                 :            : 
    3921   [ +  +  +  +  :      55660 :     switch (s->kind) {
          +  +  +  +  +  
          +  +  +  +  -  
          +  +  +  +  +  
          +  +  +  +  +  
                +  -  - ]
    3922                 :       6243 :     case FunctionDef_kind:
    3923                 :       6243 :         return compiler_function(c, s, 0);
    3924                 :        733 :     case ClassDef_kind:
    3925                 :        733 :         return compiler_class(c, s);
    3926                 :       5842 :     case Return_kind:
    3927                 :       5842 :         return compiler_return(c, s);
    3928                 :        201 :     case Delete_kind:
    3929   [ -  +  +  -  :        439 :         VISIT_SEQ(c, expr, s->v.Delete.targets)
                   +  + ]
    3930                 :        201 :         break;
    3931                 :      16725 :     case Assign_kind:
    3932                 :            :     {
    3933         [ +  - ]:      16725 :         Py_ssize_t n = asdl_seq_LEN(s->v.Assign.targets);
    3934         [ -  + ]:      16725 :         VISIT(c, expr, s->v.Assign.value);
    3935         [ +  + ]:      33608 :         for (Py_ssize_t i = 0; i < n; i++) {
    3936         [ +  + ]:      16883 :             if (i < n - 1) {
    3937         [ -  + ]:        158 :                 ADDOP_I(c, LOC(s), COPY, 1);
    3938                 :            :             }
    3939         [ -  + ]:      16883 :             VISIT(c, expr,
    3940                 :            :                   (expr_ty)asdl_seq_GET(s->v.Assign.targets, i));
    3941                 :            :         }
    3942                 :      16725 :         break;
    3943                 :            :     }
    3944                 :        722 :     case AugAssign_kind:
    3945                 :        722 :         return compiler_augassign(c, s);
    3946                 :         17 :     case AnnAssign_kind:
    3947                 :         17 :         return compiler_annassign(c, s);
    3948                 :       1236 :     case For_kind:
    3949                 :       1236 :         return compiler_for(c, s);
    3950                 :        305 :     case While_kind:
    3951                 :        305 :         return compiler_while(c, s);
    3952                 :       8896 :     case If_kind:
    3953                 :       8896 :         return compiler_if(c, s);
    3954                 :          4 :     case Match_kind:
    3955                 :          4 :         return compiler_match(c, s);
    3956                 :       1939 :     case Raise_kind:
    3957                 :            :     {
    3958                 :       1939 :         Py_ssize_t n = 0;
    3959         [ +  + ]:       1939 :         if (s->v.Raise.exc) {
    3960         [ -  + ]:       1739 :             VISIT(c, expr, s->v.Raise.exc);
    3961                 :       1739 :             n++;
    3962         [ +  + ]:       1739 :             if (s->v.Raise.cause) {
    3963         [ -  + ]:        102 :                 VISIT(c, expr, s->v.Raise.cause);
    3964                 :        102 :                 n++;
    3965                 :            :             }
    3966                 :            :         }
    3967         [ -  + ]:       1939 :         ADDOP_I(c, LOC(s), RAISE_VARARGS, (int)n);
    3968                 :       1939 :         break;
    3969                 :            :     }
    3970                 :       1469 :     case Try_kind:
    3971                 :       1469 :         return compiler_try(c, s);
    3972                 :          0 :     case TryStar_kind:
    3973                 :          0 :         return compiler_try_star(c, s);
    3974                 :        239 :     case Assert_kind:
    3975                 :        239 :         return compiler_assert(c, s);
    3976                 :        899 :     case Import_kind:
    3977                 :        899 :         return compiler_import(c, s);
    3978                 :        524 :     case ImportFrom_kind:
    3979                 :        524 :         return compiler_from_import(c, s);
    3980                 :         87 :     case Global_kind:
    3981                 :            :     case Nonlocal_kind:
    3982                 :         87 :         break;
    3983                 :       8026 :     case Expr_kind:
    3984                 :            :     {
    3985                 :       8026 :         return compiler_stmt_expr(c, LOC(s), s->v.Expr.value);
    3986                 :            :     }
    3987                 :        505 :     case Pass_kind:
    3988                 :            :     {
    3989         [ -  + ]:        505 :         ADDOP(c, LOC(s), NOP);
    3990                 :        505 :         break;
    3991                 :            :     }
    3992                 :        275 :     case Break_kind:
    3993                 :            :     {
    3994                 :        275 :         return compiler_break(c, LOC(s));
    3995                 :            :     }
    3996                 :        231 :     case Continue_kind:
    3997                 :            :     {
    3998                 :        231 :         return compiler_continue(c, LOC(s));
    3999                 :            :     }
    4000                 :        379 :     case With_kind:
    4001                 :        379 :         return compiler_with(c, s, 0);
    4002                 :        158 :     case AsyncFunctionDef_kind:
    4003                 :        158 :         return compiler_function(c, s, 1);
    4004                 :          5 :     case AsyncWith_kind:
    4005                 :          5 :         return compiler_async_with(c, s, 0);
    4006                 :          0 :     case AsyncFor_kind:
    4007                 :          0 :         return compiler_async_for(c, s);
    4008                 :            :     }
    4009                 :            : 
    4010                 :      19457 :     return SUCCESS;
    4011                 :            : }
    4012                 :            : 
    4013                 :            : static int
    4014                 :        266 : unaryop(unaryop_ty op)
    4015                 :            : {
    4016   [ +  +  +  - ]:        266 :     switch (op) {
    4017                 :         25 :     case Invert:
    4018                 :         25 :         return UNARY_INVERT;
    4019                 :         73 :     case Not:
    4020                 :         73 :         return UNARY_NOT;
    4021                 :        168 :     case USub:
    4022                 :        168 :         return UNARY_NEGATIVE;
    4023                 :          0 :     default:
    4024                 :          0 :         PyErr_Format(PyExc_SystemError,
    4025                 :            :             "unary op %d should not be possible", op);
    4026                 :          0 :         return 0;
    4027                 :            :     }
    4028                 :            : }
    4029                 :            : 
    4030                 :            : static int
    4031                 :       4263 : addop_binary(struct compiler *c, location loc, operator_ty binop,
    4032                 :            :              bool inplace)
    4033                 :            : {
    4034                 :            :     int oparg;
    4035   [ +  +  +  +  :       4263 :     switch (binop) {
          +  +  +  +  +  
             +  +  +  +  
                      - ]
    4036                 :       1898 :         case Add:
    4037         [ +  + ]:       1898 :             oparg = inplace ? NB_INPLACE_ADD : NB_ADD;
    4038                 :       1898 :             break;
    4039                 :        627 :         case Sub:
    4040         [ +  + ]:        627 :             oparg = inplace ? NB_INPLACE_SUBTRACT : NB_SUBTRACT;
    4041                 :        627 :             break;
    4042                 :        415 :         case Mult:
    4043         [ +  + ]:        415 :             oparg = inplace ? NB_INPLACE_MULTIPLY : NB_MULTIPLY;
    4044                 :        415 :             break;
    4045                 :          2 :         case MatMult:
    4046         [ +  + ]:          2 :             oparg = inplace ? NB_INPLACE_MATRIX_MULTIPLY : NB_MATRIX_MULTIPLY;
    4047                 :          2 :             break;
    4048                 :        111 :         case Div:
    4049         [ +  + ]:        111 :             oparg = inplace ? NB_INPLACE_TRUE_DIVIDE : NB_TRUE_DIVIDE;
    4050                 :        111 :             break;
    4051                 :        542 :         case Mod:
    4052         [ +  + ]:        542 :             oparg = inplace ? NB_INPLACE_REMAINDER : NB_REMAINDER;
    4053                 :        542 :             break;
    4054                 :         91 :         case Pow:
    4055         [ +  + ]:         91 :             oparg = inplace ? NB_INPLACE_POWER : NB_POWER;
    4056                 :         91 :             break;
    4057                 :         39 :         case LShift:
    4058         [ +  + ]:         39 :             oparg = inplace ? NB_INPLACE_LSHIFT : NB_LSHIFT;
    4059                 :         39 :             break;
    4060                 :         25 :         case RShift:
    4061         [ +  + ]:         25 :             oparg = inplace ? NB_INPLACE_RSHIFT : NB_RSHIFT;
    4062                 :         25 :             break;
    4063                 :        186 :         case BitOr:
    4064         [ +  + ]:        186 :             oparg = inplace ? NB_INPLACE_OR : NB_OR;
    4065                 :        186 :             break;
    4066                 :         22 :         case BitXor:
    4067         [ +  + ]:         22 :             oparg = inplace ? NB_INPLACE_XOR : NB_XOR;
    4068                 :         22 :             break;
    4069                 :        210 :         case BitAnd:
    4070         [ +  + ]:        210 :             oparg = inplace ? NB_INPLACE_AND : NB_AND;
    4071                 :        210 :             break;
    4072                 :         95 :         case FloorDiv:
    4073         [ +  + ]:         95 :             oparg = inplace ? NB_INPLACE_FLOOR_DIVIDE : NB_FLOOR_DIVIDE;
    4074                 :         95 :             break;
    4075                 :          0 :         default:
    4076         [ #  # ]:          0 :             PyErr_Format(PyExc_SystemError, "%s op %d should not be possible",
    4077                 :            :                          inplace ? "inplace" : "binary", binop);
    4078                 :          0 :             return ERROR;
    4079                 :            :     }
    4080         [ -  + ]:       4263 :     ADDOP_I(c, loc, BINARY_OP, oparg);
    4081                 :       4263 :     return SUCCESS;
    4082                 :            : }
    4083                 :            : 
    4084                 :            : 
    4085                 :            : static int
    4086                 :        449 : addop_yield(struct compiler *c, location loc) {
    4087   [ +  -  +  + ]:        449 :     if (c->u->u_ste->ste_generator && c->u->u_ste->ste_coroutine) {
    4088         [ -  + ]:          3 :         ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_ASYNC_GEN_WRAP);
    4089                 :            :     }
    4090         [ -  + ]:        449 :     ADDOP_I(c, loc, YIELD_VALUE, 0);
    4091         [ -  + ]:        449 :     ADDOP_I(c, loc, RESUME, 1);
    4092                 :        449 :     return SUCCESS;
    4093                 :            : }
    4094                 :            : 
    4095                 :            : static int
    4096                 :     115879 : compiler_nameop(struct compiler *c, location loc,
    4097                 :            :                 identifier name, expr_context_ty ctx)
    4098                 :            : {
    4099                 :            :     int op, scope;
    4100                 :            :     Py_ssize_t arg;
    4101                 :            :     enum { OP_FAST, OP_GLOBAL, OP_DEREF, OP_NAME } optype;
    4102                 :            : 
    4103                 :     115879 :     PyObject *dict = c->u->u_names;
    4104                 :            :     PyObject *mangled;
    4105                 :            : 
    4106                 :            :     assert(!_PyUnicode_EqualToASCIIString(name, "None") &&
    4107                 :            :            !_PyUnicode_EqualToASCIIString(name, "True") &&
    4108                 :            :            !_PyUnicode_EqualToASCIIString(name, "False"));
    4109                 :            : 
    4110         [ -  + ]:     115879 :     if (forbidden_name(c, loc, name, ctx)) {
    4111                 :          0 :         return ERROR;
    4112                 :            :     }
    4113                 :            : 
    4114                 :     115879 :     mangled = _Py_Mangle(c->u->u_private, name);
    4115         [ -  + ]:     115879 :     if (!mangled) {
    4116                 :          0 :         return ERROR;
    4117                 :            :     }
    4118                 :            : 
    4119                 :     115879 :     op = 0;
    4120                 :     115879 :     optype = OP_NAME;
    4121                 :     115879 :     scope = _PyST_GetScope(c->u->u_ste, mangled);
    4122   [ +  +  +  +  :     115879 :     switch (scope) {
                   +  + ]
    4123                 :        996 :     case FREE:
    4124                 :        996 :         dict = c->u->u_freevars;
    4125                 :        996 :         optype = OP_DEREF;
    4126                 :        996 :         break;
    4127                 :       1452 :     case CELL:
    4128                 :       1452 :         dict = c->u->u_cellvars;
    4129                 :       1452 :         optype = OP_DEREF;
    4130                 :       1452 :         break;
    4131                 :      86222 :     case LOCAL:
    4132         [ +  + ]:      86222 :         if (c->u->u_ste->ste_type == FunctionBlock)
    4133                 :      71661 :             optype = OP_FAST;
    4134                 :      86222 :         break;
    4135                 :      24052 :     case GLOBAL_IMPLICIT:
    4136         [ +  + ]:      24052 :         if (c->u->u_ste->ste_type == FunctionBlock)
    4137                 :      21268 :             optype = OP_GLOBAL;
    4138                 :      24052 :         break;
    4139                 :        287 :     case GLOBAL_EXPLICIT:
    4140                 :        287 :         optype = OP_GLOBAL;
    4141                 :        287 :         break;
    4142                 :       2870 :     default:
    4143                 :            :         /* scope can be 0 */
    4144                 :       2870 :         break;
    4145                 :            :     }
    4146                 :            : 
    4147                 :            :     /* XXX Leave assert here, but handle __doc__ and the like better */
    4148                 :            :     assert(scope || PyUnicode_READ_CHAR(name, 0) == '_');
    4149                 :            : 
    4150   [ +  +  +  +  :     115879 :     switch (optype) {
                      - ]
    4151   [ +  +  -  - ]:       2448 :     case OP_DEREF:
    4152                 :            :         switch (ctx) {
    4153                 :       2022 :         case Load:
    4154         [ +  + ]:       2022 :             op = (c->u->u_ste->ste_type == ClassBlock) ? LOAD_CLASSDEREF : LOAD_DEREF;
    4155                 :       2022 :             break;
    4156                 :        426 :         case Store: op = STORE_DEREF; break;
    4157                 :          0 :         case Del: op = DELETE_DEREF; break;
    4158                 :            :         }
    4159                 :       2448 :         break;
    4160   [ +  +  +  - ]:      71661 :     case OP_FAST:
    4161                 :            :         switch (ctx) {
    4162                 :      55671 :         case Load: op = LOAD_FAST; break;
    4163                 :      15390 :         case Store: op = STORE_FAST; break;
    4164                 :        600 :         case Del: op = DELETE_FAST; break;
    4165                 :            :         }
    4166         [ -  + ]:      71661 :         ADDOP_N(c, loc, op, mangled, varnames);
    4167                 :      71661 :         return SUCCESS;
    4168   [ +  +  -  - ]:      21555 :     case OP_GLOBAL:
    4169                 :            :         switch (ctx) {
    4170                 :      21400 :         case Load: op = LOAD_GLOBAL; break;
    4171                 :        155 :         case Store: op = STORE_GLOBAL; break;
    4172                 :          0 :         case Del: op = DELETE_GLOBAL; break;
    4173                 :            :         }
    4174                 :      21555 :         break;
    4175   [ +  +  +  - ]:      20215 :     case OP_NAME:
    4176                 :            :         switch (ctx) {
    4177                 :       6996 :         case Load: op = LOAD_NAME; break;
    4178                 :      13085 :         case Store: op = STORE_NAME; break;
    4179                 :        134 :         case Del: op = DELETE_NAME; break;
    4180                 :            :         }
    4181                 :      20215 :         break;
    4182                 :            :     }
    4183                 :            : 
    4184                 :      44218 :     assert(op);
    4185                 :      44218 :     arg = dict_add_o(dict, mangled);
    4186                 :      44218 :     Py_DECREF(mangled);
    4187         [ -  + ]:      44218 :     if (arg < 0) {
    4188                 :          0 :         return ERROR;
    4189                 :            :     }
    4190         [ +  + ]:      44218 :     if (op == LOAD_GLOBAL) {
    4191                 :      21400 :         arg <<= 1;
    4192                 :            :     }
    4193                 :      44218 :     return codegen_addop_i(INSTR_SEQUENCE(c), op, arg, loc);
    4194                 :            : }
    4195                 :            : 
    4196                 :            : static int
    4197                 :        392 : compiler_boolop(struct compiler *c, expr_ty e)
    4198                 :            : {
    4199                 :            :     int jumpi;
    4200                 :            :     Py_ssize_t i, n;
    4201                 :            :     asdl_expr_seq *s;
    4202                 :            : 
    4203                 :        392 :     location loc = LOC(e);
    4204                 :            :     assert(e->kind == BoolOp_kind);
    4205         [ +  + ]:        392 :     if (e->v.BoolOp.op == And)
    4206                 :        152 :         jumpi = JUMP_IF_FALSE_OR_POP;
    4207                 :            :     else
    4208                 :        240 :         jumpi = JUMP_IF_TRUE_OR_POP;
    4209         [ -  + ]:        392 :     NEW_JUMP_TARGET_LABEL(c, end);
    4210                 :        392 :     s = e->v.BoolOp.values;
    4211         [ +  - ]:        392 :     n = asdl_seq_LEN(s) - 1;
    4212                 :            :     assert(n >= 0);
    4213         [ +  + ]:        846 :     for (i = 0; i < n; ++i) {
    4214         [ -  + ]:        454 :         VISIT(c, expr, (expr_ty)asdl_seq_GET(s, i));
    4215         [ -  + ]:        454 :         ADDOP_JUMP(c, loc, jumpi, end);
    4216         [ -  + ]:        454 :         NEW_JUMP_TARGET_LABEL(c, next);
    4217                 :            : 
    4218         [ -  + ]:        454 :         USE_LABEL(c, next);
    4219                 :            :     }
    4220         [ -  + ]:        392 :     VISIT(c, expr, (expr_ty)asdl_seq_GET(s, n));
    4221                 :            : 
    4222         [ -  + ]:        392 :     USE_LABEL(c, end);
    4223                 :        392 :     return SUCCESS;
    4224                 :            : }
    4225                 :            : 
    4226                 :            : static int
    4227                 :       3075 : starunpack_helper(struct compiler *c, location loc,
    4228                 :            :                   asdl_expr_seq *elts, int pushed,
    4229                 :            :                   int build, int add, int extend, int tuple)
    4230                 :            : {
    4231         [ +  + ]:       3075 :     Py_ssize_t n = asdl_seq_LEN(elts);
    4232   [ +  +  +  + ]:       3075 :     if (n > 2 && are_all_items_const(elts, 0, n)) {
    4233                 :        180 :         PyObject *folded = PyTuple_New(n);
    4234         [ -  + ]:        180 :         if (folded == NULL) {
    4235                 :          0 :             return ERROR;
    4236                 :            :         }
    4237                 :            :         PyObject *val;
    4238         [ +  + ]:       2505 :         for (Py_ssize_t i = 0; i < n; i++) {
    4239                 :       2325 :             val = ((expr_ty)asdl_seq_GET(elts, i))->v.Constant.value;
    4240                 :       2325 :             PyTuple_SET_ITEM(folded, i, Py_NewRef(val));
    4241                 :            :         }
    4242   [ +  +  +  - ]:        180 :         if (tuple && !pushed) {
    4243   [ -  +  -  + ]:          1 :             ADDOP_LOAD_CONST_NEW(c, loc, folded);
    4244                 :            :         } else {
    4245         [ +  + ]:        179 :             if (add == SET_ADD) {
    4246                 :          8 :                 Py_SETREF(folded, PyFrozenSet_New(folded));
    4247         [ -  + ]:          8 :                 if (folded == NULL) {
    4248                 :          0 :                     return ERROR;
    4249                 :            :                 }
    4250                 :            :             }
    4251         [ -  + ]:        179 :             ADDOP_I(c, loc, build, pushed);
    4252   [ -  +  -  + ]:        179 :             ADDOP_LOAD_CONST_NEW(c, loc, folded);
    4253         [ -  + ]:        179 :             ADDOP_I(c, loc, extend, 1);
    4254         [ -  + ]:        179 :             if (tuple) {
    4255         [ #  # ]:          0 :                 ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_LIST_TO_TUPLE);
    4256                 :            :             }
    4257                 :            :         }
    4258                 :        180 :         return SUCCESS;
    4259                 :            :     }
    4260                 :            : 
    4261                 :       2895 :     int big = n+pushed > STACK_USE_GUIDELINE;
    4262                 :       2895 :     int seen_star = 0;
    4263         [ +  + ]:       8326 :     for (Py_ssize_t i = 0; i < n; i++) {
    4264                 :       5562 :         expr_ty elt = asdl_seq_GET(elts, i);
    4265         [ +  + ]:       5562 :         if (elt->kind == Starred_kind) {
    4266                 :        131 :             seen_star = 1;
    4267                 :        131 :             break;
    4268                 :            :         }
    4269                 :            :     }
    4270   [ +  +  +  - ]:       2895 :     if (!seen_star && !big) {
    4271         [ +  + ]:       8019 :         for (Py_ssize_t i = 0; i < n; i++) {
    4272                 :       5255 :             expr_ty elt = asdl_seq_GET(elts, i);
    4273         [ -  + ]:       5255 :             VISIT(c, expr, elt);
    4274                 :            :         }
    4275         [ +  + ]:       2764 :         if (tuple) {
    4276         [ -  + ]:       1877 :             ADDOP_I(c, loc, BUILD_TUPLE, n+pushed);
    4277                 :            :         } else {
    4278         [ -  + ]:        887 :             ADDOP_I(c, loc, build, n+pushed);
    4279                 :            :         }
    4280                 :       2764 :         return SUCCESS;
    4281                 :            :     }
    4282                 :        131 :     int sequence_built = 0;
    4283         [ -  + ]:        131 :     if (big) {
    4284         [ #  # ]:          0 :         ADDOP_I(c, loc, build, pushed);
    4285                 :          0 :         sequence_built = 1;
    4286                 :            :     }
    4287         [ +  + ]:        456 :     for (Py_ssize_t i = 0; i < n; i++) {
    4288                 :        325 :         expr_ty elt = asdl_seq_GET(elts, i);
    4289         [ +  + ]:        325 :         if (elt->kind == Starred_kind) {
    4290         [ +  + ]:        140 :             if (sequence_built == 0) {
    4291         [ -  + ]:        131 :                 ADDOP_I(c, loc, build, i+pushed);
    4292                 :        131 :                 sequence_built = 1;
    4293                 :            :             }
    4294         [ -  + ]:        140 :             VISIT(c, expr, elt->v.Starred.value);
    4295         [ -  + ]:        140 :             ADDOP_I(c, loc, extend, 1);
    4296                 :            :         }
    4297                 :            :         else {
    4298         [ -  + ]:        185 :             VISIT(c, expr, elt);
    4299         [ +  + ]:        185 :             if (sequence_built) {
    4300         [ -  + ]:          9 :                 ADDOP_I(c, loc, add, 1);
    4301                 :            :             }
    4302                 :            :         }
    4303                 :            :     }
    4304                 :            :     assert(sequence_built);
    4305         [ +  + ]:        131 :     if (tuple) {
    4306         [ -  + ]:        129 :         ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_LIST_TO_TUPLE);
    4307                 :            :     }
    4308                 :        131 :     return SUCCESS;
    4309                 :            : }
    4310                 :            : 
    4311                 :            : static int
    4312                 :       1134 : unpack_helper(struct compiler *c, location loc, asdl_expr_seq *elts)
    4313                 :            : {
    4314         [ +  - ]:       1134 :     Py_ssize_t n = asdl_seq_LEN(elts);
    4315                 :       1134 :     int seen_star = 0;
    4316         [ +  + ]:       3864 :     for (Py_ssize_t i = 0; i < n; i++) {
    4317                 :       2730 :         expr_ty elt = asdl_seq_GET(elts, i);
    4318   [ +  +  +  - ]:       2730 :         if (elt->kind == Starred_kind && !seen_star) {
    4319         [ +  - ]:          7 :             if ((i >= (1 << 8)) ||
    4320         [ -  + ]:          7 :                 (n-i-1 >= (INT_MAX >> 8))) {
    4321                 :          0 :                 return compiler_error(c, loc,
    4322                 :            :                     "too many expressions in "
    4323                 :            :                     "star-unpacking assignment");
    4324                 :            :             }
    4325         [ -  + ]:          7 :             ADDOP_I(c, loc, UNPACK_EX, (i + ((n-i-1) << 8)));
    4326                 :          7 :             seen_star = 1;
    4327                 :            :         }
    4328         [ -  + ]:       2723 :         else if (elt->kind == Starred_kind) {
    4329                 :          0 :             return compiler_error(c, loc,
    4330                 :            :                 "multiple starred expressions in assignment");
    4331                 :            :         }
    4332                 :            :     }
    4333         [ +  + ]:       1134 :     if (!seen_star) {
    4334         [ -  + ]:       1127 :         ADDOP_I(c, loc, UNPACK_SEQUENCE, n);
    4335                 :            :     }
    4336                 :       1134 :     return SUCCESS;
    4337                 :            : }
    4338                 :            : 
    4339                 :            : static int
    4340                 :       1134 : assignment_helper(struct compiler *c, location loc, asdl_expr_seq *elts)
    4341                 :            : {
    4342         [ +  - ]:       1134 :     Py_ssize_t n = asdl_seq_LEN(elts);
    4343         [ -  + ]:       1134 :     RETURN_IF_ERROR(unpack_helper(c, loc, elts));
    4344         [ +  + ]:       3864 :     for (Py_ssize_t i = 0; i < n; i++) {
    4345                 :       2730 :         expr_ty elt = asdl_seq_GET(elts, i);
    4346   [ +  +  -  + ]:       2730 :         VISIT(c, expr, elt->kind != Starred_kind ? elt : elt->v.Starred.value);
    4347                 :            :     }
    4348                 :       1134 :     return SUCCESS;
    4349                 :            : }
    4350                 :            : 
    4351                 :            : static int
    4352                 :       1029 : compiler_list(struct compiler *c, expr_ty e)
    4353                 :            : {
    4354                 :       1029 :     location loc = LOC(e);
    4355                 :       1029 :     asdl_expr_seq *elts = e->v.List.elts;
    4356         [ +  + ]:       1029 :     if (e->v.List.ctx == Store) {
    4357                 :          1 :         return assignment_helper(c, loc, elts);
    4358                 :            :     }
    4359         [ +  - ]:       1028 :     else if (e->v.List.ctx == Load) {
    4360                 :       1028 :         return starunpack_helper(c, loc, elts, 0,
    4361                 :            :                                  BUILD_LIST, LIST_APPEND, LIST_EXTEND, 0);
    4362                 :            :     }
    4363                 :            :     else {
    4364   [ #  #  #  #  :          0 :         VISIT_SEQ(c, expr, elts);
                   #  # ]
    4365                 :            :     }
    4366                 :          0 :     return SUCCESS;
    4367                 :            : }
    4368                 :            : 
    4369                 :            : static int
    4370                 :       2952 : compiler_tuple(struct compiler *c, expr_ty e)
    4371                 :            : {
    4372                 :       2952 :     location loc = LOC(e);
    4373                 :       2952 :     asdl_expr_seq *elts = e->v.Tuple.elts;
    4374         [ +  + ]:       2952 :     if (e->v.Tuple.ctx == Store) {
    4375                 :       1133 :         return assignment_helper(c, loc, elts);
    4376                 :            :     }
    4377         [ +  + ]:       1819 :     else if (e->v.Tuple.ctx == Load) {
    4378                 :       1818 :         return starunpack_helper(c, loc, elts, 0,
    4379                 :            :                                  BUILD_LIST, LIST_APPEND, LIST_EXTEND, 1);
    4380                 :            :     }
    4381                 :            :     else {
    4382   [ -  +  +  -  :         43 :         VISIT_SEQ(c, expr, elts);
                   +  + ]
    4383                 :            :     }
    4384                 :          1 :     return SUCCESS;
    4385                 :            : }
    4386                 :            : 
    4387                 :            : static int
    4388                 :         40 : compiler_set(struct compiler *c, expr_ty e)
    4389                 :            : {
    4390                 :         40 :     location loc = LOC(e);
    4391                 :         40 :     return starunpack_helper(c, loc, e->v.Set.elts, 0,
    4392                 :            :                              BUILD_SET, SET_ADD, SET_UPDATE, 0);
    4393                 :            : }
    4394                 :            : 
    4395                 :            : static bool
    4396                 :        924 : are_all_items_const(asdl_expr_seq *seq, Py_ssize_t begin, Py_ssize_t end)
    4397                 :            : {
    4398         [ +  + ]:       3859 :     for (Py_ssize_t i = begin; i < end; i++) {
    4399                 :       3576 :         expr_ty key = (expr_ty)asdl_seq_GET(seq, i);
    4400   [ +  -  +  + ]:       3576 :         if (key == NULL || key->kind != Constant_kind) {
    4401                 :        641 :             return false;
    4402                 :            :         }
    4403                 :            :     }
    4404                 :        283 :     return true;
    4405                 :            : }
    4406                 :            : 
    4407                 :            : static int
    4408                 :        282 : compiler_subdict(struct compiler *c, expr_ty e, Py_ssize_t begin, Py_ssize_t end)
    4409                 :            : {
    4410                 :        282 :     Py_ssize_t i, n = end - begin;
    4411                 :            :     PyObject *keys, *key;
    4412                 :        282 :     int big = n*2 > STACK_USE_GUIDELINE;
    4413                 :        282 :     location loc = LOC(e);
    4414   [ +  +  +  +  :        282 :     if (n > 1 && !big && are_all_items_const(e->v.Dict.keys, begin, end)) {
                   +  + ]
    4415         [ +  + ]:        611 :         for (i = begin; i < end; i++) {
    4416         [ -  + ]:        508 :             VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
    4417                 :            :         }
    4418                 :        103 :         keys = PyTuple_New(n);
    4419         [ -  + ]:        103 :         if (keys == NULL) {
    4420                 :          0 :             return SUCCESS;
    4421                 :            :         }
    4422         [ +  + ]:        611 :         for (i = begin; i < end; i++) {
    4423                 :        508 :             key = ((expr_ty)asdl_seq_GET(e->v.Dict.keys, i))->v.Constant.value;
    4424                 :        508 :             PyTuple_SET_ITEM(keys, i - begin, Py_NewRef(key));
    4425                 :            :         }
    4426   [ -  +  -  + ]:        103 :         ADDOP_LOAD_CONST_NEW(c, loc, keys);
    4427         [ -  + ]:        103 :         ADDOP_I(c, loc, BUILD_CONST_KEY_MAP, n);
    4428                 :        103 :         return SUCCESS;
    4429                 :            :     }
    4430         [ +  + ]:        179 :     if (big) {
    4431         [ -  + ]:        135 :         ADDOP_I(c, loc, BUILD_MAP, 0);
    4432                 :            :     }
    4433         [ +  + ]:       2559 :     for (i = begin; i < end; i++) {
    4434         [ -  + ]:       2380 :         VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.keys, i));
    4435         [ -  + ]:       2380 :         VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
    4436         [ +  + ]:       2380 :         if (big) {
    4437         [ -  + ]:       2292 :             ADDOP_I(c, loc, MAP_ADD, 1);
    4438                 :            :         }
    4439                 :            :     }
    4440         [ +  + ]:        179 :     if (!big) {
    4441         [ -  + ]:         44 :         ADDOP_I(c, loc, BUILD_MAP, n);
    4442                 :            :     }
    4443                 :        179 :     return SUCCESS;
    4444                 :            : }
    4445                 :            : 
    4446                 :            : static int
    4447                 :        397 : compiler_dict(struct compiler *c, expr_ty e)
    4448                 :            : {
    4449                 :        397 :     location loc = LOC(e);
    4450                 :            :     Py_ssize_t i, n, elements;
    4451                 :            :     int have_dict;
    4452                 :        397 :     int is_unpacking = 0;
    4453         [ +  - ]:        397 :     n = asdl_seq_LEN(e->v.Dict.values);
    4454                 :        397 :     have_dict = 0;
    4455                 :        397 :     elements = 0;
    4456         [ +  + ]:       3297 :     for (i = 0; i < n; i++) {
    4457                 :       2900 :         is_unpacking = (expr_ty)asdl_seq_GET(e->v.Dict.keys, i) == NULL;
    4458         [ +  + ]:       2900 :         if (is_unpacking) {
    4459         [ -  + ]:         12 :             if (elements) {
    4460         [ #  # ]:          0 :                 RETURN_IF_ERROR(compiler_subdict(c, e, i - elements, i));
    4461         [ #  # ]:          0 :                 if (have_dict) {
    4462         [ #  # ]:          0 :                     ADDOP_I(c, loc, DICT_UPDATE, 1);
    4463                 :            :                 }
    4464                 :          0 :                 have_dict = 1;
    4465                 :          0 :                 elements = 0;
    4466                 :            :             }
    4467         [ +  + ]:         12 :             if (have_dict == 0) {
    4468         [ -  + ]:          6 :                 ADDOP_I(c, loc, BUILD_MAP, 0);
    4469                 :          6 :                 have_dict = 1;
    4470                 :            :             }
    4471         [ -  + ]:         12 :             VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Dict.values, i));
    4472         [ -  + ]:         12 :             ADDOP_I(c, loc, DICT_UPDATE, 1);
    4473                 :            :         }
    4474                 :            :         else {
    4475         [ +  + ]:       2888 :             if (elements*2 > STACK_USE_GUIDELINE) {
    4476         [ -  + ]:        132 :                 RETURN_IF_ERROR(compiler_subdict(c, e, i - elements, i + 1));
    4477         [ +  + ]:        132 :                 if (have_dict) {
    4478         [ -  + ]:        122 :                     ADDOP_I(c, loc, DICT_UPDATE, 1);
    4479                 :            :                 }
    4480                 :        132 :                 have_dict = 1;
    4481                 :        132 :                 elements = 0;
    4482                 :            :             }
    4483                 :            :             else {
    4484                 :       2756 :                 elements++;
    4485                 :            :             }
    4486                 :            :         }
    4487                 :            :     }
    4488         [ +  + ]:        397 :     if (elements) {
    4489         [ -  + ]:        150 :         RETURN_IF_ERROR(compiler_subdict(c, e, n - elements, n));
    4490         [ +  + ]:        150 :         if (have_dict) {
    4491         [ -  + ]:         10 :             ADDOP_I(c, loc, DICT_UPDATE, 1);
    4492                 :            :         }
    4493                 :        150 :         have_dict = 1;
    4494                 :            :     }
    4495         [ +  + ]:        397 :     if (!have_dict) {
    4496         [ -  + ]:        241 :         ADDOP_I(c, loc, BUILD_MAP, 0);
    4497                 :            :     }
    4498                 :        397 :     return SUCCESS;
    4499                 :            : }
    4500                 :            : 
    4501                 :            : static int
    4502                 :       6321 : compiler_compare(struct compiler *c, expr_ty e)
    4503                 :            : {
    4504                 :       6321 :     location loc = LOC(e);
    4505                 :            :     Py_ssize_t i, n;
    4506                 :            : 
    4507         [ -  + ]:       6321 :     RETURN_IF_ERROR(check_compare(c, e));
    4508         [ -  + ]:       6321 :     VISIT(c, expr, e->v.Compare.left);
    4509                 :            :     assert(asdl_seq_LEN(e->v.Compare.ops) > 0);
    4510         [ +  - ]:       6321 :     n = asdl_seq_LEN(e->v.Compare.ops) - 1;
    4511         [ +  + ]:       6321 :     if (n == 0) {
    4512         [ -  + ]:       6317 :         VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, 0));
    4513         [ -  + ]:       6317 :         ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, 0));
    4514                 :            :     }
    4515                 :            :     else {
    4516         [ -  + ]:          4 :         NEW_JUMP_TARGET_LABEL(c, cleanup);
    4517         [ +  + ]:          8 :         for (i = 0; i < n; i++) {
    4518         [ -  + ]:          4 :             VISIT(c, expr,
    4519                 :            :                 (expr_ty)asdl_seq_GET(e->v.Compare.comparators, i));
    4520         [ -  + ]:          4 :             ADDOP_I(c, loc, SWAP, 2);
    4521         [ -  + ]:          4 :             ADDOP_I(c, loc, COPY, 2);
    4522         [ -  + ]:          4 :             ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, i));
    4523         [ -  + ]:          4 :             ADDOP_JUMP(c, loc, JUMP_IF_FALSE_OR_POP, cleanup);
    4524                 :            :         }
    4525         [ -  + ]:          4 :         VISIT(c, expr, (expr_ty)asdl_seq_GET(e->v.Compare.comparators, n));
    4526         [ -  + ]:          4 :         ADDOP_COMPARE(c, loc, asdl_seq_GET(e->v.Compare.ops, n));
    4527         [ -  + ]:          4 :         NEW_JUMP_TARGET_LABEL(c, end);
    4528         [ -  + ]:          4 :         ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
    4529                 :            : 
    4530         [ -  + ]:          4 :         USE_LABEL(c, cleanup);
    4531         [ -  + ]:          4 :         ADDOP_I(c, loc, SWAP, 2);
    4532         [ -  + ]:          4 :         ADDOP(c, loc, POP_TOP);
    4533                 :            : 
    4534         [ -  + ]:          4 :         USE_LABEL(c, end);
    4535                 :            :     }
    4536                 :       6321 :     return SUCCESS;
    4537                 :            : }
    4538                 :            : 
    4539                 :            : static PyTypeObject *
    4540                 :       2593 : infer_type(expr_ty e)
    4541                 :            : {
    4542   [ +  -  -  -  :       2593 :     switch (e->kind) {
             -  -  -  +  
                      + ]
    4543                 :         43 :     case Tuple_kind:
    4544                 :         43 :         return &PyTuple_Type;
    4545                 :          0 :     case List_kind:
    4546                 :            :     case ListComp_kind:
    4547                 :          0 :         return &PyList_Type;
    4548                 :          0 :     case Dict_kind:
    4549                 :            :     case DictComp_kind:
    4550                 :          0 :         return &PyDict_Type;
    4551                 :          0 :     case Set_kind:
    4552                 :            :     case SetComp_kind:
    4553                 :          0 :         return &PySet_Type;
    4554                 :          0 :     case GeneratorExp_kind:
    4555                 :          0 :         return &PyGen_Type;
    4556                 :          0 :     case Lambda_kind:
    4557                 :          0 :         return &PyFunction_Type;
    4558                 :          0 :     case JoinedStr_kind:
    4559                 :            :     case FormattedValue_kind:
    4560                 :          0 :         return &PyUnicode_Type;
    4561                 :       1070 :     case Constant_kind:
    4562                 :       1070 :         return Py_TYPE(e->v.Constant.value);
    4563                 :       1480 :     default:
    4564                 :       1480 :         return NULL;
    4565                 :            :     }
    4566                 :            : }
    4567                 :            : 
    4568                 :            : static int
    4569                 :      15536 : check_caller(struct compiler *c, expr_ty e)
    4570                 :            : {
    4571         [ -  + ]:      15536 :     switch (e->kind) {
    4572                 :          0 :     case Constant_kind:
    4573                 :            :     case Tuple_kind:
    4574                 :            :     case List_kind:
    4575                 :            :     case ListComp_kind:
    4576                 :            :     case Dict_kind:
    4577                 :            :     case DictComp_kind:
    4578                 :            :     case Set_kind:
    4579                 :            :     case SetComp_kind:
    4580                 :            :     case GeneratorExp_kind:
    4581                 :            :     case JoinedStr_kind:
    4582                 :            :     case FormattedValue_kind: {
    4583                 :          0 :         location loc = LOC(e);
    4584                 :          0 :         return compiler_warn(c, loc, "'%.200s' object is not callable; "
    4585                 :            :                                      "perhaps you missed a comma?",
    4586                 :          0 :                                      infer_type(e)->tp_name);
    4587                 :            :     }
    4588                 :      15536 :     default:
    4589                 :      15536 :         return SUCCESS;
    4590                 :            :     }
    4591                 :            : }
    4592                 :            : 
    4593                 :            : static int
    4594                 :       2593 : check_subscripter(struct compiler *c, expr_ty e)
    4595                 :            : {
    4596                 :            :     PyObject *v;
    4597                 :            : 
    4598      [ -  -  + ]:       2593 :     switch (e->kind) {
    4599                 :          0 :     case Constant_kind:
    4600                 :          0 :         v = e->v.Constant.value;
    4601   [ #  #  #  #  :          0 :         if (!(v == Py_None || v == Py_Ellipsis ||
             #  #  #  # ]
    4602   [ #  #  #  # ]:          0 :               PyLong_Check(v) || PyFloat_Check(v) || PyComplex_Check(v) ||
    4603   [ #  #  #  #  :          0 :               PyAnySet_Check(v)))
                   #  # ]
    4604                 :            :         {
    4605                 :          0 :             return SUCCESS;
    4606                 :            :         }
    4607                 :            :         /* fall through */
    4608                 :            :     case Set_kind:
    4609                 :            :     case SetComp_kind:
    4610                 :            :     case GeneratorExp_kind:
    4611                 :            :     case Lambda_kind: {
    4612                 :          0 :         location loc = LOC(e);
    4613                 :          0 :         return compiler_warn(c, loc, "'%.200s' object is not subscriptable; "
    4614                 :            :                                      "perhaps you missed a comma?",
    4615                 :          0 :                                      infer_type(e)->tp_name);
    4616                 :            :     }
    4617                 :       2593 :     default:
    4618                 :       2593 :         return SUCCESS;
    4619                 :            :     }
    4620                 :            : }
    4621                 :            : 
    4622                 :            : static int
    4623                 :       2593 : check_index(struct compiler *c, expr_ty e, expr_ty s)
    4624                 :            : {
    4625                 :            :     PyObject *v;
    4626                 :            : 
    4627                 :       2593 :     PyTypeObject *index_type = infer_type(s);
    4628         [ +  + ]:       2593 :     if (index_type == NULL
    4629         [ +  + ]:       1113 :         || PyType_FastSubclass(index_type, Py_TPFLAGS_LONG_SUBCLASS)
    4630         [ -  + ]:        153 :         || index_type == &PySlice_Type) {
    4631                 :       2440 :         return SUCCESS;
    4632                 :            :     }
    4633                 :            : 
    4634      [ -  -  + ]:        153 :     switch (e->kind) {
    4635                 :          0 :     case Constant_kind:
    4636                 :          0 :         v = e->v.Constant.value;
    4637   [ #  #  #  #  :          0 :         if (!(PyUnicode_Check(v) || PyBytes_Check(v) || PyTuple_Check(v))) {
                   #  # ]
    4638                 :          0 :             return SUCCESS;
    4639                 :            :         }
    4640                 :            :         /* fall through */
    4641                 :            :     case Tuple_kind:
    4642                 :            :     case List_kind:
    4643                 :            :     case ListComp_kind:
    4644                 :            :     case JoinedStr_kind:
    4645                 :            :     case FormattedValue_kind: {
    4646                 :          0 :         location loc = LOC(e);
    4647                 :          0 :         return compiler_warn(c, loc, "%.200s indices must be integers "
    4648                 :            :                                      "or slices, not %.200s; "
    4649                 :            :                                      "perhaps you missed a comma?",
    4650                 :          0 :                                      infer_type(e)->tp_name,
    4651                 :            :                                      index_type->tp_name);
    4652                 :            :     }
    4653                 :        153 :     default:
    4654                 :        153 :         return SUCCESS;
    4655                 :            :     }
    4656                 :            : }
    4657                 :            : 
    4658                 :            : static int
    4659                 :      13833 : is_import_originated(struct compiler *c, expr_ty e)
    4660                 :            : {
    4661                 :            :     /* Check whether the global scope has an import named
    4662                 :            :      e, if it is a Name object. For not traversing all the
    4663                 :            :      scope stack every time this function is called, it will
    4664                 :            :      only check the global scope to determine whether something
    4665                 :            :      is imported or not. */
    4666                 :            : 
    4667         [ +  + ]:      13833 :     if (e->kind != Name_kind) {
    4668                 :       2962 :         return 0;
    4669                 :            :     }
    4670                 :            : 
    4671                 :      10871 :     long flags = _PyST_GetSymbol(c->c_st->st_top, e->v.Name.id);
    4672                 :      10871 :     return flags & DEF_IMPORT;
    4673                 :            : }
    4674                 :            : 
    4675                 :            : // If an attribute access spans multiple lines, update the current start
    4676                 :            : // location to point to the attribute name.
    4677                 :            : static location
    4678                 :      41161 : update_start_location_to_match_attr(struct compiler *c, location loc,
    4679                 :            :                                     expr_ty attr)
    4680                 :            : {
    4681                 :            :     assert(attr->kind == Attribute_kind);
    4682         [ +  + ]:      41161 :     if (loc.lineno != attr->end_lineno) {
    4683                 :         80 :         loc.lineno = attr->end_lineno;
    4684                 :         80 :         int len = (int)PyUnicode_GET_LENGTH(attr->v.Attribute.attr);
    4685         [ +  - ]:         80 :         if (len <= attr->end_col_offset) {
    4686                 :         80 :             loc.col_offset = attr->end_col_offset - len;
    4687                 :            :         }
    4688                 :            :         else {
    4689                 :            :             // GH-94694: Somebody's compiling weird ASTs. Just drop the columns:
    4690                 :          0 :             loc.col_offset = -1;
    4691                 :          0 :             loc.end_col_offset = -1;
    4692                 :            :         }
    4693                 :            :         // Make sure the end position still follows the start position, even for
    4694                 :            :         // weird ASTs:
    4695                 :         80 :         loc.end_lineno = Py_MAX(loc.lineno, loc.end_lineno);
    4696         [ +  + ]:         80 :         if (loc.lineno == loc.end_lineno) {
    4697                 :         75 :             loc.end_col_offset = Py_MAX(loc.col_offset, loc.end_col_offset);
    4698                 :            :         }
    4699                 :            :     }
    4700                 :      41161 :     return loc;
    4701                 :            : }
    4702                 :            : 
    4703                 :            : // Return 1 if the method call was optimized, 0 if not, and -1 on error.
    4704                 :            : static int
    4705                 :      26546 : maybe_optimize_method_call(struct compiler *c, expr_ty e)
    4706                 :            : {
    4707                 :            :     Py_ssize_t argsl, i, kwdsl;
    4708                 :      26546 :     expr_ty meth = e->v.Call.func;
    4709                 :      26546 :     asdl_expr_seq *args = e->v.Call.args;
    4710                 :      26546 :     asdl_keyword_seq *kwds = e->v.Call.keywords;
    4711                 :            : 
    4712                 :            :     /* Check that the call node is an attribute access */
    4713   [ +  +  -  + ]:      26546 :     if (meth->kind != Attribute_kind || meth->v.Attribute.ctx != Load) {
    4714                 :      12713 :         return 0;
    4715                 :            :     }
    4716                 :            : 
    4717                 :            :     /* Check that the base object is not something that is imported */
    4718         [ +  + ]:      13833 :     if (is_import_originated(c, meth->v.Attribute.value)) {
    4719                 :       2657 :         return 0;
    4720                 :            :     }
    4721                 :            : 
    4722                 :            :     /* Check that there aren't too many arguments */
    4723         [ +  + ]:      11176 :     argsl = asdl_seq_LEN(args);
    4724         [ +  + ]:      11176 :     kwdsl = asdl_seq_LEN(kwds);
    4725         [ -  + ]:      11176 :     if (argsl + kwdsl + (kwdsl != 0) >= STACK_USE_GUIDELINE) {
    4726                 :          0 :         return 0;
    4727                 :            :     }
    4728                 :            :     /* Check that there are no *varargs types of arguments. */
    4729         [ +  + ]:      23164 :     for (i = 0; i < argsl; i++) {
    4730                 :      12118 :         expr_ty elt = asdl_seq_GET(args, i);
    4731         [ +  + ]:      12118 :         if (elt->kind == Starred_kind) {
    4732                 :        130 :             return 0;
    4733                 :            :         }
    4734                 :            :     }
    4735                 :            : 
    4736         [ +  + ]:      11859 :     for (i = 0; i < kwdsl; i++) {
    4737                 :        849 :         keyword_ty kw = asdl_seq_GET(kwds, i);
    4738         [ +  + ]:        849 :         if (kw->arg == NULL) {
    4739                 :         36 :             return 0;
    4740                 :            :         }
    4741                 :            :     }
    4742                 :            :     /* Alright, we can optimize the code. */
    4743         [ -  + ]:      11010 :     VISIT(c, expr, meth->v.Attribute.value);
    4744                 :      11010 :     location loc = LOC(meth);
    4745                 :      11010 :     loc = update_start_location_to_match_attr(c, loc, meth);
    4746         [ -  + ]:      11010 :     ADDOP_NAME(c, loc, LOAD_METHOD, meth->v.Attribute.attr, names);
    4747   [ -  +  +  +  :      22825 :     VISIT_SEQ(c, expr, e->v.Call.args);
                   +  + ]
    4748                 :            : 
    4749         [ +  + ]:      11010 :     if (kwdsl) {
    4750   [ -  +  +  -  :       1236 :         VISIT_SEQ(c, keyword, kwds);
                   +  + ]
    4751         [ -  + ]:        433 :         RETURN_IF_ERROR(
    4752                 :            :             compiler_call_simple_kw_helper(c, loc, kwds, kwdsl));
    4753                 :            :     }
    4754                 :      11010 :     loc = update_start_location_to_match_attr(c, LOC(e), meth);
    4755         [ -  + ]:      11010 :     ADDOP_I(c, loc, CALL, argsl + kwdsl);
    4756                 :      11010 :     return 1;
    4757                 :            : }
    4758                 :            : 
    4759                 :            : static int
    4760                 :      42815 : validate_keywords(struct compiler *c, asdl_keyword_seq *keywords)
    4761                 :            : {
    4762         [ +  + ]:      42815 :     Py_ssize_t nkeywords = asdl_seq_LEN(keywords);
    4763         [ +  + ]:      46334 :     for (Py_ssize_t i = 0; i < nkeywords; i++) {
    4764                 :       3519 :         keyword_ty key = ((keyword_ty)asdl_seq_GET(keywords, i));
    4765         [ +  + ]:       3519 :         if (key->arg == NULL) {
    4766                 :        362 :             continue;
    4767                 :            :         }
    4768                 :       3157 :         location loc = LOC(key);
    4769         [ -  + ]:       3157 :         if (forbidden_name(c, loc, key->arg, Store)) {
    4770                 :          0 :             return ERROR;
    4771                 :            :         }
    4772         [ +  + ]:       5646 :         for (Py_ssize_t j = i + 1; j < nkeywords; j++) {
    4773                 :       2489 :             keyword_ty other = ((keyword_ty)asdl_seq_GET(keywords, j));
    4774   [ +  +  -  + ]:       2489 :             if (other->arg && !PyUnicode_Compare(key->arg, other->arg)) {
    4775                 :          0 :                 compiler_error(c, LOC(other), "keyword argument repeated: %U", key->arg);
    4776                 :          0 :                 return ERROR;
    4777                 :            :             }
    4778                 :            :         }
    4779                 :            :     }
    4780                 :      42815 :     return SUCCESS;
    4781                 :            : }
    4782                 :            : 
    4783                 :            : static int
    4784                 :      26546 : compiler_call(struct compiler *c, expr_ty e)
    4785                 :            : {
    4786         [ -  + ]:      26546 :     RETURN_IF_ERROR(validate_keywords(c, e->v.Call.keywords));
    4787                 :      26546 :     int ret = maybe_optimize_method_call(c, e);
    4788         [ -  + ]:      26546 :     if (ret < 0) {
    4789                 :          0 :         return ERROR;
    4790                 :            :     }
    4791         [ +  + ]:      26546 :     if (ret == 1) {
    4792                 :      11010 :         return SUCCESS;
    4793                 :            :     }
    4794         [ -  + ]:      15536 :     RETURN_IF_ERROR(check_caller(c, e->v.Call.func));
    4795                 :      15536 :     location loc = LOC(e->v.Call.func);
    4796         [ -  + ]:      15536 :     ADDOP(c, loc, PUSH_NULL);
    4797         [ -  + ]:      15536 :     VISIT(c, expr, e->v.Call.func);
    4798                 :      15536 :     loc = LOC(e);
    4799                 :      15536 :     return compiler_call_helper(c, loc, 0,
    4800                 :            :                                 e->v.Call.args,
    4801                 :            :                                 e->v.Call.keywords);
    4802                 :            : }
    4803                 :            : 
    4804                 :            : static int
    4805                 :       1188 : compiler_joined_str(struct compiler *c, expr_ty e)
    4806                 :            : {
    4807                 :       1188 :     location loc = LOC(e);
    4808         [ +  - ]:       1188 :     Py_ssize_t value_count = asdl_seq_LEN(e->v.JoinedStr.values);
    4809         [ -  + ]:       1188 :     if (value_count > STACK_USE_GUIDELINE) {
    4810                 :            :         _Py_DECLARE_STR(empty, "");
    4811   [ #  #  #  # ]:          0 :         ADDOP_LOAD_CONST_NEW(c, loc, Py_NewRef(&_Py_STR(empty)));
    4812         [ #  # ]:          0 :         ADDOP_NAME(c, loc, LOAD_METHOD, &_Py_ID(join), names);
    4813         [ #  # ]:          0 :         ADDOP_I(c, loc, BUILD_LIST, 0);
    4814   [ #  #  #  # ]:          0 :         for (Py_ssize_t i = 0; i < asdl_seq_LEN(e->v.JoinedStr.values); i++) {
    4815         [ #  # ]:          0 :             VISIT(c, expr, asdl_seq_GET(e->v.JoinedStr.values, i));
    4816         [ #  # ]:          0 :             ADDOP_I(c, loc, LIST_APPEND, 1);
    4817                 :            :         }
    4818         [ #  # ]:          0 :         ADDOP_I(c, loc, CALL, 1);
    4819                 :            :     }
    4820                 :            :     else {
    4821   [ -  +  +  -  :       5021 :         VISIT_SEQ(c, expr, e->v.JoinedStr.values);
                   +  + ]
    4822   [ +  -  +  + ]:       1188 :         if (asdl_seq_LEN(e->v.JoinedStr.values) != 1) {
    4823   [ +  -  -  + ]:       1130 :             ADDOP_I(c, loc, BUILD_STRING, asdl_seq_LEN(e->v.JoinedStr.values));
    4824                 :            :         }
    4825                 :            :     }
    4826                 :       1188 :     return SUCCESS;
    4827                 :            : }
    4828                 :            : 
    4829                 :            : /* Used to implement f-strings. Format a single value. */
    4830                 :            : static int
    4831                 :       1826 : compiler_formatted_value(struct compiler *c, expr_ty e)
    4832                 :            : {
    4833                 :            :     /* Our oparg encodes 2 pieces of information: the conversion
    4834                 :            :        character, and whether or not a format_spec was provided.
    4835                 :            : 
    4836                 :            :        Convert the conversion char to 3 bits:
    4837                 :            :            : 000  0x0  FVC_NONE   The default if nothing specified.
    4838                 :            :        !s  : 001  0x1  FVC_STR
    4839                 :            :        !r  : 010  0x2  FVC_REPR
    4840                 :            :        !a  : 011  0x3  FVC_ASCII
    4841                 :            : 
    4842                 :            :        next bit is whether or not we have a format spec:
    4843                 :            :        yes : 100  0x4
    4844                 :            :        no  : 000  0x0
    4845                 :            :     */
    4846                 :            : 
    4847                 :       1826 :     int conversion = e->v.FormattedValue.conversion;
    4848                 :            :     int oparg;
    4849                 :            : 
    4850                 :            :     /* The expression to be formatted. */
    4851         [ -  + ]:       1826 :     VISIT(c, expr, e->v.FormattedValue.value);
    4852                 :            : 
    4853   [ +  +  -  +  :       1826 :     switch (conversion) {
                      - ]
    4854                 :        417 :     case 's': oparg = FVC_STR;   break;
    4855                 :        482 :     case 'r': oparg = FVC_REPR;  break;
    4856                 :          0 :     case 'a': oparg = FVC_ASCII; break;
    4857                 :        927 :     case -1:  oparg = FVC_NONE;  break;
    4858                 :          0 :     default:
    4859                 :          0 :         PyErr_Format(PyExc_SystemError,
    4860                 :            :                      "Unrecognized conversion character %d", conversion);
    4861                 :          0 :         return ERROR;
    4862                 :            :     }
    4863         [ +  + ]:       1826 :     if (e->v.FormattedValue.format_spec) {
    4864                 :            :         /* Evaluate the format spec, and update our opcode arg. */
    4865         [ -  + ]:         39 :         VISIT(c, expr, e->v.FormattedValue.format_spec);
    4866                 :         39 :         oparg |= FVS_HAVE_SPEC;
    4867                 :            :     }
    4868                 :            : 
    4869                 :            :     /* And push our opcode and oparg */
    4870                 :       1826 :     location loc = LOC(e);
    4871         [ -  + ]:       1826 :     ADDOP_I(c, loc, FORMAT_VALUE, oparg);
    4872                 :            : 
    4873                 :       1826 :     return SUCCESS;
    4874                 :            : }
    4875                 :            : 
    4876                 :            : static int
    4877                 :         24 : compiler_subkwargs(struct compiler *c, location loc,
    4878                 :            :                    asdl_keyword_seq *keywords,
    4879                 :            :                    Py_ssize_t begin, Py_ssize_t end)
    4880                 :            : {
    4881                 :         24 :     Py_ssize_t i, n = end - begin;
    4882                 :            :     keyword_ty kw;
    4883                 :            :     PyObject *keys, *key;
    4884                 :            :     assert(n > 0);
    4885                 :         24 :     int big = n*2 > STACK_USE_GUIDELINE;
    4886   [ +  +  +  - ]:         24 :     if (n > 1 && !big) {
    4887         [ +  + ]:         39 :         for (i = begin; i < end; i++) {
    4888                 :         30 :             kw = asdl_seq_GET(keywords, i);
    4889         [ -  + ]:         30 :             VISIT(c, expr, kw->value);
    4890                 :            :         }
    4891                 :          9 :         keys = PyTuple_New(n);
    4892         [ -  + ]:          9 :         if (keys == NULL) {
    4893                 :          0 :             return ERROR;
    4894                 :            :         }
    4895         [ +  + ]:         39 :         for (i = begin; i < end; i++) {
    4896                 :         30 :             key = ((keyword_ty) asdl_seq_GET(keywords, i))->arg;
    4897                 :         30 :             PyTuple_SET_ITEM(keys, i - begin, Py_NewRef(key));
    4898                 :            :         }
    4899   [ -  +  -  + ]:          9 :         ADDOP_LOAD_CONST_NEW(c, loc, keys);
    4900         [ -  + ]:          9 :         ADDOP_I(c, loc, BUILD_CONST_KEY_MAP, n);
    4901                 :          9 :         return SUCCESS;
    4902                 :            :     }
    4903         [ -  + ]:         15 :     if (big) {
    4904         [ #  # ]:          0 :         ADDOP_I(c, NO_LOCATION, BUILD_MAP, 0);
    4905                 :            :     }
    4906         [ +  + ]:         30 :     for (i = begin; i < end; i++) {
    4907                 :         15 :         kw = asdl_seq_GET(keywords, i);
    4908         [ -  + ]:         15 :         ADDOP_LOAD_CONST(c, loc, kw->arg);
    4909         [ -  + ]:         15 :         VISIT(c, expr, kw->value);
    4910         [ -  + ]:         15 :         if (big) {
    4911         [ #  # ]:          0 :             ADDOP_I(c, NO_LOCATION, MAP_ADD, 1);
    4912                 :            :         }
    4913                 :            :     }
    4914         [ +  - ]:         15 :     if (!big) {
    4915         [ -  + ]:         15 :         ADDOP_I(c, loc, BUILD_MAP, n);
    4916                 :            :     }
    4917                 :         15 :     return SUCCESS;
    4918                 :            : }
    4919                 :            : 
    4920                 :            : /* Used by compiler_call_helper and maybe_optimize_method_call to emit
    4921                 :            :  * KW_NAMES before CALL.
    4922                 :            :  */
    4923                 :            : static int
    4924                 :       1195 : compiler_call_simple_kw_helper(struct compiler *c, location loc,
    4925                 :            :                                asdl_keyword_seq *keywords, Py_ssize_t nkwelts)
    4926                 :            : {
    4927                 :            :     PyObject *names;
    4928                 :       1195 :     names = PyTuple_New(nkwelts);
    4929         [ -  + ]:       1195 :     if (names == NULL) {
    4930                 :          0 :         return ERROR;
    4931                 :            :     }
    4932         [ +  + ]:       3158 :     for (int i = 0; i < nkwelts; i++) {
    4933                 :       1963 :         keyword_ty kw = asdl_seq_GET(keywords, i);
    4934                 :       1963 :         PyTuple_SET_ITEM(names, i, Py_NewRef(kw->arg));
    4935                 :            :     }
    4936                 :       1195 :     Py_ssize_t arg = compiler_add_const(c->c_const_cache, c->u, names);
    4937         [ -  + ]:       1195 :     if (arg < 0) {
    4938                 :          0 :         return ERROR;
    4939                 :            :     }
    4940                 :       1195 :     Py_DECREF(names);
    4941         [ -  + ]:       1195 :     ADDOP_I(c, loc, KW_NAMES, arg);
    4942                 :       1195 :     return SUCCESS;
    4943                 :            : }
    4944                 :            : 
    4945                 :            : 
    4946                 :            : /* shared code between compiler_call and compiler_class */
    4947                 :            : static int
    4948                 :      16269 : compiler_call_helper(struct compiler *c, location loc,
    4949                 :            :                      int n, /* Args already pushed */
    4950                 :            :                      asdl_expr_seq *args,
    4951                 :            :                      asdl_keyword_seq *keywords)
    4952                 :            : {
    4953                 :            :     Py_ssize_t i, nseen, nelts, nkwelts;
    4954                 :            : 
    4955         [ -  + ]:      16269 :     RETURN_IF_ERROR(validate_keywords(c, keywords));
    4956                 :            : 
    4957         [ +  + ]:      16269 :     nelts = asdl_seq_LEN(args);
    4958         [ +  + ]:      16269 :     nkwelts = asdl_seq_LEN(keywords);
    4959                 :            : 
    4960         [ +  + ]:      16269 :     if (nelts + nkwelts*2 > STACK_USE_GUIDELINE) {
    4961                 :          1 :          goto ex_call;
    4962                 :            :     }
    4963         [ +  + ]:      38166 :     for (i = 0; i < nelts; i++) {
    4964                 :      22179 :         expr_ty elt = asdl_seq_GET(args, i);
    4965         [ +  + ]:      22179 :         if (elt->kind == Starred_kind) {
    4966                 :        281 :             goto ex_call;
    4967                 :            :         }
    4968                 :            :     }
    4969         [ +  + ]:      17171 :     for (i = 0; i < nkwelts; i++) {
    4970                 :       1257 :         keyword_ty kw = asdl_seq_GET(keywords, i);
    4971         [ +  + ]:       1257 :         if (kw->arg == NULL) {
    4972                 :         73 :             goto ex_call;
    4973                 :            :         }
    4974                 :            :     }
    4975                 :            : 
    4976                 :            :     /* No * or ** args, so can use faster calling sequence */
    4977         [ +  + ]:      37530 :     for (i = 0; i < nelts; i++) {
    4978                 :      21616 :         expr_ty elt = asdl_seq_GET(args, i);
    4979                 :            :         assert(elt->kind != Starred_kind);
    4980         [ -  + ]:      21616 :         VISIT(c, expr, elt);
    4981                 :            :     }
    4982         [ +  + ]:      15914 :     if (nkwelts) {
    4983   [ -  +  +  -  :       1922 :         VISIT_SEQ(c, keyword, keywords);
                   +  + ]
    4984         [ -  + ]:        762 :         RETURN_IF_ERROR(
    4985                 :            :             compiler_call_simple_kw_helper(c, loc, keywords, nkwelts));
    4986                 :            :     }
    4987         [ -  + ]:      15914 :     ADDOP_I(c, loc, CALL, n + nelts + nkwelts);
    4988                 :      15914 :     return SUCCESS;
    4989                 :            : 
    4990                 :        355 : ex_call:
    4991                 :            : 
    4992                 :            :     /* Do positional arguments. */
    4993   [ +  -  +  +  :        355 :     if (n ==0 && nelts == 1 && ((expr_ty)asdl_seq_GET(args, 0))->kind == Starred_kind) {
                   +  + ]
    4994         [ -  + ]:        166 :         VISIT(c, expr, ((expr_ty)asdl_seq_GET(args, 0))->v.Starred.value);
    4995                 :            :     }
    4996                 :            :     else {
    4997         [ -  + ]:        189 :         RETURN_IF_ERROR(starunpack_helper(c, loc, args, n, BUILD_LIST,
    4998                 :            :                                           LIST_APPEND, LIST_EXTEND, 1));
    4999                 :            :     }
    5000                 :            :     /* Then keyword arguments */
    5001         [ +  + ]:        355 :     if (nkwelts) {
    5002                 :            :         /* Has a new dict been pushed */
    5003                 :        189 :         int have_dict = 0;
    5004                 :            : 
    5005                 :        189 :         nseen = 0;  /* the number of keyword arguments on the stack following */
    5006         [ +  + ]:        415 :         for (i = 0; i < nkwelts; i++) {
    5007                 :        226 :             keyword_ty kw = asdl_seq_GET(keywords, i);
    5008         [ +  + ]:        226 :             if (kw->arg == NULL) {
    5009                 :            :                 /* A keyword argument unpacking. */
    5010         [ +  + ]:        181 :                 if (nseen) {
    5011         [ -  + ]:         16 :                     RETURN_IF_ERROR(compiler_subkwargs(c, loc, keywords, i - nseen, i));
    5012         [ -  + ]:         16 :                     if (have_dict) {
    5013         [ #  # ]:          0 :                         ADDOP_I(c, loc, DICT_MERGE, 1);
    5014                 :            :                     }
    5015                 :         16 :                     have_dict = 1;
    5016                 :         16 :                     nseen = 0;
    5017                 :            :                 }
    5018         [ +  + ]:        181 :                 if (!have_dict) {
    5019         [ -  + ]:        165 :                     ADDOP_I(c, loc, BUILD_MAP, 0);
    5020                 :        165 :                     have_dict = 1;
    5021                 :            :                 }
    5022         [ -  + ]:        181 :                 VISIT(c, expr, kw->value);
    5023         [ -  + ]:        181 :                 ADDOP_I(c, loc, DICT_MERGE, 1);
    5024                 :            :             }
    5025                 :            :             else {
    5026                 :         45 :                 nseen++;
    5027                 :            :             }
    5028                 :            :         }
    5029         [ +  + ]:        189 :         if (nseen) {
    5030                 :            :             /* Pack up any trailing keyword arguments. */
    5031         [ -  + ]:          8 :             RETURN_IF_ERROR(compiler_subkwargs(c, loc, keywords, nkwelts - nseen, nkwelts));
    5032         [ -  + ]:          8 :             if (have_dict) {
    5033         [ #  # ]:          0 :                 ADDOP_I(c, loc, DICT_MERGE, 1);
    5034                 :            :             }
    5035                 :          8 :             have_dict = 1;
    5036                 :            :         }
    5037                 :            :         assert(have_dict);
    5038                 :            :     }
    5039         [ -  + ]:        355 :     ADDOP_I(c, loc, CALL_FUNCTION_EX, nkwelts > 0);
    5040                 :        355 :     return SUCCESS;
    5041                 :            : }
    5042                 :            : 
    5043                 :            : 
    5044                 :            : /* List and set comprehensions and generator expressions work by creating a
    5045                 :            :   nested function to perform the actual iteration. This means that the
    5046                 :            :   iteration variables don't leak into the current scope.
    5047                 :            :   The defined function is called immediately following its definition, with the
    5048                 :            :   result of that call being the result of the expression.
    5049                 :            :   The LC/SC version returns the populated container, while the GE version is
    5050                 :            :   flagged in symtable.c as a generator, so it returns the generator object
    5051                 :            :   when the function is called.
    5052                 :            : 
    5053                 :            :   Possible cleanups:
    5054                 :            :     - iterate over the generator sequence instead of using recursion
    5055                 :            : */
    5056                 :            : 
    5057                 :            : 
    5058                 :            : static int
    5059                 :        471 : compiler_comprehension_generator(struct compiler *c, location loc,
    5060                 :            :                                  asdl_comprehension_seq *generators, int gen_index,
    5061                 :            :                                  int depth,
    5062                 :            :                                  expr_ty elt, expr_ty val, int type)
    5063                 :            : {
    5064                 :            :     comprehension_ty gen;
    5065                 :        471 :     gen = (comprehension_ty)asdl_seq_GET(generators, gen_index);
    5066         [ -  + ]:        471 :     if (gen->is_async) {
    5067                 :          0 :         return compiler_async_comprehension_generator(
    5068                 :            :             c, loc, generators, gen_index, depth, elt, val, type);
    5069                 :            :     } else {
    5070                 :        471 :         return compiler_sync_comprehension_generator(
    5071                 :            :             c, loc, generators, gen_index, depth, elt, val, type);
    5072                 :            :     }
    5073                 :            : }
    5074                 :            : 
    5075                 :            : static int
    5076                 :        471 : compiler_sync_comprehension_generator(struct compiler *c, location loc,
    5077                 :            :                                       asdl_comprehension_seq *generators,
    5078                 :            :                                       int gen_index, int depth,
    5079                 :            :                                       expr_ty elt, expr_ty val, int type)
    5080                 :            : {
    5081                 :            :     /* generate code for the iterator, then each of the ifs,
    5082                 :            :        and then write to the element */
    5083                 :            : 
    5084         [ -  + ]:        471 :     NEW_JUMP_TARGET_LABEL(c, start);
    5085         [ -  + ]:        471 :     NEW_JUMP_TARGET_LABEL(c, if_cleanup);
    5086         [ -  + ]:        471 :     NEW_JUMP_TARGET_LABEL(c, anchor);
    5087                 :            : 
    5088                 :        471 :     comprehension_ty gen = (comprehension_ty)asdl_seq_GET(generators,
    5089                 :            :                                                           gen_index);
    5090                 :            : 
    5091         [ +  + ]:        471 :     if (gen_index == 0) {
    5092                 :            :         /* Receive outermost iter as an implicit argument */
    5093                 :        453 :         c->u->u_argcount = 1;
    5094         [ -  + ]:        453 :         ADDOP_I(c, loc, LOAD_FAST, 0);
    5095                 :            :     }
    5096                 :            :     else {
    5097                 :            :         /* Sub-iter - calculate on the fly */
    5098                 :            :         /* Fast path for the temporary variable assignment idiom:
    5099                 :            :              for y in [f(x)]
    5100                 :            :          */
    5101                 :            :         asdl_expr_seq *elts;
    5102      [ -  -  + ]:         18 :         switch (gen->iter->kind) {
    5103                 :          0 :             case List_kind:
    5104                 :          0 :                 elts = gen->iter->v.List.elts;
    5105                 :          0 :                 break;
    5106                 :          0 :             case Tuple_kind:
    5107                 :          0 :                 elts = gen->iter->v.Tuple.elts;
    5108                 :          0 :                 break;
    5109                 :         18 :             default:
    5110                 :         18 :                 elts = NULL;
    5111                 :            :         }
    5112   [ -  +  -  - ]:         18 :         if (asdl_seq_LEN(elts) == 1) {
    5113                 :          0 :             expr_ty elt = asdl_seq_GET(elts, 0);
    5114         [ #  # ]:          0 :             if (elt->kind != Starred_kind) {
    5115         [ #  # ]:          0 :                 VISIT(c, expr, elt);
    5116                 :          0 :                 start = NO_LABEL;
    5117                 :            :             }
    5118                 :            :         }
    5119         [ +  - ]:         18 :         if (IS_LABEL(start)) {
    5120         [ -  + ]:         18 :             VISIT(c, expr, gen->iter);
    5121         [ -  + ]:         18 :             ADDOP(c, loc, GET_ITER);
    5122                 :            :         }
    5123                 :            :     }
    5124         [ +  - ]:        471 :     if (IS_LABEL(start)) {
    5125                 :        471 :         depth++;
    5126         [ -  + ]:        471 :         USE_LABEL(c, start);
    5127         [ -  + ]:        471 :         ADDOP_JUMP(c, loc, FOR_ITER, anchor);
    5128                 :            :     }
    5129         [ -  + ]:        471 :     VISIT(c, expr, gen->target);
    5130                 :            : 
    5131                 :            :     /* XXX this needs to be cleaned up...a lot! */
    5132         [ +  - ]:        471 :     Py_ssize_t n = asdl_seq_LEN(gen->ifs);
    5133         [ +  + ]:        591 :     for (Py_ssize_t i = 0; i < n; i++) {
    5134                 :        120 :         expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i);
    5135         [ -  + ]:        120 :         RETURN_IF_ERROR(compiler_jump_if(c, loc, e, if_cleanup, 0));
    5136                 :            :     }
    5137                 :            : 
    5138   [ +  -  +  + ]:        471 :     if (++gen_index < asdl_seq_LEN(generators)) {
    5139         [ -  + ]:         18 :         RETURN_IF_ERROR(
    5140                 :            :             compiler_comprehension_generator(c, loc,
    5141                 :            :                                              generators, gen_index, depth,
    5142                 :            :                                              elt, val, type));
    5143                 :            :     }
    5144                 :            : 
    5145                 :        471 :     location elt_loc = LOC(elt);
    5146                 :            : 
    5147                 :            :     /* only append after the last for generator */
    5148   [ +  -  +  + ]:        471 :     if (gen_index >= asdl_seq_LEN(generators)) {
    5149                 :            :         /* comprehension specific code */
    5150   [ +  +  +  +  :        453 :         switch (type) {
                      - ]
    5151                 :        197 :         case COMP_GENEXP:
    5152         [ -  + ]:        197 :             VISIT(c, expr, elt);
    5153         [ -  + ]:        197 :             ADDOP_YIELD(c, elt_loc);
    5154         [ -  + ]:        197 :             ADDOP(c, elt_loc, POP_TOP);
    5155                 :        453 :             break;
    5156                 :        219 :         case COMP_LISTCOMP:
    5157         [ -  + ]:        219 :             VISIT(c, expr, elt);
    5158         [ -  + ]:        219 :             ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1);
    5159                 :        219 :             break;
    5160                 :         14 :         case COMP_SETCOMP:
    5161         [ -  + ]:         14 :             VISIT(c, expr, elt);
    5162         [ -  + ]:         14 :             ADDOP_I(c, elt_loc, SET_ADD, depth + 1);
    5163                 :         14 :             break;
    5164                 :         23 :         case COMP_DICTCOMP:
    5165                 :            :             /* With '{k: v}', k is evaluated before v, so we do
    5166                 :            :                the same. */
    5167         [ -  + ]:         23 :             VISIT(c, expr, elt);
    5168         [ -  + ]:         23 :             VISIT(c, expr, val);
    5169                 :         23 :             elt_loc = LOCATION(elt->lineno,
    5170                 :            :                                val->end_lineno,
    5171                 :            :                                elt->col_offset,
    5172                 :            :                                val->end_col_offset);
    5173         [ -  + ]:         23 :             ADDOP_I(c, elt_loc, MAP_ADD, depth + 1);
    5174                 :         23 :             break;
    5175                 :          0 :         default:
    5176                 :          0 :             return ERROR;
    5177                 :            :         }
    5178                 :         18 :     }
    5179                 :            : 
    5180         [ -  + ]:        471 :     USE_LABEL(c, if_cleanup);
    5181         [ +  - ]:        471 :     if (IS_LABEL(start)) {
    5182         [ -  + ]:        471 :         ADDOP_JUMP(c, elt_loc, JUMP, start);
    5183                 :            : 
    5184         [ -  + ]:        471 :         USE_LABEL(c, anchor);
    5185         [ -  + ]:        471 :         ADDOP(c, NO_LOCATION, END_FOR);
    5186                 :            :     }
    5187                 :            : 
    5188                 :        471 :     return SUCCESS;
    5189                 :            : }
    5190                 :            : 
    5191                 :            : static int
    5192                 :          0 : compiler_async_comprehension_generator(struct compiler *c, location loc,
    5193                 :            :                                       asdl_comprehension_seq *generators,
    5194                 :            :                                       int gen_index, int depth,
    5195                 :            :                                       expr_ty elt, expr_ty val, int type)
    5196                 :            : {
    5197         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, start);
    5198         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, except);
    5199         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, if_cleanup);
    5200                 :            : 
    5201                 :          0 :     comprehension_ty gen = (comprehension_ty)asdl_seq_GET(generators,
    5202                 :            :                                                           gen_index);
    5203                 :            : 
    5204         [ #  # ]:          0 :     if (gen_index == 0) {
    5205                 :            :         /* Receive outermost iter as an implicit argument */
    5206                 :          0 :         c->u->u_argcount = 1;
    5207         [ #  # ]:          0 :         ADDOP_I(c, loc, LOAD_FAST, 0);
    5208                 :            :     }
    5209                 :            :     else {
    5210                 :            :         /* Sub-iter - calculate on the fly */
    5211         [ #  # ]:          0 :         VISIT(c, expr, gen->iter);
    5212         [ #  # ]:          0 :         ADDOP(c, loc, GET_AITER);
    5213                 :            :     }
    5214                 :            : 
    5215         [ #  # ]:          0 :     USE_LABEL(c, start);
    5216                 :            :     /* Runtime will push a block here, so we need to account for that */
    5217         [ #  # ]:          0 :     RETURN_IF_ERROR(
    5218                 :            :         compiler_push_fblock(c, loc, ASYNC_COMPREHENSION_GENERATOR,
    5219                 :            :                              start, NO_LABEL, NULL));
    5220                 :            : 
    5221         [ #  # ]:          0 :     ADDOP_JUMP(c, loc, SETUP_FINALLY, except);
    5222         [ #  # ]:          0 :     ADDOP(c, loc, GET_ANEXT);
    5223         [ #  # ]:          0 :     ADDOP_LOAD_CONST(c, loc, Py_None);
    5224         [ #  # ]:          0 :     ADD_YIELD_FROM(c, loc, 1);
    5225         [ #  # ]:          0 :     ADDOP(c, loc, POP_BLOCK);
    5226         [ #  # ]:          0 :     VISIT(c, expr, gen->target);
    5227                 :            : 
    5228         [ #  # ]:          0 :     Py_ssize_t n = asdl_seq_LEN(gen->ifs);
    5229         [ #  # ]:          0 :     for (Py_ssize_t i = 0; i < n; i++) {
    5230                 :          0 :         expr_ty e = (expr_ty)asdl_seq_GET(gen->ifs, i);
    5231         [ #  # ]:          0 :         RETURN_IF_ERROR(compiler_jump_if(c, loc, e, if_cleanup, 0));
    5232                 :            :     }
    5233                 :            : 
    5234                 :          0 :     depth++;
    5235   [ #  #  #  # ]:          0 :     if (++gen_index < asdl_seq_LEN(generators)) {
    5236         [ #  # ]:          0 :         RETURN_IF_ERROR(
    5237                 :            :             compiler_comprehension_generator(c, loc,
    5238                 :            :                                              generators, gen_index, depth,
    5239                 :            :                                              elt, val, type));
    5240                 :            :     }
    5241                 :            : 
    5242                 :          0 :     location elt_loc = LOC(elt);
    5243                 :            :     /* only append after the last for generator */
    5244   [ #  #  #  # ]:          0 :     if (gen_index >= asdl_seq_LEN(generators)) {
    5245                 :            :         /* comprehension specific code */
    5246   [ #  #  #  #  :          0 :         switch (type) {
                      # ]
    5247                 :          0 :         case COMP_GENEXP:
    5248         [ #  # ]:          0 :             VISIT(c, expr, elt);
    5249         [ #  # ]:          0 :             ADDOP_YIELD(c, elt_loc);
    5250         [ #  # ]:          0 :             ADDOP(c, elt_loc, POP_TOP);
    5251                 :          0 :             break;
    5252                 :          0 :         case COMP_LISTCOMP:
    5253         [ #  # ]:          0 :             VISIT(c, expr, elt);
    5254         [ #  # ]:          0 :             ADDOP_I(c, elt_loc, LIST_APPEND, depth + 1);
    5255                 :          0 :             break;
    5256                 :          0 :         case COMP_SETCOMP:
    5257         [ #  # ]:          0 :             VISIT(c, expr, elt);
    5258         [ #  # ]:          0 :             ADDOP_I(c, elt_loc, SET_ADD, depth + 1);
    5259                 :          0 :             break;
    5260                 :          0 :         case COMP_DICTCOMP:
    5261                 :            :             /* With '{k: v}', k is evaluated before v, so we do
    5262                 :            :                the same. */
    5263         [ #  # ]:          0 :             VISIT(c, expr, elt);
    5264         [ #  # ]:          0 :             VISIT(c, expr, val);
    5265                 :          0 :             elt_loc = LOCATION(elt->lineno,
    5266                 :            :                                val->end_lineno,
    5267                 :            :                                elt->col_offset,
    5268                 :            :                                val->end_col_offset);
    5269         [ #  # ]:          0 :             ADDOP_I(c, elt_loc, MAP_ADD, depth + 1);
    5270                 :          0 :             break;
    5271                 :          0 :         default:
    5272                 :          0 :             return ERROR;
    5273                 :            :         }
    5274                 :          0 :     }
    5275                 :            : 
    5276         [ #  # ]:          0 :     USE_LABEL(c, if_cleanup);
    5277         [ #  # ]:          0 :     ADDOP_JUMP(c, elt_loc, JUMP, start);
    5278                 :            : 
    5279                 :          0 :     compiler_pop_fblock(c, ASYNC_COMPREHENSION_GENERATOR, start);
    5280                 :            : 
    5281         [ #  # ]:          0 :     USE_LABEL(c, except);
    5282                 :            : 
    5283         [ #  # ]:          0 :     ADDOP(c, loc, END_ASYNC_FOR);
    5284                 :            : 
    5285                 :          0 :     return SUCCESS;
    5286                 :            : }
    5287                 :            : 
    5288                 :            : static int
    5289                 :        453 : compiler_comprehension(struct compiler *c, expr_ty e, int type,
    5290                 :            :                        identifier name, asdl_comprehension_seq *generators, expr_ty elt,
    5291                 :            :                        expr_ty val)
    5292                 :            : {
    5293                 :        453 :     PyCodeObject *co = NULL;
    5294                 :            :     comprehension_ty outermost;
    5295                 :        453 :     int scope_type = c->u->u_scope_type;
    5296                 :        453 :     int is_async_generator = 0;
    5297   [ -  +  -  - ]:        453 :     int is_top_level_await = IS_TOP_LEVEL_AWAIT(c);
    5298                 :            : 
    5299                 :        453 :     outermost = (comprehension_ty) asdl_seq_GET(generators, 0);
    5300         [ -  + ]:        453 :     if (compiler_enter_scope(c, name, COMPILER_SCOPE_COMPREHENSION,
    5301                 :            :                              (void *)e, e->lineno) < 0)
    5302                 :            :     {
    5303                 :          0 :         goto error;
    5304                 :            :     }
    5305                 :        453 :     location loc = LOC(e);
    5306                 :            : 
    5307                 :        453 :     is_async_generator = c->u->u_ste->ste_coroutine;
    5308                 :            : 
    5309   [ -  +  -  -  :        453 :     if (is_async_generator && type != COMP_GENEXP &&
                   -  - ]
    5310         [ #  # ]:          0 :         scope_type != COMPILER_SCOPE_ASYNC_FUNCTION &&
    5311         [ #  # ]:          0 :         scope_type != COMPILER_SCOPE_COMPREHENSION &&
    5312                 :            :         !is_top_level_await)
    5313                 :            :     {
    5314                 :          0 :         compiler_error(c, loc, "asynchronous comprehension outside of "
    5315                 :            :                                "an asynchronous function");
    5316                 :          0 :         goto error_in_scope;
    5317                 :            :     }
    5318                 :            : 
    5319         [ +  + ]:        453 :     if (type != COMP_GENEXP) {
    5320                 :            :         int op;
    5321   [ +  +  +  - ]:        256 :         switch (type) {
    5322                 :        219 :         case COMP_LISTCOMP:
    5323                 :        219 :             op = BUILD_LIST;
    5324                 :        219 :             break;
    5325                 :         14 :         case COMP_SETCOMP:
    5326                 :         14 :             op = BUILD_SET;
    5327                 :         14 :             break;
    5328                 :         23 :         case COMP_DICTCOMP:
    5329                 :         23 :             op = BUILD_MAP;
    5330                 :         23 :             break;
    5331                 :          0 :         default:
    5332                 :          0 :             PyErr_Format(PyExc_SystemError,
    5333                 :            :                          "unknown comprehension type %d", type);
    5334                 :          0 :             goto error_in_scope;
    5335                 :            :         }
    5336                 :            : 
    5337         [ -  + ]:        256 :         ADDOP_I(c, loc, op, 0);
    5338                 :            :     }
    5339                 :            : 
    5340         [ -  + ]:        453 :     if (compiler_comprehension_generator(c, loc, generators, 0, 0,
    5341                 :            :                                          elt, val, type) < 0) {
    5342                 :          0 :         goto error_in_scope;
    5343                 :            :     }
    5344                 :            : 
    5345         [ +  + ]:        453 :     if (type != COMP_GENEXP) {
    5346         [ -  + ]:        256 :         ADDOP(c, LOC(e), RETURN_VALUE);
    5347                 :            :     }
    5348         [ +  + ]:        453 :     if (type == COMP_GENEXP) {
    5349         [ -  + ]:        197 :         if (wrap_in_stopiteration_handler(c) < 0) {
    5350                 :          0 :             goto error_in_scope;
    5351                 :            :         }
    5352                 :            :     }
    5353                 :            : 
    5354                 :        453 :     co = assemble(c, 1);
    5355                 :        453 :     compiler_exit_scope(c);
    5356   [ -  +  -  - ]:        453 :     if (is_top_level_await && is_async_generator){
    5357                 :          0 :         c->u->u_ste->ste_coroutine = 1;
    5358                 :            :     }
    5359         [ -  + ]:        453 :     if (co == NULL) {
    5360                 :          0 :         goto error;
    5361                 :            :     }
    5362                 :            : 
    5363                 :        453 :     loc = LOC(e);
    5364         [ -  + ]:        453 :     if (compiler_make_closure(c, loc, co, 0) < 0) {
    5365                 :          0 :         goto error;
    5366                 :            :     }
    5367                 :        453 :     Py_DECREF(co);
    5368                 :            : 
    5369         [ -  + ]:        453 :     VISIT(c, expr, outermost->iter);
    5370                 :            : 
    5371                 :        453 :     loc = LOC(e);
    5372         [ -  + ]:        453 :     if (outermost->is_async) {
    5373         [ #  # ]:          0 :         ADDOP(c, loc, GET_AITER);
    5374                 :            :     } else {
    5375         [ -  + ]:        453 :         ADDOP(c, loc, GET_ITER);
    5376                 :            :     }
    5377                 :            : 
    5378         [ -  + ]:        453 :     ADDOP_I(c, loc, CALL, 0);
    5379                 :            : 
    5380   [ -  +  -  - ]:        453 :     if (is_async_generator && type != COMP_GENEXP) {
    5381         [ #  # ]:          0 :         ADDOP_I(c, loc, GET_AWAITABLE, 0);
    5382         [ #  # ]:          0 :         ADDOP_LOAD_CONST(c, loc, Py_None);
    5383         [ #  # ]:          0 :         ADD_YIELD_FROM(c, loc, 1);
    5384                 :            :     }
    5385                 :            : 
    5386                 :        453 :     return SUCCESS;
    5387                 :          0 : error_in_scope:
    5388                 :          0 :     compiler_exit_scope(c);
    5389                 :          0 : error:
    5390                 :          0 :     Py_XDECREF(co);
    5391                 :          0 :     return ERROR;
    5392                 :            : }
    5393                 :            : 
    5394                 :            : static int
    5395                 :        197 : compiler_genexp(struct compiler *c, expr_ty e)
    5396                 :            : {
    5397                 :            :     assert(e->kind == GeneratorExp_kind);
    5398                 :            :     _Py_DECLARE_STR(anon_genexpr, "<genexpr>");
    5399                 :        197 :     return compiler_comprehension(c, e, COMP_GENEXP, &_Py_STR(anon_genexpr),
    5400                 :            :                                   e->v.GeneratorExp.generators,
    5401                 :            :                                   e->v.GeneratorExp.elt, NULL);
    5402                 :            : }
    5403                 :            : 
    5404                 :            : static int
    5405                 :        219 : compiler_listcomp(struct compiler *c, expr_ty e)
    5406                 :            : {
    5407                 :            :     assert(e->kind == ListComp_kind);
    5408                 :            :     _Py_DECLARE_STR(anon_listcomp, "<listcomp>");
    5409                 :        219 :     return compiler_comprehension(c, e, COMP_LISTCOMP, &_Py_STR(anon_listcomp),
    5410                 :            :                                   e->v.ListComp.generators,
    5411                 :            :                                   e->v.ListComp.elt, NULL);
    5412                 :            : }
    5413                 :            : 
    5414                 :            : static int
    5415                 :         14 : compiler_setcomp(struct compiler *c, expr_ty e)
    5416                 :            : {
    5417                 :            :     assert(e->kind == SetComp_kind);
    5418                 :            :     _Py_DECLARE_STR(anon_setcomp, "<setcomp>");
    5419                 :         14 :     return compiler_comprehension(c, e, COMP_SETCOMP, &_Py_STR(anon_setcomp),
    5420                 :            :                                   e->v.SetComp.generators,
    5421                 :            :                                   e->v.SetComp.elt, NULL);
    5422                 :            : }
    5423                 :            : 
    5424                 :            : 
    5425                 :            : static int
    5426                 :         23 : compiler_dictcomp(struct compiler *c, expr_ty e)
    5427                 :            : {
    5428                 :            :     assert(e->kind == DictComp_kind);
    5429                 :            :     _Py_DECLARE_STR(anon_dictcomp, "<dictcomp>");
    5430                 :         23 :     return compiler_comprehension(c, e, COMP_DICTCOMP, &_Py_STR(anon_dictcomp),
    5431                 :            :                                   e->v.DictComp.generators,
    5432                 :            :                                   e->v.DictComp.key, e->v.DictComp.value);
    5433                 :            : }
    5434                 :            : 
    5435                 :            : 
    5436                 :            : static int
    5437                 :       1963 : compiler_visit_keyword(struct compiler *c, keyword_ty k)
    5438                 :            : {
    5439         [ -  + ]:       1963 :     VISIT(c, expr, k->value);
    5440                 :       1963 :     return SUCCESS;
    5441                 :            : }
    5442                 :            : 
    5443                 :            : 
    5444                 :            : static int
    5445                 :        389 : compiler_with_except_finish(struct compiler *c, jump_target_label cleanup) {
    5446         [ -  + ]:        389 :     NEW_JUMP_TARGET_LABEL(c, suppress);
    5447         [ -  + ]:        389 :     ADDOP_JUMP(c, NO_LOCATION, POP_JUMP_IF_TRUE, suppress);
    5448         [ -  + ]:        389 :     ADDOP_I(c, NO_LOCATION, RERAISE, 2);
    5449                 :            : 
    5450         [ -  + ]:        389 :     USE_LABEL(c, suppress);
    5451         [ -  + ]:        389 :     ADDOP(c, NO_LOCATION, POP_TOP); /* exc_value */
    5452         [ -  + ]:        389 :     ADDOP(c, NO_LOCATION, POP_BLOCK);
    5453         [ -  + ]:        389 :     ADDOP(c, NO_LOCATION, POP_EXCEPT);
    5454         [ -  + ]:        389 :     ADDOP(c, NO_LOCATION, POP_TOP);
    5455         [ -  + ]:        389 :     ADDOP(c, NO_LOCATION, POP_TOP);
    5456         [ -  + ]:        389 :     NEW_JUMP_TARGET_LABEL(c, exit);
    5457         [ -  + ]:        389 :     ADDOP_JUMP(c, NO_LOCATION, JUMP, exit);
    5458                 :            : 
    5459         [ -  + ]:        389 :     USE_LABEL(c, cleanup);
    5460         [ -  + ]:        389 :     POP_EXCEPT_AND_RERAISE(c, NO_LOCATION);
    5461                 :            : 
    5462         [ -  + ]:        389 :     USE_LABEL(c, exit);
    5463                 :        389 :     return SUCCESS;
    5464                 :            : }
    5465                 :            : 
    5466                 :            : /*
    5467                 :            :    Implements the async with statement.
    5468                 :            : 
    5469                 :            :    The semantics outlined in that PEP are as follows:
    5470                 :            : 
    5471                 :            :    async with EXPR as VAR:
    5472                 :            :        BLOCK
    5473                 :            : 
    5474                 :            :    It is implemented roughly as:
    5475                 :            : 
    5476                 :            :    context = EXPR
    5477                 :            :    exit = context.__aexit__  # not calling it
    5478                 :            :    value = await context.__aenter__()
    5479                 :            :    try:
    5480                 :            :        VAR = value  # if VAR present in the syntax
    5481                 :            :        BLOCK
    5482                 :            :    finally:
    5483                 :            :        if an exception was raised:
    5484                 :            :            exc = copy of (exception, instance, traceback)
    5485                 :            :        else:
    5486                 :            :            exc = (None, None, None)
    5487                 :            :        if not (await exit(*exc)):
    5488                 :            :            raise
    5489                 :            :  */
    5490                 :            : static int
    5491                 :          5 : compiler_async_with(struct compiler *c, stmt_ty s, int pos)
    5492                 :            : {
    5493                 :          5 :     location loc = LOC(s);
    5494                 :          5 :     withitem_ty item = asdl_seq_GET(s->v.AsyncWith.items, pos);
    5495                 :            : 
    5496                 :            :     assert(s->kind == AsyncWith_kind);
    5497   [ -  +  -  - ]:          5 :     if (IS_TOP_LEVEL_AWAIT(c)){
    5498                 :          0 :         c->u->u_ste->ste_coroutine = 1;
    5499         [ -  + ]:          5 :     } else if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION){
    5500                 :          0 :         return compiler_error(c, loc, "'async with' outside async function");
    5501                 :            :     }
    5502                 :            : 
    5503         [ -  + ]:          5 :     NEW_JUMP_TARGET_LABEL(c, block);
    5504         [ -  + ]:          5 :     NEW_JUMP_TARGET_LABEL(c, final);
    5505         [ -  + ]:          5 :     NEW_JUMP_TARGET_LABEL(c, exit);
    5506         [ -  + ]:          5 :     NEW_JUMP_TARGET_LABEL(c, cleanup);
    5507                 :            : 
    5508                 :            :     /* Evaluate EXPR */
    5509         [ -  + ]:          5 :     VISIT(c, expr, item->context_expr);
    5510                 :            : 
    5511         [ -  + ]:          5 :     ADDOP(c, loc, BEFORE_ASYNC_WITH);
    5512         [ -  + ]:          5 :     ADDOP_I(c, loc, GET_AWAITABLE, 1);
    5513         [ -  + ]:          5 :     ADDOP_LOAD_CONST(c, loc, Py_None);
    5514         [ -  + ]:          5 :     ADD_YIELD_FROM(c, loc, 1);
    5515                 :            : 
    5516         [ -  + ]:          5 :     ADDOP_JUMP(c, loc, SETUP_WITH, final);
    5517                 :            : 
    5518                 :            :     /* SETUP_WITH pushes a finally block. */
    5519         [ -  + ]:          5 :     USE_LABEL(c, block);
    5520         [ -  + ]:          5 :     RETURN_IF_ERROR(compiler_push_fblock(c, loc, ASYNC_WITH, block, final, s));
    5521                 :            : 
    5522         [ -  + ]:          5 :     if (item->optional_vars) {
    5523         [ #  # ]:          0 :         VISIT(c, expr, item->optional_vars);
    5524                 :            :     }
    5525                 :            :     else {
    5526                 :            :         /* Discard result from context.__aenter__() */
    5527         [ -  + ]:          5 :         ADDOP(c, loc, POP_TOP);
    5528                 :            :     }
    5529                 :            : 
    5530                 :          5 :     pos++;
    5531   [ +  -  +  - ]:          5 :     if (pos == asdl_seq_LEN(s->v.AsyncWith.items)) {
    5532                 :            :         /* BLOCK code */
    5533   [ -  +  +  -  :         13 :         VISIT_SEQ(c, stmt, s->v.AsyncWith.body)
                   +  + ]
    5534                 :            :     }
    5535                 :            :     else {
    5536         [ #  # ]:          0 :         RETURN_IF_ERROR(compiler_async_with(c, s, pos));
    5537                 :            :     }
    5538                 :            : 
    5539                 :          5 :     compiler_pop_fblock(c, ASYNC_WITH, block);
    5540                 :            : 
    5541         [ -  + ]:          5 :     ADDOP(c, loc, POP_BLOCK);
    5542                 :            :     /* End of body; start the cleanup */
    5543                 :            : 
    5544                 :            :     /* For successful outcome:
    5545                 :            :      * call __exit__(None, None, None)
    5546                 :            :      */
    5547         [ -  + ]:          5 :     RETURN_IF_ERROR(compiler_call_exit_with_nones(c, loc));
    5548         [ -  + ]:          5 :     ADDOP_I(c, loc, GET_AWAITABLE, 2);
    5549         [ -  + ]:          5 :     ADDOP_LOAD_CONST(c, loc, Py_None);
    5550         [ -  + ]:          5 :     ADD_YIELD_FROM(c, loc, 1);
    5551                 :            : 
    5552         [ -  + ]:          5 :     ADDOP(c, loc, POP_TOP);
    5553                 :            : 
    5554         [ -  + ]:          5 :     ADDOP_JUMP(c, loc, JUMP, exit);
    5555                 :            : 
    5556                 :            :     /* For exceptional outcome: */
    5557         [ -  + ]:          5 :     USE_LABEL(c, final);
    5558                 :            : 
    5559         [ -  + ]:          5 :     ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
    5560         [ -  + ]:          5 :     ADDOP(c, loc, PUSH_EXC_INFO);
    5561         [ -  + ]:          5 :     ADDOP(c, loc, WITH_EXCEPT_START);
    5562         [ -  + ]:          5 :     ADDOP_I(c, loc, GET_AWAITABLE, 2);
    5563         [ -  + ]:          5 :     ADDOP_LOAD_CONST(c, loc, Py_None);
    5564         [ -  + ]:          5 :     ADD_YIELD_FROM(c, loc, 1);
    5565         [ -  + ]:          5 :     RETURN_IF_ERROR(compiler_with_except_finish(c, cleanup));
    5566                 :            : 
    5567         [ -  + ]:          5 :     USE_LABEL(c, exit);
    5568                 :          5 :     return SUCCESS;
    5569                 :            : }
    5570                 :            : 
    5571                 :            : 
    5572                 :            : /*
    5573                 :            :    Implements the with statement from PEP 343.
    5574                 :            :    with EXPR as VAR:
    5575                 :            :        BLOCK
    5576                 :            :    is implemented as:
    5577                 :            :         <code for EXPR>
    5578                 :            :         SETUP_WITH  E
    5579                 :            :         <code to store to VAR> or POP_TOP
    5580                 :            :         <code for BLOCK>
    5581                 :            :         LOAD_CONST (None, None, None)
    5582                 :            :         CALL_FUNCTION_EX 0
    5583                 :            :         JUMP  EXIT
    5584                 :            :     E:  WITH_EXCEPT_START (calls EXPR.__exit__)
    5585                 :            :         POP_JUMP_IF_TRUE T:
    5586                 :            :         RERAISE
    5587                 :            :     T:  POP_TOP (remove exception from stack)
    5588                 :            :         POP_EXCEPT
    5589                 :            :         POP_TOP
    5590                 :            :     EXIT:
    5591                 :            :  */
    5592                 :            : 
    5593                 :            : static int
    5594                 :        384 : compiler_with(struct compiler *c, stmt_ty s, int pos)
    5595                 :            : {
    5596                 :        384 :     withitem_ty item = asdl_seq_GET(s->v.With.items, pos);
    5597                 :            : 
    5598                 :            :     assert(s->kind == With_kind);
    5599                 :            : 
    5600         [ -  + ]:        384 :     NEW_JUMP_TARGET_LABEL(c, block);
    5601         [ -  + ]:        384 :     NEW_JUMP_TARGET_LABEL(c, final);
    5602         [ -  + ]:        384 :     NEW_JUMP_TARGET_LABEL(c, exit);
    5603         [ -  + ]:        384 :     NEW_JUMP_TARGET_LABEL(c, cleanup);
    5604                 :            : 
    5605                 :            :     /* Evaluate EXPR */
    5606         [ -  + ]:        384 :     VISIT(c, expr, item->context_expr);
    5607                 :            :     /* Will push bound __exit__ */
    5608                 :        384 :     location loc = LOC(s);
    5609         [ -  + ]:        384 :     ADDOP(c, loc, BEFORE_WITH);
    5610         [ -  + ]:        384 :     ADDOP_JUMP(c, loc, SETUP_WITH, final);
    5611                 :            : 
    5612                 :            :     /* SETUP_WITH pushes a finally block. */
    5613         [ -  + ]:        384 :     USE_LABEL(c, block);
    5614         [ -  + ]:        384 :     RETURN_IF_ERROR(compiler_push_fblock(c, loc, WITH, block, final, s));
    5615                 :            : 
    5616         [ +  + ]:        384 :     if (item->optional_vars) {
    5617         [ -  + ]:        143 :         VISIT(c, expr, item->optional_vars);
    5618                 :            :     }
    5619                 :            :     else {
    5620                 :            :     /* Discard result from context.__enter__() */
    5621         [ -  + ]:        241 :         ADDOP(c, loc, POP_TOP);
    5622                 :            :     }
    5623                 :            : 
    5624                 :        384 :     pos++;
    5625   [ +  -  +  + ]:        384 :     if (pos == asdl_seq_LEN(s->v.With.items)) {
    5626                 :            :         /* BLOCK code */
    5627   [ -  +  +  -  :       1131 :         VISIT_SEQ(c, stmt, s->v.With.body)
                   +  + ]
    5628                 :            :     }
    5629                 :            :     else {
    5630         [ -  + ]:          5 :         RETURN_IF_ERROR(compiler_with(c, s, pos));
    5631                 :            :     }
    5632                 :            : 
    5633         [ -  + ]:        384 :     ADDOP(c, NO_LOCATION, POP_BLOCK);
    5634                 :        384 :     compiler_pop_fblock(c, WITH, block);
    5635                 :            : 
    5636                 :            :     /* End of body; start the cleanup. */
    5637                 :            : 
    5638                 :            :     /* For successful outcome:
    5639                 :            :      * call __exit__(None, None, None)
    5640                 :            :      */
    5641                 :        384 :     loc = LOC(s);
    5642         [ -  + ]:        384 :     RETURN_IF_ERROR(compiler_call_exit_with_nones(c, loc));
    5643         [ -  + ]:        384 :     ADDOP(c, loc, POP_TOP);
    5644         [ -  + ]:        384 :     ADDOP_JUMP(c, loc, JUMP, exit);
    5645                 :            : 
    5646                 :            :     /* For exceptional outcome: */
    5647         [ -  + ]:        384 :     USE_LABEL(c, final);
    5648                 :            : 
    5649         [ -  + ]:        384 :     ADDOP_JUMP(c, loc, SETUP_CLEANUP, cleanup);
    5650         [ -  + ]:        384 :     ADDOP(c, loc, PUSH_EXC_INFO);
    5651         [ -  + ]:        384 :     ADDOP(c, loc, WITH_EXCEPT_START);
    5652         [ -  + ]:        384 :     RETURN_IF_ERROR(compiler_with_except_finish(c, cleanup));
    5653                 :            : 
    5654         [ -  + ]:        384 :     USE_LABEL(c, exit);
    5655                 :        384 :     return SUCCESS;
    5656                 :            : }
    5657                 :            : 
    5658                 :            : static int
    5659                 :     201007 : compiler_visit_expr1(struct compiler *c, expr_ty e)
    5660                 :            : {
    5661                 :     201007 :     location loc = LOC(e);
    5662   [ +  +  +  +  :     201007 :     switch (e->kind) {
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  +  +  
          +  +  +  -  +  
             +  +  +  - ]
    5663                 :         32 :     case NamedExpr_kind:
    5664         [ -  + ]:     146610 :         VISIT(c, expr, e->v.NamedExpr.value);
    5665         [ -  + ]:         32 :         ADDOP_I(c, loc, COPY, 1);
    5666         [ -  + ]:         32 :         VISIT(c, expr, e->v.NamedExpr.target);
    5667                 :      54429 :         break;
    5668                 :        392 :     case BoolOp_kind:
    5669                 :        392 :         return compiler_boolop(c, e);
    5670                 :       3541 :     case BinOp_kind:
    5671         [ -  + ]:       3541 :         VISIT(c, expr, e->v.BinOp.left);
    5672         [ -  + ]:       3541 :         VISIT(c, expr, e->v.BinOp.right);
    5673         [ -  + ]:       3541 :         ADDOP_BINARY(c, loc, e->v.BinOp.op);
    5674                 :       3541 :         break;
    5675                 :        271 :     case UnaryOp_kind:
    5676         [ -  + ]:        271 :         VISIT(c, expr, e->v.UnaryOp.operand);
    5677         [ +  + ]:        271 :         if (e->v.UnaryOp.op == UAdd) {
    5678         [ -  + ]:          5 :             ADDOP_I(c, loc, CALL_INTRINSIC_1, INTRINSIC_UNARY_POSITIVE);
    5679                 :            :         }
    5680                 :            :         else {
    5681         [ -  + ]:        266 :             ADDOP(c, loc, unaryop(e->v.UnaryOp.op));
    5682                 :            :         }
    5683                 :        271 :         break;
    5684                 :        135 :     case Lambda_kind:
    5685                 :        135 :         return compiler_lambda(c, e);
    5686                 :        231 :     case IfExp_kind:
    5687                 :        231 :         return compiler_ifexp(c, e);
    5688                 :        397 :     case Dict_kind:
    5689                 :        397 :         return compiler_dict(c, e);
    5690                 :         40 :     case Set_kind:
    5691                 :         40 :         return compiler_set(c, e);
    5692                 :        197 :     case GeneratorExp_kind:
    5693                 :        197 :         return compiler_genexp(c, e);
    5694                 :        219 :     case ListComp_kind:
    5695                 :        219 :         return compiler_listcomp(c, e);
    5696                 :         14 :     case SetComp_kind:
    5697                 :         14 :         return compiler_setcomp(c, e);
    5698                 :         23 :     case DictComp_kind:
    5699                 :         23 :         return compiler_dictcomp(c, e);
    5700                 :        252 :     case Yield_kind:
    5701         [ -  + ]:        252 :         if (c->u->u_ste->ste_type != FunctionBlock) {
    5702                 :          0 :             return compiler_error(c, loc, "'yield' outside function");
    5703                 :            :         }
    5704         [ +  + ]:        252 :         if (e->v.Yield.value) {
    5705         [ -  + ]:        220 :             VISIT(c, expr, e->v.Yield.value);
    5706                 :            :         }
    5707                 :            :         else {
    5708         [ -  + ]:         32 :             ADDOP_LOAD_CONST(c, loc, Py_None);
    5709                 :            :         }
    5710         [ -  + ]:        252 :         ADDOP_YIELD(c, loc);
    5711                 :        252 :         break;
    5712                 :         44 :     case YieldFrom_kind:
    5713         [ -  + ]:         44 :         if (c->u->u_ste->ste_type != FunctionBlock) {
    5714                 :          0 :             return compiler_error(c, loc, "'yield' outside function");
    5715                 :            :         }
    5716         [ -  + ]:         44 :         if (c->u->u_scope_type == COMPILER_SCOPE_ASYNC_FUNCTION) {
    5717                 :          0 :             return compiler_error(c, loc, "'yield from' inside async function");
    5718                 :            :         }
    5719         [ -  + ]:         44 :         VISIT(c, expr, e->v.YieldFrom.value);
    5720         [ -  + ]:         44 :         ADDOP(c, loc, GET_YIELD_FROM_ITER);
    5721         [ -  + ]:         44 :         ADDOP_LOAD_CONST(c, loc, Py_None);
    5722         [ -  + ]:         44 :         ADD_YIELD_FROM(c, loc, 0);
    5723                 :         44 :         break;
    5724                 :        133 :     case Await_kind:
    5725   [ -  +  -  - ]:        133 :         if (!IS_TOP_LEVEL_AWAIT(c)){
    5726         [ -  + ]:        133 :             if (c->u->u_ste->ste_type != FunctionBlock){
    5727                 :          0 :                 return compiler_error(c, loc, "'await' outside function");
    5728                 :            :             }
    5729                 :            : 
    5730         [ -  + ]:        133 :             if (c->u->u_scope_type != COMPILER_SCOPE_ASYNC_FUNCTION &&
    5731         [ #  # ]:          0 :                     c->u->u_scope_type != COMPILER_SCOPE_COMPREHENSION) {
    5732                 :          0 :                 return compiler_error(c, loc, "'await' outside async function");
    5733                 :            :             }
    5734                 :            :         }
    5735                 :            : 
    5736         [ -  + ]:        133 :         VISIT(c, expr, e->v.Await.value);
    5737         [ -  + ]:        133 :         ADDOP_I(c, loc, GET_AWAITABLE, 0);
    5738         [ -  + ]:        133 :         ADDOP_LOAD_CONST(c, loc, Py_None);
    5739         [ -  + ]:        133 :         ADD_YIELD_FROM(c, loc, 1);
    5740                 :        133 :         break;
    5741                 :       6321 :     case Compare_kind:
    5742                 :       6321 :         return compiler_compare(c, e);
    5743                 :      26546 :     case Call_kind:
    5744                 :      26546 :         return compiler_call(c, e);
    5745                 :      31226 :     case Constant_kind:
    5746         [ -  + ]:      31226 :         ADDOP_LOAD_CONST(c, loc, e->v.Constant.value);
    5747                 :      31226 :         break;
    5748                 :       1188 :     case JoinedStr_kind:
    5749                 :       1188 :         return compiler_joined_str(c, e);
    5750                 :       1826 :     case FormattedValue_kind:
    5751                 :       1826 :         return compiler_formatted_value(c, e);
    5752                 :            :     /* The following exprs can be assignment targets. */
    5753                 :      18909 :     case Attribute_kind:
    5754         [ -  + ]:      18909 :         VISIT(c, expr, e->v.Attribute.value);
    5755                 :      18909 :         loc = LOC(e);
    5756                 :      18909 :         loc = update_start_location_to_match_attr(c, loc, e);
    5757   [ +  +  +  - ]:      18909 :         switch (e->v.Attribute.ctx) {
    5758                 :      15961 :         case Load:
    5759         [ -  + ]:      15961 :             ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names);
    5760                 :      15961 :             break;
    5761                 :       2928 :         case Store:
    5762         [ -  + ]:       2928 :             if (forbidden_name(c, loc, e->v.Attribute.attr, e->v.Attribute.ctx)) {
    5763                 :          0 :                 return ERROR;
    5764                 :            :             }
    5765         [ -  + ]:       2928 :             ADDOP_NAME(c, loc, STORE_ATTR, e->v.Attribute.attr, names);
    5766                 :       2928 :             break;
    5767                 :         20 :         case Del:
    5768         [ -  + ]:         20 :             ADDOP_NAME(c, loc, DELETE_ATTR, e->v.Attribute.attr, names);
    5769                 :         20 :             break;
    5770                 :            :         }
    5771                 :      18909 :         break;
    5772                 :       3526 :     case Subscript_kind:
    5773                 :       3526 :         return compiler_subscript(c, e);
    5774                 :          0 :     case Starred_kind:
    5775         [ #  # ]:          0 :         switch (e->v.Starred.ctx) {
    5776                 :          0 :         case Store:
    5777                 :            :             /* In all legitimate cases, the Starred node was already replaced
    5778                 :            :              * by compiler_list/compiler_tuple. XXX: is that okay? */
    5779                 :          0 :             return compiler_error(c, loc,
    5780                 :            :                 "starred assignment target must be in a list or tuple");
    5781                 :          0 :         default:
    5782                 :          0 :             return compiler_error(c, loc,
    5783                 :            :                 "can't use starred expression here");
    5784                 :            :         }
    5785                 :            :         break;
    5786                 :         21 :     case Slice_kind:
    5787                 :            :     {
    5788                 :         21 :         int n = compiler_slice(c, e);
    5789         [ -  + ]:         21 :         RETURN_IF_ERROR(n);
    5790         [ -  + ]:         21 :         ADDOP_I(c, loc, BUILD_SLICE, n);
    5791                 :         21 :         break;
    5792                 :            :     }
    5793                 :     101542 :     case Name_kind:
    5794                 :     101542 :         return compiler_nameop(c, loc, e->v.Name.id, e->v.Name.ctx);
    5795                 :            :     /* child nodes of List and Tuple will have expr_context set */
    5796                 :       1029 :     case List_kind:
    5797                 :       1029 :         return compiler_list(c, e);
    5798                 :       2952 :     case Tuple_kind:
    5799                 :       2952 :         return compiler_tuple(c, e);
    5800                 :            :     }
    5801                 :      54429 :     return SUCCESS;
    5802                 :            : }
    5803                 :            : 
    5804                 :            : static int
    5805                 :     201007 : compiler_visit_expr(struct compiler *c, expr_ty e)
    5806                 :            : {
    5807                 :     201007 :     int res = compiler_visit_expr1(c, e);
    5808                 :     201007 :     return res;
    5809                 :            : }
    5810                 :            : 
    5811                 :            : static bool
    5812                 :       3562 : is_two_element_slice(expr_ty s)
    5813                 :            : {
    5814         [ +  + ]:       4376 :     return s->kind == Slice_kind &&
    5815         [ +  + ]:        814 :            s->v.Slice.step == NULL;
    5816                 :            : }
    5817                 :            : 
    5818                 :            : static int
    5819                 :        722 : compiler_augassign(struct compiler *c, stmt_ty s)
    5820                 :            : {
    5821                 :            :     assert(s->kind == AugAssign_kind);
    5822                 :        722 :     expr_ty e = s->v.AugAssign.target;
    5823                 :            : 
    5824                 :        722 :     location loc = LOC(e);
    5825                 :            : 
    5826   [ +  +  +  - ]:        722 :     switch (e->kind) {
    5827                 :        116 :     case Attribute_kind:
    5828         [ -  + ]:        116 :         VISIT(c, expr, e->v.Attribute.value);
    5829         [ -  + ]:        116 :         ADDOP_I(c, loc, COPY, 1);
    5830                 :        116 :         loc = update_start_location_to_match_attr(c, loc, e);
    5831         [ -  + ]:        116 :         ADDOP_NAME(c, loc, LOAD_ATTR, e->v.Attribute.attr, names);
    5832                 :        116 :         break;
    5833                 :         18 :     case Subscript_kind:
    5834         [ -  + ]:         18 :         VISIT(c, expr, e->v.Subscript.value);
    5835         [ -  + ]:         18 :         if (is_two_element_slice(e->v.Subscript.slice)) {
    5836         [ #  # ]:          0 :             RETURN_IF_ERROR(compiler_slice(c, e->v.Subscript.slice));
    5837         [ #  # ]:          0 :             ADDOP_I(c, loc, COPY, 3);
    5838         [ #  # ]:          0 :             ADDOP_I(c, loc, COPY, 3);
    5839         [ #  # ]:          0 :             ADDOP_I(c, loc, COPY, 3);
    5840         [ #  # ]:          0 :             ADDOP(c, loc, BINARY_SLICE);
    5841                 :            :         }
    5842                 :            :         else {
    5843         [ -  + ]:         18 :             VISIT(c, expr, e->v.Subscript.slice);
    5844         [ -  + ]:         18 :             ADDOP_I(c, loc, COPY, 2);
    5845         [ -  + ]:         18 :             ADDOP_I(c, loc, COPY, 2);
    5846         [ -  + ]:         18 :             ADDOP(c, loc, BINARY_SUBSCR);
    5847                 :            :         }
    5848                 :         18 :         break;
    5849                 :        588 :     case Name_kind:
    5850         [ -  + ]:        588 :         RETURN_IF_ERROR(compiler_nameop(c, loc, e->v.Name.id, Load));
    5851                 :        588 :         break;
    5852                 :          0 :     default:
    5853                 :          0 :         PyErr_Format(PyExc_SystemError,
    5854                 :            :             "invalid node type (%d) for augmented assignment",
    5855                 :          0 :             e->kind);
    5856                 :          0 :         return ERROR;
    5857                 :            :     }
    5858                 :            : 
    5859                 :        722 :     loc = LOC(s);
    5860                 :            : 
    5861         [ -  + ]:        722 :     VISIT(c, expr, s->v.AugAssign.value);
    5862         [ -  + ]:        722 :     ADDOP_INPLACE(c, loc, s->v.AugAssign.op);
    5863                 :            : 
    5864                 :        722 :     loc = LOC(e);
    5865                 :            : 
    5866   [ +  +  +  - ]:        722 :     switch (e->kind) {
    5867                 :        116 :     case Attribute_kind:
    5868                 :        116 :         loc = update_start_location_to_match_attr(c, loc, e);
    5869         [ -  + ]:        116 :         ADDOP_I(c, loc, SWAP, 2);
    5870         [ -  + ]:        116 :         ADDOP_NAME(c, loc, STORE_ATTR, e->v.Attribute.attr, names);
    5871                 :        116 :         break;
    5872                 :         18 :     case Subscript_kind:
    5873         [ -  + ]:         18 :         if (is_two_element_slice(e->v.Subscript.slice)) {
    5874         [ #  # ]:          0 :             ADDOP_I(c, loc, SWAP, 4);
    5875         [ #  # ]:          0 :             ADDOP_I(c, loc, SWAP, 3);
    5876         [ #  # ]:          0 :             ADDOP_I(c, loc, SWAP, 2);
    5877         [ #  # ]:          0 :             ADDOP(c, loc, STORE_SLICE);
    5878                 :            :         }
    5879                 :            :         else {
    5880         [ -  + ]:         18 :             ADDOP_I(c, loc, SWAP, 3);
    5881         [ -  + ]:         18 :             ADDOP_I(c, loc, SWAP, 2);
    5882         [ -  + ]:         18 :             ADDOP(c, loc, STORE_SUBSCR);
    5883                 :            :         }
    5884                 :         18 :         break;
    5885                 :        588 :     case Name_kind:
    5886                 :        588 :         return compiler_nameop(c, loc, e->v.Name.id, Store);
    5887                 :          0 :     default:
    5888                 :          0 :         Py_UNREACHABLE();
    5889                 :            :     }
    5890                 :        134 :     return SUCCESS;
    5891                 :            : }
    5892                 :            : 
    5893                 :            : static int
    5894                 :          0 : check_ann_expr(struct compiler *c, expr_ty e)
    5895                 :            : {
    5896         [ #  # ]:          0 :     VISIT(c, expr, e);
    5897         [ #  # ]:          0 :     ADDOP(c, LOC(e), POP_TOP);
    5898                 :          0 :     return SUCCESS;
    5899                 :            : }
    5900                 :            : 
    5901                 :            : static int
    5902                 :         10 : check_annotation(struct compiler *c, stmt_ty s)
    5903                 :            : {
    5904                 :            :     /* Annotations of complex targets does not produce anything
    5905                 :            :        under annotations future */
    5906         [ -  + ]:         10 :     if (c->c_future.ff_features & CO_FUTURE_ANNOTATIONS) {
    5907                 :          0 :         return SUCCESS;
    5908                 :            :     }
    5909                 :            : 
    5910                 :            :     /* Annotations are only evaluated in a module or class. */
    5911         [ +  - ]:         10 :     if (c->u->u_scope_type == COMPILER_SCOPE_MODULE ||
    5912         [ -  + ]:         10 :         c->u->u_scope_type == COMPILER_SCOPE_CLASS) {
    5913                 :          0 :         return check_ann_expr(c, s->v.AnnAssign.annotation);
    5914                 :            :     }
    5915                 :         10 :     return SUCCESS;
    5916                 :            : }
    5917                 :            : 
    5918                 :            : static int
    5919                 :          0 : check_ann_subscr(struct compiler *c, expr_ty e)
    5920                 :            : {
    5921                 :            :     /* We check that everything in a subscript is defined at runtime. */
    5922      [ #  #  # ]:          0 :     switch (e->kind) {
    5923                 :          0 :     case Slice_kind:
    5924   [ #  #  #  # ]:          0 :         if (e->v.Slice.lower && check_ann_expr(c, e->v.Slice.lower) < 0) {
    5925                 :          0 :             return ERROR;
    5926                 :            :         }
    5927   [ #  #  #  # ]:          0 :         if (e->v.Slice.upper && check_ann_expr(c, e->v.Slice.upper) < 0) {
    5928                 :          0 :             return ERROR;
    5929                 :            :         }
    5930   [ #  #  #  # ]:          0 :         if (e->v.Slice.step && check_ann_expr(c, e->v.Slice.step) < 0) {
    5931                 :          0 :             return ERROR;
    5932                 :            :         }
    5933                 :          0 :         return SUCCESS;
    5934                 :          0 :     case Tuple_kind: {
    5935                 :            :         /* extended slice */
    5936                 :          0 :         asdl_expr_seq *elts = e->v.Tuple.elts;
    5937         [ #  # ]:          0 :         Py_ssize_t i, n = asdl_seq_LEN(elts);
    5938         [ #  # ]:          0 :         for (i = 0; i < n; i++) {
    5939         [ #  # ]:          0 :             RETURN_IF_ERROR(check_ann_subscr(c, asdl_seq_GET(elts, i)));
    5940                 :            :         }
    5941                 :          0 :         return SUCCESS;
    5942                 :            :     }
    5943                 :          0 :     default:
    5944                 :          0 :         return check_ann_expr(c, e);
    5945                 :            :     }
    5946                 :            : }
    5947                 :            : 
    5948                 :            : static int
    5949                 :         17 : compiler_annassign(struct compiler *c, stmt_ty s)
    5950                 :            : {
    5951                 :         17 :     location loc = LOC(s);
    5952                 :         17 :     expr_ty targ = s->v.AnnAssign.target;
    5953                 :            :     PyObject* mangled;
    5954                 :            : 
    5955                 :            :     assert(s->kind == AnnAssign_kind);
    5956                 :            : 
    5957                 :            :     /* We perform the actual assignment first. */
    5958         [ +  + ]:         17 :     if (s->v.AnnAssign.value) {
    5959         [ -  + ]:         15 :         VISIT(c, expr, s->v.AnnAssign.value);
    5960         [ -  + ]:         15 :         VISIT(c, expr, targ);
    5961                 :            :     }
    5962   [ +  +  -  - ]:         17 :     switch (targ->kind) {
    5963                 :          7 :     case Name_kind:
    5964         [ -  + ]:          7 :         if (forbidden_name(c, loc, targ->v.Name.id, Store)) {
    5965                 :          0 :             return ERROR;
    5966                 :            :         }
    5967                 :            :         /* If we have a simple name in a module or class, store annotation. */
    5968         [ +  - ]:          7 :         if (s->v.AnnAssign.simple &&
    5969         [ +  - ]:          7 :             (c->u->u_scope_type == COMPILER_SCOPE_MODULE ||
    5970         [ +  + ]:          7 :              c->u->u_scope_type == COMPILER_SCOPE_CLASS)) {
    5971         [ -  + ]:          2 :             if (c->c_future.ff_features & CO_FUTURE_ANNOTATIONS) {
    5972         [ #  # ]:          0 :                 VISIT(c, annexpr, s->v.AnnAssign.annotation)
    5973                 :            :             }
    5974                 :            :             else {
    5975         [ -  + ]:          2 :                 VISIT(c, expr, s->v.AnnAssign.annotation);
    5976                 :            :             }
    5977         [ -  + ]:          2 :             ADDOP_NAME(c, loc, LOAD_NAME, &_Py_ID(__annotations__), names);
    5978                 :          2 :             mangled = _Py_Mangle(c->u->u_private, targ->v.Name.id);
    5979   [ -  +  -  + ]:          2 :             ADDOP_LOAD_CONST_NEW(c, loc, mangled);
    5980         [ -  + ]:          2 :             ADDOP(c, loc, STORE_SUBSCR);
    5981                 :            :         }
    5982                 :          7 :         break;
    5983                 :         10 :     case Attribute_kind:
    5984         [ -  + ]:         10 :         if (forbidden_name(c, loc, targ->v.Attribute.attr, Store)) {
    5985                 :          0 :             return ERROR;
    5986                 :            :         }
    5987   [ -  +  -  - ]:         10 :         if (!s->v.AnnAssign.value &&
    5988                 :          0 :             check_ann_expr(c, targ->v.Attribute.value) < 0) {
    5989                 :          0 :             return ERROR;
    5990                 :            :         }
    5991                 :         10 :         break;
    5992                 :          0 :     case Subscript_kind:
    5993   [ #  #  #  # ]:          0 :         if (!s->v.AnnAssign.value &&
    5994         [ #  # ]:          0 :             (check_ann_expr(c, targ->v.Subscript.value) < 0 ||
    5995                 :          0 :              check_ann_subscr(c, targ->v.Subscript.slice) < 0)) {
    5996                 :          0 :                 return ERROR;
    5997                 :            :         }
    5998                 :          0 :         break;
    5999                 :          0 :     default:
    6000                 :          0 :         PyErr_Format(PyExc_SystemError,
    6001                 :            :                      "invalid node type (%d) for annotated assignment",
    6002                 :          0 :                      targ->kind);
    6003                 :          0 :         return ERROR;
    6004                 :            :     }
    6005                 :            :     /* Annotation is evaluated last. */
    6006   [ +  +  -  + ]:         17 :     if (!s->v.AnnAssign.simple && check_annotation(c, s) < 0) {
    6007                 :          0 :         return ERROR;
    6008                 :            :     }
    6009                 :         17 :     return SUCCESS;
    6010                 :            : }
    6011                 :            : 
    6012                 :            : /* Raises a SyntaxError and returns 0.
    6013                 :            :    If something goes wrong, a different exception may be raised.
    6014                 :            : */
    6015                 :            : 
    6016                 :            : static int
    6017                 :          0 : compiler_error(struct compiler *c, location loc,
    6018                 :            :                const char *format, ...)
    6019                 :            : {
    6020                 :            :     va_list vargs;
    6021                 :          0 :     va_start(vargs, format);
    6022                 :          0 :     PyObject *msg = PyUnicode_FromFormatV(format, vargs);
    6023                 :          0 :     va_end(vargs);
    6024         [ #  # ]:          0 :     if (msg == NULL) {
    6025                 :          0 :         return ERROR;
    6026                 :            :     }
    6027                 :          0 :     PyObject *loc_obj = PyErr_ProgramTextObject(c->c_filename, loc.lineno);
    6028         [ #  # ]:          0 :     if (loc_obj == NULL) {
    6029                 :          0 :         loc_obj = Py_NewRef(Py_None);
    6030                 :            :     }
    6031                 :          0 :     PyObject *args = Py_BuildValue("O(OiiOii)", msg, c->c_filename,
    6032                 :          0 :                                    loc.lineno, loc.col_offset + 1, loc_obj,
    6033                 :          0 :                                    loc.end_lineno, loc.end_col_offset + 1);
    6034                 :          0 :     Py_DECREF(msg);
    6035         [ #  # ]:          0 :     if (args == NULL) {
    6036                 :          0 :         goto exit;
    6037                 :            :     }
    6038                 :          0 :     PyErr_SetObject(PyExc_SyntaxError, args);
    6039                 :          0 :  exit:
    6040                 :          0 :     Py_DECREF(loc_obj);
    6041                 :          0 :     Py_XDECREF(args);
    6042                 :          0 :     return ERROR;
    6043                 :            : }
    6044                 :            : 
    6045                 :            : /* Emits a SyntaxWarning and returns 1 on success.
    6046                 :            :    If a SyntaxWarning raised as error, replaces it with a SyntaxError
    6047                 :            :    and returns 0.
    6048                 :            : */
    6049                 :            : static int
    6050                 :          0 : compiler_warn(struct compiler *c, location loc,
    6051                 :            :               const char *format, ...)
    6052                 :            : {
    6053                 :            :     va_list vargs;
    6054                 :          0 :     va_start(vargs, format);
    6055                 :          0 :     PyObject *msg = PyUnicode_FromFormatV(format, vargs);
    6056                 :          0 :     va_end(vargs);
    6057         [ #  # ]:          0 :     if (msg == NULL) {
    6058                 :          0 :         return ERROR;
    6059                 :            :     }
    6060         [ #  # ]:          0 :     if (PyErr_WarnExplicitObject(PyExc_SyntaxWarning, msg, c->c_filename,
    6061                 :            :                                  loc.lineno, NULL, NULL) < 0)
    6062                 :            :     {
    6063         [ #  # ]:          0 :         if (PyErr_ExceptionMatches(PyExc_SyntaxWarning)) {
    6064                 :            :             /* Replace the SyntaxWarning exception with a SyntaxError
    6065                 :            :                to get a more accurate error report */
    6066                 :          0 :             PyErr_Clear();
    6067                 :            :             assert(PyUnicode_AsUTF8(msg) != NULL);
    6068                 :          0 :             compiler_error(c, loc, PyUnicode_AsUTF8(msg));
    6069                 :            :         }
    6070                 :          0 :         Py_DECREF(msg);
    6071                 :          0 :         return ERROR;
    6072                 :            :     }
    6073                 :          0 :     Py_DECREF(msg);
    6074                 :          0 :     return SUCCESS;
    6075                 :            : }
    6076                 :            : 
    6077                 :            : static int
    6078                 :       3526 : compiler_subscript(struct compiler *c, expr_ty e)
    6079                 :            : {
    6080                 :       3526 :     location loc = LOC(e);
    6081                 :       3526 :     expr_context_ty ctx = e->v.Subscript.ctx;
    6082                 :       3526 :     int op = 0;
    6083                 :            : 
    6084         [ +  + ]:       3526 :     if (ctx == Load) {
    6085         [ -  + ]:       2593 :         RETURN_IF_ERROR(check_subscripter(c, e->v.Subscript.value));
    6086         [ -  + ]:       2593 :         RETURN_IF_ERROR(check_index(c, e->v.Subscript.value, e->v.Subscript.slice));
    6087                 :            :     }
    6088                 :            : 
    6089         [ -  + ]:       3526 :     VISIT(c, expr, e->v.Subscript.value);
    6090   [ +  +  +  + ]:       3526 :     if (is_two_element_slice(e->v.Subscript.slice) && ctx != Del) {
    6091         [ -  + ]:        793 :         RETURN_IF_ERROR(compiler_slice(c, e->v.Subscript.slice));
    6092         [ +  + ]:        793 :         if (ctx == Load) {
    6093         [ -  + ]:        751 :             ADDOP(c, loc, BINARY_SLICE);
    6094                 :            :         }
    6095                 :            :         else {
    6096                 :            :             assert(ctx == Store);
    6097         [ -  + ]:         42 :             ADDOP(c, loc, STORE_SLICE);
    6098                 :            :         }
    6099                 :            :     }
    6100                 :            :     else {
    6101         [ -  + ]:       2733 :         VISIT(c, expr, e->v.Subscript.slice);
    6102   [ +  +  +  - ]:       2733 :         switch (ctx) {
    6103                 :       1842 :             case Load:    op = BINARY_SUBSCR; break;
    6104                 :        770 :             case Store:   op = STORE_SUBSCR; break;
    6105                 :        121 :             case Del:     op = DELETE_SUBSCR; break;
    6106                 :            :         }
    6107                 :       2733 :         assert(op);
    6108         [ -  + ]:       2733 :         ADDOP(c, loc, op);
    6109                 :            :     }
    6110                 :       3526 :     return SUCCESS;
    6111                 :            : }
    6112                 :            : 
    6113                 :            : /* Returns the number of the values emitted,
    6114                 :            :  * thus are needed to build the slice, or -1 if there is an error. */
    6115                 :            : static int
    6116                 :        814 : compiler_slice(struct compiler *c, expr_ty s)
    6117                 :            : {
    6118                 :        814 :     int n = 2;
    6119                 :            :     assert(s->kind == Slice_kind);
    6120                 :            : 
    6121                 :            :     /* only handles the cases where BUILD_SLICE is emitted */
    6122         [ +  + ]:        814 :     if (s->v.Slice.lower) {
    6123         [ -  + ]:        450 :         VISIT(c, expr, s->v.Slice.lower);
    6124                 :            :     }
    6125                 :            :     else {
    6126         [ -  + ]:        364 :         ADDOP_LOAD_CONST(c, LOC(s), Py_None);
    6127                 :            :     }
    6128                 :            : 
    6129         [ +  + ]:        814 :     if (s->v.Slice.upper) {
    6130         [ -  + ]:        483 :         VISIT(c, expr, s->v.Slice.upper);
    6131                 :            :     }
    6132                 :            :     else {
    6133         [ -  + ]:        331 :         ADDOP_LOAD_CONST(c, LOC(s), Py_None);
    6134                 :            :     }
    6135                 :            : 
    6136         [ +  + ]:        814 :     if (s->v.Slice.step) {
    6137                 :          9 :         n++;
    6138         [ -  + ]:          9 :         VISIT(c, expr, s->v.Slice.step);
    6139                 :            :     }
    6140                 :        814 :     return n;
    6141                 :            : }
    6142                 :            : 
    6143                 :            : 
    6144                 :            : // PEP 634: Structural Pattern Matching
    6145                 :            : 
    6146                 :            : // To keep things simple, all compiler_pattern_* and pattern_helper_* routines
    6147                 :            : // follow the convention of consuming TOS (the subject for the given pattern)
    6148                 :            : // and calling jump_to_fail_pop on failure (no match).
    6149                 :            : 
    6150                 :            : // When calling into these routines, it's important that pc->on_top be kept
    6151                 :            : // updated to reflect the current number of items that we are using on the top
    6152                 :            : // of the stack: they will be popped on failure, and any name captures will be
    6153                 :            : // stored *underneath* them on success. This lets us defer all names stores
    6154                 :            : // until the *entire* pattern matches.
    6155                 :            : 
    6156                 :            : #define WILDCARD_CHECK(N) \
    6157                 :            :     ((N)->kind == MatchAs_kind && !(N)->v.MatchAs.name)
    6158                 :            : 
    6159                 :            : #define WILDCARD_STAR_CHECK(N) \
    6160                 :            :     ((N)->kind == MatchStar_kind && !(N)->v.MatchStar.name)
    6161                 :            : 
    6162                 :            : // Limit permitted subexpressions, even if the parser & AST validator let them through
    6163                 :            : #define MATCH_VALUE_EXPR(N) \
    6164                 :            :     ((N)->kind == Constant_kind || (N)->kind == Attribute_kind)
    6165                 :            : 
    6166                 :            : // Allocate or resize pc->fail_pop to allow for n items to be popped on failure.
    6167                 :            : static int
    6168                 :         19 : ensure_fail_pop(struct compiler *c, pattern_context *pc, Py_ssize_t n)
    6169                 :            : {
    6170                 :         19 :     Py_ssize_t size = n + 1;
    6171         [ +  + ]:         19 :     if (size <= pc->fail_pop_size) {
    6172                 :          8 :         return SUCCESS;
    6173                 :            :     }
    6174                 :         11 :     Py_ssize_t needed = sizeof(jump_target_label) * size;
    6175                 :         11 :     jump_target_label *resized = PyObject_Realloc(pc->fail_pop, needed);
    6176         [ -  + ]:         11 :     if (resized == NULL) {
    6177                 :          0 :         PyErr_NoMemory();
    6178                 :          0 :         return ERROR;
    6179                 :            :     }
    6180                 :         11 :     pc->fail_pop = resized;
    6181         [ +  + ]:         31 :     while (pc->fail_pop_size < size) {
    6182         [ -  + ]:         20 :         NEW_JUMP_TARGET_LABEL(c, new_block);
    6183                 :         20 :         pc->fail_pop[pc->fail_pop_size++] = new_block;
    6184                 :            :     }
    6185                 :         11 :     return SUCCESS;
    6186                 :            : }
    6187                 :            : 
    6188                 :            : // Use op to jump to the correct fail_pop block.
    6189                 :            : static int
    6190                 :         18 : jump_to_fail_pop(struct compiler *c, location loc,
    6191                 :            :                  pattern_context *pc, int op)
    6192                 :            : {
    6193                 :            :     // Pop any items on the top of the stack, plus any objects we were going to
    6194                 :            :     // capture on success:
    6195                 :         18 :     Py_ssize_t pops = pc->on_top + PyList_GET_SIZE(pc->stores);
    6196         [ -  + ]:         18 :     RETURN_IF_ERROR(ensure_fail_pop(c, pc, pops));
    6197         [ -  + ]:         18 :     ADDOP_JUMP(c, loc, op, pc->fail_pop[pops]);
    6198                 :         18 :     return SUCCESS;
    6199                 :            : }
    6200                 :            : 
    6201                 :            : // Build all of the fail_pop blocks and reset fail_pop.
    6202                 :            : static int
    6203                 :         11 : emit_and_reset_fail_pop(struct compiler *c, location loc,
    6204                 :            :                         pattern_context *pc)
    6205                 :            : {
    6206         [ -  + ]:         11 :     if (!pc->fail_pop_size) {
    6207                 :            :         assert(pc->fail_pop == NULL);
    6208                 :          0 :         return SUCCESS;
    6209                 :            :     }
    6210         [ +  + ]:         20 :     while (--pc->fail_pop_size) {
    6211         [ -  + ]:          9 :         USE_LABEL(c, pc->fail_pop[pc->fail_pop_size]);
    6212         [ -  + ]:          9 :         if (codegen_addop_noarg(INSTR_SEQUENCE(c), POP_TOP, loc) < 0) {
    6213                 :          0 :             pc->fail_pop_size = 0;
    6214                 :          0 :             PyObject_Free(pc->fail_pop);
    6215                 :          0 :             pc->fail_pop = NULL;
    6216                 :          0 :             return ERROR;
    6217                 :            :         }
    6218                 :            :     }
    6219         [ -  + ]:         11 :     USE_LABEL(c, pc->fail_pop[0]);
    6220                 :         11 :     PyObject_Free(pc->fail_pop);
    6221                 :         11 :     pc->fail_pop = NULL;
    6222                 :         11 :     return SUCCESS;
    6223                 :            : }
    6224                 :            : 
    6225                 :            : static int
    6226                 :          0 : compiler_error_duplicate_store(struct compiler *c, location loc, identifier n)
    6227                 :            : {
    6228                 :          0 :     return compiler_error(c, loc,
    6229                 :            :         "multiple assignments to name %R in pattern", n);
    6230                 :            : }
    6231                 :            : 
    6232                 :            : // Duplicate the effect of 3.10's ROT_* instructions using SWAPs.
    6233                 :            : static int
    6234                 :          4 : pattern_helper_rotate(struct compiler *c, location loc, Py_ssize_t count)
    6235                 :            : {
    6236         [ -  + ]:          4 :     while (1 < count) {
    6237         [ #  # ]:          0 :         ADDOP_I(c, loc, SWAP, count--);
    6238                 :            :     }
    6239                 :          4 :     return SUCCESS;
    6240                 :            : }
    6241                 :            : 
    6242                 :            : static int
    6243                 :          4 : pattern_helper_store_name(struct compiler *c, location loc,
    6244                 :            :                           identifier n, pattern_context *pc)
    6245                 :            : {
    6246         [ -  + ]:          4 :     if (n == NULL) {
    6247         [ #  # ]:          0 :         ADDOP(c, loc, POP_TOP);
    6248                 :          0 :         return SUCCESS;
    6249                 :            :     }
    6250         [ -  + ]:          4 :     if (forbidden_name(c, loc, n, Store)) {
    6251                 :          0 :         return ERROR;
    6252                 :            :     }
    6253                 :            :     // Can't assign to the same name twice:
    6254                 :          4 :     int duplicate = PySequence_Contains(pc->stores, n);
    6255         [ -  + ]:          4 :     RETURN_IF_ERROR(duplicate);
    6256         [ -  + ]:          4 :     if (duplicate) {
    6257                 :          0 :         return compiler_error_duplicate_store(c, loc, n);
    6258                 :            :     }
    6259                 :            :     // Rotate this object underneath any items we need to preserve:
    6260                 :          4 :     Py_ssize_t rotations = pc->on_top + PyList_GET_SIZE(pc->stores) + 1;
    6261         [ -  + ]:          4 :     RETURN_IF_ERROR(pattern_helper_rotate(c, loc, rotations));
    6262         [ -  + ]:          4 :     RETURN_IF_ERROR(PyList_Append(pc->stores, n));
    6263                 :          4 :     return SUCCESS;
    6264                 :            : }
    6265                 :            : 
    6266                 :            : 
    6267                 :            : static int
    6268                 :          5 : pattern_unpack_helper(struct compiler *c, location loc,
    6269                 :            :                       asdl_pattern_seq *elts)
    6270                 :            : {
    6271         [ +  - ]:          5 :     Py_ssize_t n = asdl_seq_LEN(elts);
    6272                 :          5 :     int seen_star = 0;
    6273         [ +  + ]:         10 :     for (Py_ssize_t i = 0; i < n; i++) {
    6274                 :          5 :         pattern_ty elt = asdl_seq_GET(elts, i);
    6275   [ +  +  +  - ]:          5 :         if (elt->kind == MatchStar_kind && !seen_star) {
    6276         [ +  - ]:          1 :             if ((i >= (1 << 8)) ||
    6277         [ -  + ]:          1 :                 (n-i-1 >= (INT_MAX >> 8))) {
    6278                 :          0 :                 return compiler_error(c, loc,
    6279                 :            :                     "too many expressions in "
    6280                 :            :                     "star-unpacking sequence pattern");
    6281                 :            :             }
    6282         [ -  + ]:          1 :             ADDOP_I(c, loc, UNPACK_EX, (i + ((n-i-1) << 8)));
    6283                 :          1 :             seen_star = 1;
    6284                 :            :         }
    6285         [ -  + ]:          4 :         else if (elt->kind == MatchStar_kind) {
    6286                 :          0 :             return compiler_error(c, loc,
    6287                 :            :                 "multiple starred expressions in sequence pattern");
    6288                 :            :         }
    6289                 :            :     }
    6290         [ +  + ]:          5 :     if (!seen_star) {
    6291         [ -  + ]:          4 :         ADDOP_I(c, loc, UNPACK_SEQUENCE, n);
    6292                 :            :     }
    6293                 :          5 :     return SUCCESS;
    6294                 :            : }
    6295                 :            : 
    6296                 :            : static int
    6297                 :          5 : pattern_helper_sequence_unpack(struct compiler *c, location loc,
    6298                 :            :                                asdl_pattern_seq *patterns, Py_ssize_t star,
    6299                 :            :                                pattern_context *pc)
    6300                 :            : {
    6301         [ -  + ]:          5 :     RETURN_IF_ERROR(pattern_unpack_helper(c, loc, patterns));
    6302         [ +  - ]:          5 :     Py_ssize_t size = asdl_seq_LEN(patterns);
    6303                 :            :     // We've now got a bunch of new subjects on the stack. They need to remain
    6304                 :            :     // there after each subpattern match:
    6305                 :          5 :     pc->on_top += size;
    6306         [ +  + ]:         10 :     for (Py_ssize_t i = 0; i < size; i++) {
    6307                 :            :         // One less item to keep track of each time we loop through:
    6308                 :          5 :         pc->on_top--;
    6309                 :          5 :         pattern_ty pattern = asdl_seq_GET(patterns, i);
    6310         [ -  + ]:          5 :         RETURN_IF_ERROR(compiler_pattern_subpattern(c, pattern, pc));
    6311                 :            :     }
    6312                 :          5 :     return SUCCESS;
    6313                 :            : }
    6314                 :            : 
    6315                 :            : // Like pattern_helper_sequence_unpack, but uses BINARY_SUBSCR instead of
    6316                 :            : // UNPACK_SEQUENCE / UNPACK_EX. This is more efficient for patterns with a
    6317                 :            : // starred wildcard like [first, *_] / [first, *_, last] / [*_, last] / etc.
    6318                 :            : static int
    6319                 :          0 : pattern_helper_sequence_subscr(struct compiler *c, location loc,
    6320                 :            :                                asdl_pattern_seq *patterns, Py_ssize_t star,
    6321                 :            :                                pattern_context *pc)
    6322                 :            : {
    6323                 :            :     // We need to keep the subject around for extracting elements:
    6324                 :          0 :     pc->on_top++;
    6325         [ #  # ]:          0 :     Py_ssize_t size = asdl_seq_LEN(patterns);
    6326         [ #  # ]:          0 :     for (Py_ssize_t i = 0; i < size; i++) {
    6327                 :          0 :         pattern_ty pattern = asdl_seq_GET(patterns, i);
    6328   [ #  #  #  # ]:          0 :         if (WILDCARD_CHECK(pattern)) {
    6329                 :          0 :             continue;
    6330                 :            :         }
    6331         [ #  # ]:          0 :         if (i == star) {
    6332                 :            :             assert(WILDCARD_STAR_CHECK(pattern));
    6333                 :          0 :             continue;
    6334                 :            :         }
    6335         [ #  # ]:          0 :         ADDOP_I(c, loc, COPY, 1);
    6336         [ #  # ]:          0 :         if (i < star) {
    6337   [ #  #  #  # ]:          0 :             ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromSsize_t(i));
    6338                 :            :         }
    6339                 :            :         else {
    6340                 :            :             // The subject may not support negative indexing! Compute a
    6341                 :            :             // nonnegative index:
    6342         [ #  # ]:          0 :             ADDOP(c, loc, GET_LEN);
    6343   [ #  #  #  # ]:          0 :             ADDOP_LOAD_CONST_NEW(c, loc, PyLong_FromSsize_t(size - i));
    6344         [ #  # ]:          0 :             ADDOP_BINARY(c, loc, Sub);
    6345                 :            :         }
    6346         [ #  # ]:          0 :         ADDOP(c, loc, BINARY_SUBSCR);
    6347         [ #  # ]:          0 :         RETURN_IF_ERROR(compiler_pattern_subpattern(c, pattern, pc));
    6348                 :            :     }
    6349                 :            :     // Pop the subject, we're done with it:
    6350                 :          0 :     pc->on_top--;
    6351         [ #  # ]:          0 :     ADDOP(c, loc, POP_TOP);
    6352                 :          0 :     return SUCCESS;
    6353                 :            : }
    6354                 :            : 
    6355                 :            : // Like compiler_pattern, but turn off checks for irrefutability.
    6356                 :            : static int
    6357                 :          7 : compiler_pattern_subpattern(struct compiler *c,
    6358                 :            :                             pattern_ty p, pattern_context *pc)
    6359                 :            : {
    6360                 :          7 :     int allow_irrefutable = pc->allow_irrefutable;
    6361                 :          7 :     pc->allow_irrefutable = 1;
    6362         [ -  + ]:          7 :     RETURN_IF_ERROR(compiler_pattern(c, p, pc));
    6363                 :          7 :     pc->allow_irrefutable = allow_irrefutable;
    6364                 :          7 :     return SUCCESS;
    6365                 :            : }
    6366                 :            : 
    6367                 :            : static int
    6368                 :          3 : compiler_pattern_as(struct compiler *c, pattern_ty p, pattern_context *pc)
    6369                 :            : {
    6370                 :            :     assert(p->kind == MatchAs_kind);
    6371         [ +  - ]:          3 :     if (p->v.MatchAs.pattern == NULL) {
    6372                 :            :         // An irrefutable match:
    6373         [ -  + ]:          3 :         if (!pc->allow_irrefutable) {
    6374         [ #  # ]:          0 :             if (p->v.MatchAs.name) {
    6375                 :          0 :                 const char *e = "name capture %R makes remaining patterns unreachable";
    6376                 :          0 :                 return compiler_error(c, LOC(p), e, p->v.MatchAs.name);
    6377                 :            :             }
    6378                 :          0 :             const char *e = "wildcard makes remaining patterns unreachable";
    6379                 :          0 :             return compiler_error(c, LOC(p), e);
    6380                 :            :         }
    6381                 :          3 :         return pattern_helper_store_name(c, LOC(p), p->v.MatchAs.name, pc);
    6382                 :            :     }
    6383                 :            :     // Need to make a copy for (possibly) storing later:
    6384                 :          0 :     pc->on_top++;
    6385         [ #  # ]:          0 :     ADDOP_I(c, LOC(p), COPY, 1);
    6386         [ #  # ]:          0 :     RETURN_IF_ERROR(compiler_pattern(c, p->v.MatchAs.pattern, pc));
    6387                 :            :     // Success! Store it:
    6388                 :          0 :     pc->on_top--;
    6389         [ #  # ]:          0 :     RETURN_IF_ERROR(pattern_helper_store_name(c, LOC(p), p->v.MatchAs.name, pc));
    6390                 :          0 :     return SUCCESS;
    6391                 :            : }
    6392                 :            : 
    6393                 :            : static int
    6394                 :          1 : compiler_pattern_star(struct compiler *c, pattern_ty p, pattern_context *pc)
    6395                 :            : {
    6396                 :            :     assert(p->kind == MatchStar_kind);
    6397         [ -  + ]:          1 :     RETURN_IF_ERROR(
    6398                 :            :         pattern_helper_store_name(c, LOC(p), p->v.MatchStar.name, pc));
    6399                 :          1 :     return SUCCESS;
    6400                 :            : }
    6401                 :            : 
    6402                 :            : static int
    6403                 :          0 : validate_kwd_attrs(struct compiler *c, asdl_identifier_seq *attrs, asdl_pattern_seq* patterns)
    6404                 :            : {
    6405                 :            :     // Any errors will point to the pattern rather than the arg name as the
    6406                 :            :     // parser is only supplying identifiers rather than Name or keyword nodes
    6407         [ #  # ]:          0 :     Py_ssize_t nattrs = asdl_seq_LEN(attrs);
    6408         [ #  # ]:          0 :     for (Py_ssize_t i = 0; i < nattrs; i++) {
    6409                 :          0 :         identifier attr = ((identifier)asdl_seq_GET(attrs, i));
    6410                 :          0 :         location loc = LOC((pattern_ty) asdl_seq_GET(patterns, i));
    6411         [ #  # ]:          0 :         if (forbidden_name(c, loc, attr, Store)) {
    6412                 :          0 :             return ERROR;
    6413                 :            :         }
    6414         [ #  # ]:          0 :         for (Py_ssize_t j = i + 1; j < nattrs; j++) {
    6415                 :          0 :             identifier other = ((identifier)asdl_seq_GET(attrs, j));
    6416         [ #  # ]:          0 :             if (!PyUnicode_Compare(attr, other)) {
    6417                 :          0 :                 location loc = LOC((pattern_ty) asdl_seq_GET(patterns, j));
    6418                 :          0 :                 compiler_error(c, loc, "attribute name repeated in class pattern: %U", attr);
    6419                 :          0 :                 return ERROR;
    6420                 :            :             }
    6421                 :            :         }
    6422                 :            :     }
    6423                 :          0 :     return SUCCESS;
    6424                 :            : }
    6425                 :            : 
    6426                 :            : static int
    6427                 :          4 : compiler_pattern_class(struct compiler *c, pattern_ty p, pattern_context *pc)
    6428                 :            : {
    6429                 :            :     assert(p->kind == MatchClass_kind);
    6430                 :          4 :     asdl_pattern_seq *patterns = p->v.MatchClass.patterns;
    6431                 :          4 :     asdl_identifier_seq *kwd_attrs = p->v.MatchClass.kwd_attrs;
    6432                 :          4 :     asdl_pattern_seq *kwd_patterns = p->v.MatchClass.kwd_patterns;
    6433         [ +  + ]:          4 :     Py_ssize_t nargs = asdl_seq_LEN(patterns);
    6434         [ -  + ]:          4 :     Py_ssize_t nattrs = asdl_seq_LEN(kwd_attrs);
    6435         [ -  + ]:          4 :     Py_ssize_t nkwd_patterns = asdl_seq_LEN(kwd_patterns);
    6436         [ -  + ]:          4 :     if (nattrs != nkwd_patterns) {
    6437                 :            :         // AST validator shouldn't let this happen, but if it does,
    6438                 :            :         // just fail, don't crash out of the interpreter
    6439                 :          0 :         const char * e = "kwd_attrs (%d) / kwd_patterns (%d) length mismatch in class pattern";
    6440                 :          0 :         return compiler_error(c, LOC(p), e, nattrs, nkwd_patterns);
    6441                 :            :     }
    6442   [ +  -  -  + ]:          4 :     if (INT_MAX < nargs || INT_MAX < nargs + nattrs - 1) {
    6443                 :          0 :         const char *e = "too many sub-patterns in class pattern %R";
    6444                 :          0 :         return compiler_error(c, LOC(p), e, p->v.MatchClass.cls);
    6445                 :            :     }
    6446         [ -  + ]:          4 :     if (nattrs) {
    6447         [ #  # ]:          0 :         RETURN_IF_ERROR(validate_kwd_attrs(c, kwd_attrs, kwd_patterns));
    6448                 :            :     }
    6449         [ -  + ]:          4 :     VISIT(c, expr, p->v.MatchClass.cls);
    6450                 :          4 :     PyObject *attr_names = PyTuple_New(nattrs);
    6451         [ -  + ]:          4 :     if (attr_names == NULL) {
    6452                 :          0 :         return ERROR;
    6453                 :            :     }
    6454                 :            :     Py_ssize_t i;
    6455         [ -  + ]:          4 :     for (i = 0; i < nattrs; i++) {
    6456                 :          0 :         PyObject *name = asdl_seq_GET(kwd_attrs, i);
    6457                 :          0 :         PyTuple_SET_ITEM(attr_names, i, Py_NewRef(name));
    6458                 :            :     }
    6459   [ -  +  -  + ]:          4 :     ADDOP_LOAD_CONST_NEW(c, LOC(p), attr_names);
    6460         [ -  + ]:          4 :     ADDOP_I(c, LOC(p), MATCH_CLASS, nargs);
    6461         [ -  + ]:          4 :     ADDOP_I(c, LOC(p), COPY, 1);
    6462         [ -  + ]:          4 :     ADDOP_LOAD_CONST(c, LOC(p), Py_None);
    6463         [ -  + ]:          4 :     ADDOP_I(c, LOC(p), IS_OP, 1);
    6464                 :            :     // TOS is now a tuple of (nargs + nattrs) attributes (or None):
    6465                 :          4 :     pc->on_top++;
    6466         [ -  + ]:          4 :     RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
    6467         [ -  + ]:          4 :     ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, nargs + nattrs);
    6468                 :          4 :     pc->on_top += nargs + nattrs - 1;
    6469         [ +  + ]:          6 :     for (i = 0; i < nargs + nattrs; i++) {
    6470                 :          2 :         pc->on_top--;
    6471                 :            :         pattern_ty pattern;
    6472         [ +  - ]:          2 :         if (i < nargs) {
    6473                 :            :             // Positional:
    6474                 :          2 :             pattern = asdl_seq_GET(patterns, i);
    6475                 :            :         }
    6476                 :            :         else {
    6477                 :            :             // Keyword:
    6478                 :          0 :             pattern = asdl_seq_GET(kwd_patterns, i - nargs);
    6479                 :            :         }
    6480   [ +  -  -  + ]:          2 :         if (WILDCARD_CHECK(pattern)) {
    6481         [ #  # ]:          0 :             ADDOP(c, LOC(p), POP_TOP);
    6482                 :          0 :             continue;
    6483                 :            :         }
    6484         [ -  + ]:          2 :         RETURN_IF_ERROR(compiler_pattern_subpattern(c, pattern, pc));
    6485                 :            :     }
    6486                 :            :     // Success! Pop the tuple of attributes:
    6487                 :          4 :     return SUCCESS;
    6488                 :            : }
    6489                 :            : 
    6490                 :            : static int
    6491                 :          0 : compiler_pattern_mapping(struct compiler *c, pattern_ty p,
    6492                 :            :                          pattern_context *pc)
    6493                 :            : {
    6494                 :            :     assert(p->kind == MatchMapping_kind);
    6495                 :          0 :     asdl_expr_seq *keys = p->v.MatchMapping.keys;
    6496                 :          0 :     asdl_pattern_seq *patterns = p->v.MatchMapping.patterns;
    6497         [ #  # ]:          0 :     Py_ssize_t size = asdl_seq_LEN(keys);
    6498         [ #  # ]:          0 :     Py_ssize_t npatterns = asdl_seq_LEN(patterns);
    6499         [ #  # ]:          0 :     if (size != npatterns) {
    6500                 :            :         // AST validator shouldn't let this happen, but if it does,
    6501                 :            :         // just fail, don't crash out of the interpreter
    6502                 :          0 :         const char * e = "keys (%d) / patterns (%d) length mismatch in mapping pattern";
    6503                 :          0 :         return compiler_error(c, LOC(p), e, size, npatterns);
    6504                 :            :     }
    6505                 :            :     // We have a double-star target if "rest" is set
    6506                 :          0 :     PyObject *star_target = p->v.MatchMapping.rest;
    6507                 :            :     // We need to keep the subject on top during the mapping and length checks:
    6508                 :          0 :     pc->on_top++;
    6509         [ #  # ]:          0 :     ADDOP(c, LOC(p), MATCH_MAPPING);
    6510         [ #  # ]:          0 :     RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
    6511   [ #  #  #  # ]:          0 :     if (!size && !star_target) {
    6512                 :            :         // If the pattern is just "{}", we're done! Pop the subject:
    6513                 :          0 :         pc->on_top--;
    6514         [ #  # ]:          0 :         ADDOP(c, LOC(p), POP_TOP);
    6515                 :          0 :         return SUCCESS;
    6516                 :            :     }
    6517         [ #  # ]:          0 :     if (size) {
    6518                 :            :         // If the pattern has any keys in it, perform a length check:
    6519         [ #  # ]:          0 :         ADDOP(c, LOC(p), GET_LEN);
    6520   [ #  #  #  # ]:          0 :         ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size));
    6521         [ #  # ]:          0 :         ADDOP_COMPARE(c, LOC(p), GtE);
    6522         [ #  # ]:          0 :         RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
    6523                 :            :     }
    6524         [ #  # ]:          0 :     if (INT_MAX < size - 1) {
    6525                 :          0 :         return compiler_error(c, LOC(p), "too many sub-patterns in mapping pattern");
    6526                 :            :     }
    6527                 :            :     // Collect all of the keys into a tuple for MATCH_KEYS and
    6528                 :            :     // **rest. They can either be dotted names or literals:
    6529                 :            : 
    6530                 :            :     // Maintaining a set of Constant_kind kind keys allows us to raise a
    6531                 :            :     // SyntaxError in the case of duplicates.
    6532                 :          0 :     PyObject *seen = PySet_New(NULL);
    6533         [ #  # ]:          0 :     if (seen == NULL) {
    6534                 :          0 :         return ERROR;
    6535                 :            :     }
    6536                 :            : 
    6537                 :            :     // NOTE: goto error on failure in the loop below to avoid leaking `seen`
    6538         [ #  # ]:          0 :     for (Py_ssize_t i = 0; i < size; i++) {
    6539                 :          0 :         expr_ty key = asdl_seq_GET(keys, i);
    6540         [ #  # ]:          0 :         if (key == NULL) {
    6541                 :          0 :             const char *e = "can't use NULL keys in MatchMapping "
    6542                 :            :                             "(set 'rest' parameter instead)";
    6543                 :          0 :             location loc = LOC((pattern_ty) asdl_seq_GET(patterns, i));
    6544                 :          0 :             compiler_error(c, loc, e);
    6545                 :          0 :             goto error;
    6546                 :            :         }
    6547                 :            : 
    6548         [ #  # ]:          0 :         if (key->kind == Constant_kind) {
    6549                 :          0 :             int in_seen = PySet_Contains(seen, key->v.Constant.value);
    6550         [ #  # ]:          0 :             if (in_seen < 0) {
    6551                 :          0 :                 goto error;
    6552                 :            :             }
    6553         [ #  # ]:          0 :             if (in_seen) {
    6554                 :          0 :                 const char *e = "mapping pattern checks duplicate key (%R)";
    6555                 :          0 :                 compiler_error(c, LOC(p), e, key->v.Constant.value);
    6556                 :          0 :                 goto error;
    6557                 :            :             }
    6558         [ #  # ]:          0 :             if (PySet_Add(seen, key->v.Constant.value)) {
    6559                 :          0 :                 goto error;
    6560                 :            :             }
    6561                 :            :         }
    6562                 :            : 
    6563         [ #  # ]:          0 :         else if (key->kind != Attribute_kind) {
    6564                 :          0 :             const char *e = "mapping pattern keys may only match literals and attribute lookups";
    6565                 :          0 :             compiler_error(c, LOC(p), e);
    6566                 :          0 :             goto error;
    6567                 :            :         }
    6568         [ #  # ]:          0 :         if (compiler_visit_expr(c, key) < 0) {
    6569                 :          0 :             goto error;
    6570                 :            :         }
    6571                 :            :     }
    6572                 :            : 
    6573                 :            :     // all keys have been checked; there are no duplicates
    6574                 :          0 :     Py_DECREF(seen);
    6575                 :            : 
    6576         [ #  # ]:          0 :     ADDOP_I(c, LOC(p), BUILD_TUPLE, size);
    6577         [ #  # ]:          0 :     ADDOP(c, LOC(p), MATCH_KEYS);
    6578                 :            :     // There's now a tuple of keys and a tuple of values on top of the subject:
    6579                 :          0 :     pc->on_top += 2;
    6580         [ #  # ]:          0 :     ADDOP_I(c, LOC(p), COPY, 1);
    6581         [ #  # ]:          0 :     ADDOP_LOAD_CONST(c, LOC(p), Py_None);
    6582         [ #  # ]:          0 :     ADDOP_I(c, LOC(p), IS_OP, 1);
    6583         [ #  # ]:          0 :     RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
    6584                 :            :     // So far so good. Use that tuple of values on the stack to match
    6585                 :            :     // sub-patterns against:
    6586         [ #  # ]:          0 :     ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, size);
    6587                 :          0 :     pc->on_top += size - 1;
    6588         [ #  # ]:          0 :     for (Py_ssize_t i = 0; i < size; i++) {
    6589                 :          0 :         pc->on_top--;
    6590                 :          0 :         pattern_ty pattern = asdl_seq_GET(patterns, i);
    6591         [ #  # ]:          0 :         RETURN_IF_ERROR(compiler_pattern_subpattern(c, pattern, pc));
    6592                 :            :     }
    6593                 :            :     // If we get this far, it's a match! Whatever happens next should consume
    6594                 :            :     // the tuple of keys and the subject:
    6595                 :          0 :     pc->on_top -= 2;
    6596         [ #  # ]:          0 :     if (star_target) {
    6597                 :            :         // If we have a starred name, bind a dict of remaining items to it (this may
    6598                 :            :         // seem a bit inefficient, but keys is rarely big enough to actually impact
    6599                 :            :         // runtime):
    6600                 :            :         // rest = dict(TOS1)
    6601                 :            :         // for key in TOS:
    6602                 :            :         //     del rest[key]
    6603         [ #  # ]:          0 :         ADDOP_I(c, LOC(p), BUILD_MAP, 0);           // [subject, keys, empty]
    6604         [ #  # ]:          0 :         ADDOP_I(c, LOC(p), SWAP, 3);                // [empty, keys, subject]
    6605         [ #  # ]:          0 :         ADDOP_I(c, LOC(p), DICT_UPDATE, 2);         // [copy, keys]
    6606         [ #  # ]:          0 :         ADDOP_I(c, LOC(p), UNPACK_SEQUENCE, size);  // [copy, keys...]
    6607         [ #  # ]:          0 :         while (size) {
    6608         [ #  # ]:          0 :             ADDOP_I(c, LOC(p), COPY, 1 + size--);   // [copy, keys..., copy]
    6609         [ #  # ]:          0 :             ADDOP_I(c, LOC(p), SWAP, 2);            // [copy, keys..., copy, key]
    6610         [ #  # ]:          0 :             ADDOP(c, LOC(p), DELETE_SUBSCR);        // [copy, keys...]
    6611                 :            :         }
    6612         [ #  # ]:          0 :         RETURN_IF_ERROR(pattern_helper_store_name(c, LOC(p), star_target, pc));
    6613                 :            :     }
    6614                 :            :     else {
    6615         [ #  # ]:          0 :         ADDOP(c, LOC(p), POP_TOP);  // Tuple of keys.
    6616         [ #  # ]:          0 :         ADDOP(c, LOC(p), POP_TOP);  // Subject.
    6617                 :            :     }
    6618                 :          0 :     return SUCCESS;
    6619                 :            : 
    6620                 :          0 : error:
    6621                 :          0 :     Py_DECREF(seen);
    6622                 :          0 :     return ERROR;
    6623                 :            : }
    6624                 :            : 
    6625                 :            : static int
    6626                 :          0 : compiler_pattern_or(struct compiler *c, pattern_ty p, pattern_context *pc)
    6627                 :            : {
    6628                 :            :     assert(p->kind == MatchOr_kind);
    6629         [ #  # ]:          0 :     NEW_JUMP_TARGET_LABEL(c, end);
    6630         [ #  # ]:          0 :     Py_ssize_t size = asdl_seq_LEN(p->v.MatchOr.patterns);
    6631                 :            :     assert(size > 1);
    6632                 :            :     // We're going to be messing with pc. Keep the original info handy:
    6633                 :          0 :     pattern_context old_pc = *pc;
    6634                 :          0 :     Py_INCREF(pc->stores);
    6635                 :            :     // control is the list of names bound by the first alternative. It is used
    6636                 :            :     // for checking different name bindings in alternatives, and for correcting
    6637                 :            :     // the order in which extracted elements are placed on the stack.
    6638                 :          0 :     PyObject *control = NULL;
    6639                 :            :     // NOTE: We can't use returning macros anymore! goto error on error.
    6640         [ #  # ]:          0 :     for (Py_ssize_t i = 0; i < size; i++) {
    6641                 :          0 :         pattern_ty alt = asdl_seq_GET(p->v.MatchOr.patterns, i);
    6642                 :          0 :         PyObject *pc_stores = PyList_New(0);
    6643         [ #  # ]:          0 :         if (pc_stores == NULL) {
    6644                 :          0 :             goto error;
    6645                 :            :         }
    6646                 :          0 :         Py_SETREF(pc->stores, pc_stores);
    6647                 :            :         // An irrefutable sub-pattern must be last, if it is allowed at all:
    6648   [ #  #  #  # ]:          0 :         pc->allow_irrefutable = (i == size - 1) && old_pc.allow_irrefutable;
    6649                 :          0 :         pc->fail_pop = NULL;
    6650                 :          0 :         pc->fail_pop_size = 0;
    6651                 :          0 :         pc->on_top = 0;
    6652   [ #  #  #  # ]:          0 :         if (codegen_addop_i(INSTR_SEQUENCE(c), COPY, 1, LOC(alt)) < 0 ||
    6653                 :          0 :             compiler_pattern(c, alt, pc) < 0) {
    6654                 :          0 :             goto error;
    6655                 :            :         }
    6656                 :            :         // Success!
    6657                 :          0 :         Py_ssize_t nstores = PyList_GET_SIZE(pc->stores);
    6658         [ #  # ]:          0 :         if (!i) {
    6659                 :            :             // This is the first alternative, so save its stores as a "control"
    6660                 :            :             // for the others (they can't bind a different set of names, and
    6661                 :            :             // might need to be reordered):
    6662                 :            :             assert(control == NULL);
    6663                 :          0 :             control = Py_NewRef(pc->stores);
    6664                 :            :         }
    6665         [ #  # ]:          0 :         else if (nstores != PyList_GET_SIZE(control)) {
    6666                 :          0 :             goto diff;
    6667                 :            :         }
    6668         [ #  # ]:          0 :         else if (nstores) {
    6669                 :            :             // There were captures. Check to see if we differ from control:
    6670                 :          0 :             Py_ssize_t icontrol = nstores;
    6671         [ #  # ]:          0 :             while (icontrol--) {
    6672                 :          0 :                 PyObject *name = PyList_GET_ITEM(control, icontrol);
    6673                 :          0 :                 Py_ssize_t istores = PySequence_Index(pc->stores, name);
    6674         [ #  # ]:          0 :                 if (istores < 0) {
    6675                 :          0 :                     PyErr_Clear();
    6676                 :          0 :                     goto diff;
    6677                 :            :                 }
    6678         [ #  # ]:          0 :                 if (icontrol != istores) {
    6679                 :            :                     // Reorder the names on the stack to match the order of the
    6680                 :            :                     // names in control. There's probably a better way of doing
    6681                 :            :                     // this; the current solution is potentially very
    6682                 :            :                     // inefficient when each alternative subpattern binds lots
    6683                 :            :                     // of names in different orders. It's fine for reasonable
    6684                 :            :                     // cases, though, and the peephole optimizer will ensure
    6685                 :            :                     // that the final code is as efficient as possible.
    6686                 :            :                     assert(istores < icontrol);
    6687                 :          0 :                     Py_ssize_t rotations = istores + 1;
    6688                 :            :                     // Perform the same rotation on pc->stores:
    6689                 :          0 :                     PyObject *rotated = PyList_GetSlice(pc->stores, 0,
    6690                 :            :                                                         rotations);
    6691   [ #  #  #  # ]:          0 :                     if (rotated == NULL ||
    6692         [ #  # ]:          0 :                         PyList_SetSlice(pc->stores, 0, rotations, NULL) ||
    6693                 :          0 :                         PyList_SetSlice(pc->stores, icontrol - istores,
    6694                 :            :                                         icontrol - istores, rotated))
    6695                 :            :                     {
    6696                 :          0 :                         Py_XDECREF(rotated);
    6697                 :          0 :                         goto error;
    6698                 :            :                     }
    6699                 :          0 :                     Py_DECREF(rotated);
    6700                 :            :                     // That just did:
    6701                 :            :                     // rotated = pc_stores[:rotations]
    6702                 :            :                     // del pc_stores[:rotations]
    6703                 :            :                     // pc_stores[icontrol-istores:icontrol-istores] = rotated
    6704                 :            :                     // Do the same thing to the stack, using several
    6705                 :            :                     // rotations:
    6706         [ #  # ]:          0 :                     while (rotations--) {
    6707         [ #  # ]:          0 :                         if (pattern_helper_rotate(c, LOC(alt), icontrol + 1) < 0) {
    6708                 :          0 :                             goto error;
    6709                 :            :                         }
    6710                 :            :                     }
    6711                 :            :                 }
    6712                 :            :             }
    6713                 :            :         }
    6714                 :            :         assert(control);
    6715   [ #  #  #  # ]:          0 :         if (codegen_addop_j(INSTR_SEQUENCE(c), LOC(alt), JUMP, end) < 0 ||
    6716                 :          0 :             emit_and_reset_fail_pop(c, LOC(alt), pc) < 0)
    6717                 :            :         {
    6718                 :          0 :             goto error;
    6719                 :            :         }
    6720                 :            :     }
    6721                 :          0 :     Py_DECREF(pc->stores);
    6722                 :          0 :     *pc = old_pc;
    6723                 :          0 :     Py_INCREF(pc->stores);
    6724                 :            :     // Need to NULL this for the PyObject_Free call in the error block.
    6725                 :          0 :     old_pc.fail_pop = NULL;
    6726                 :            :     // No match. Pop the remaining copy of the subject and fail:
    6727   [ #  #  #  # ]:          0 :     if (codegen_addop_noarg(INSTR_SEQUENCE(c), POP_TOP, LOC(p)) < 0 ||
    6728                 :          0 :         jump_to_fail_pop(c, LOC(p), pc, JUMP) < 0) {
    6729                 :          0 :         goto error;
    6730                 :            :     }
    6731                 :            : 
    6732         [ #  # ]:          0 :     USE_LABEL(c, end);
    6733                 :          0 :     Py_ssize_t nstores = PyList_GET_SIZE(control);
    6734                 :            :     // There's a bunch of stuff on the stack between where the new stores
    6735                 :            :     // are and where they need to be:
    6736                 :            :     // - The other stores.
    6737                 :            :     // - A copy of the subject.
    6738                 :            :     // - Anything else that may be on top of the stack.
    6739                 :            :     // - Any previous stores we've already stashed away on the stack.
    6740                 :          0 :     Py_ssize_t nrots = nstores + 1 + pc->on_top + PyList_GET_SIZE(pc->stores);
    6741         [ #  # ]:          0 :     for (Py_ssize_t i = 0; i < nstores; i++) {
    6742                 :            :         // Rotate this capture to its proper place on the stack:
    6743         [ #  # ]:          0 :         if (pattern_helper_rotate(c, LOC(p), nrots) < 0) {
    6744                 :          0 :             goto error;
    6745                 :            :         }
    6746                 :            :         // Update the list of previous stores with this new name, checking for
    6747                 :            :         // duplicates:
    6748                 :          0 :         PyObject *name = PyList_GET_ITEM(control, i);
    6749                 :          0 :         int dupe = PySequence_Contains(pc->stores, name);
    6750         [ #  # ]:          0 :         if (dupe < 0) {
    6751                 :          0 :             goto error;
    6752                 :            :         }
    6753         [ #  # ]:          0 :         if (dupe) {
    6754                 :          0 :             compiler_error_duplicate_store(c, LOC(p), name);
    6755                 :          0 :             goto error;
    6756                 :            :         }
    6757         [ #  # ]:          0 :         if (PyList_Append(pc->stores, name)) {
    6758                 :          0 :             goto error;
    6759                 :            :         }
    6760                 :            :     }
    6761                 :          0 :     Py_DECREF(old_pc.stores);
    6762                 :          0 :     Py_DECREF(control);
    6763                 :            :     // NOTE: Returning macros are safe again.
    6764                 :            :     // Pop the copy of the subject:
    6765         [ #  # ]:          0 :     ADDOP(c, LOC(p), POP_TOP);
    6766                 :          0 :     return SUCCESS;
    6767                 :          0 : diff:
    6768                 :          0 :     compiler_error(c, LOC(p), "alternative patterns bind different names");
    6769                 :          0 : error:
    6770                 :          0 :     PyObject_Free(old_pc.fail_pop);
    6771                 :          0 :     Py_DECREF(old_pc.stores);
    6772                 :          0 :     Py_XDECREF(control);
    6773                 :          0 :     return ERROR;
    6774                 :            : }
    6775                 :            : 
    6776                 :            : 
    6777                 :            : static int
    6778                 :          5 : compiler_pattern_sequence(struct compiler *c, pattern_ty p,
    6779                 :            :                           pattern_context *pc)
    6780                 :            : {
    6781                 :            :     assert(p->kind == MatchSequence_kind);
    6782                 :          5 :     asdl_pattern_seq *patterns = p->v.MatchSequence.patterns;
    6783         [ +  - ]:          5 :     Py_ssize_t size = asdl_seq_LEN(patterns);
    6784                 :          5 :     Py_ssize_t star = -1;
    6785                 :          5 :     int only_wildcard = 1;
    6786                 :          5 :     int star_wildcard = 0;
    6787                 :            :     // Find a starred name, if it exists. There may be at most one:
    6788         [ +  + ]:         10 :     for (Py_ssize_t i = 0; i < size; i++) {
    6789                 :          5 :         pattern_ty pattern = asdl_seq_GET(patterns, i);
    6790         [ +  + ]:          5 :         if (pattern->kind == MatchStar_kind) {
    6791         [ -  + ]:          1 :             if (star >= 0) {
    6792                 :          0 :                 const char *e = "multiple starred names in sequence pattern";
    6793                 :          0 :                 return compiler_error(c, LOC(p), e);
    6794                 :            :             }
    6795   [ +  -  -  + ]:          1 :             star_wildcard = WILDCARD_STAR_CHECK(pattern);
    6796                 :          1 :             only_wildcard &= star_wildcard;
    6797                 :          1 :             star = i;
    6798                 :          1 :             continue;
    6799                 :            :         }
    6800   [ -  +  -  - ]:          4 :         only_wildcard &= WILDCARD_CHECK(pattern);
    6801                 :            :     }
    6802                 :            :     // We need to keep the subject on top during the sequence and length checks:
    6803                 :          5 :     pc->on_top++;
    6804         [ -  + ]:          5 :     ADDOP(c, LOC(p), MATCH_SEQUENCE);
    6805         [ -  + ]:          5 :     RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
    6806         [ +  + ]:          5 :     if (star < 0) {
    6807                 :            :         // No star: len(subject) == size
    6808         [ -  + ]:          4 :         ADDOP(c, LOC(p), GET_LEN);
    6809   [ -  +  -  + ]:          4 :         ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size));
    6810         [ -  + ]:          4 :         ADDOP_COMPARE(c, LOC(p), Eq);
    6811         [ -  + ]:          4 :         RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
    6812                 :            :     }
    6813         [ -  + ]:          1 :     else if (size > 1) {
    6814                 :            :         // Star: len(subject) >= size - 1
    6815         [ #  # ]:          0 :         ADDOP(c, LOC(p), GET_LEN);
    6816   [ #  #  #  # ]:          0 :         ADDOP_LOAD_CONST_NEW(c, LOC(p), PyLong_FromSsize_t(size - 1));
    6817         [ #  # ]:          0 :         ADDOP_COMPARE(c, LOC(p), GtE);
    6818         [ #  # ]:          0 :         RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
    6819                 :            :     }
    6820                 :            :     // Whatever comes next should consume the subject:
    6821                 :          5 :     pc->on_top--;
    6822         [ -  + ]:          5 :     if (only_wildcard) {
    6823                 :            :         // Patterns like: [] / [_] / [_, _] / [*_] / [_, *_] / [_, _, *_] / etc.
    6824         [ #  # ]:          0 :         ADDOP(c, LOC(p), POP_TOP);
    6825                 :            :     }
    6826         [ -  + ]:          5 :     else if (star_wildcard) {
    6827         [ #  # ]:          0 :         RETURN_IF_ERROR(pattern_helper_sequence_subscr(c, LOC(p), patterns, star, pc));
    6828                 :            :     }
    6829                 :            :     else {
    6830         [ -  + ]:          5 :         RETURN_IF_ERROR(pattern_helper_sequence_unpack(c, LOC(p), patterns, star, pc));
    6831                 :            :     }
    6832                 :          5 :     return SUCCESS;
    6833                 :            : }
    6834                 :            : 
    6835                 :            : static int
    6836                 :          4 : compiler_pattern_value(struct compiler *c, pattern_ty p, pattern_context *pc)
    6837                 :            : {
    6838                 :            :     assert(p->kind == MatchValue_kind);
    6839                 :          4 :     expr_ty value = p->v.MatchValue.value;
    6840   [ -  +  -  - ]:          4 :     if (!MATCH_VALUE_EXPR(value)) {
    6841                 :          0 :         const char *e = "patterns may only match literals and attribute lookups";
    6842                 :          0 :         return compiler_error(c, LOC(p), e);
    6843                 :            :     }
    6844         [ -  + ]:          4 :     VISIT(c, expr, value);
    6845         [ -  + ]:          4 :     ADDOP_COMPARE(c, LOC(p), Eq);
    6846         [ -  + ]:          4 :     RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
    6847                 :          4 :     return SUCCESS;
    6848                 :            : }
    6849                 :            : 
    6850                 :            : static int
    6851                 :          1 : compiler_pattern_singleton(struct compiler *c, pattern_ty p, pattern_context *pc)
    6852                 :            : {
    6853                 :            :     assert(p->kind == MatchSingleton_kind);
    6854         [ -  + ]:          1 :     ADDOP_LOAD_CONST(c, LOC(p), p->v.MatchSingleton.value);
    6855         [ -  + ]:          1 :     ADDOP_COMPARE(c, LOC(p), Is);
    6856         [ -  + ]:          1 :     RETURN_IF_ERROR(jump_to_fail_pop(c, LOC(p), pc, POP_JUMP_IF_FALSE));
    6857                 :          1 :     return SUCCESS;
    6858                 :            : }
    6859                 :            : 
    6860                 :            : static int
    6861                 :         18 : compiler_pattern(struct compiler *c, pattern_ty p, pattern_context *pc)
    6862                 :            : {
    6863   [ +  +  +  -  :         18 :     switch (p->kind) {
             +  +  +  -  
                      - ]
    6864                 :          4 :         case MatchValue_kind:
    6865                 :          4 :             return compiler_pattern_value(c, p, pc);
    6866                 :          1 :         case MatchSingleton_kind:
    6867                 :          1 :             return compiler_pattern_singleton(c, p, pc);
    6868                 :          5 :         case MatchSequence_kind:
    6869                 :          5 :             return compiler_pattern_sequence(c, p, pc);
    6870                 :          0 :         case MatchMapping_kind:
    6871                 :          0 :             return compiler_pattern_mapping(c, p, pc);
    6872                 :          4 :         case MatchClass_kind:
    6873                 :          4 :             return compiler_pattern_class(c, p, pc);
    6874                 :          1 :         case MatchStar_kind:
    6875                 :          1 :             return compiler_pattern_star(c, p, pc);
    6876                 :          3 :         case MatchAs_kind:
    6877                 :          3 :             return compiler_pattern_as(c, p, pc);
    6878                 :          0 :         case MatchOr_kind:
    6879                 :          0 :             return compiler_pattern_or(c, p, pc);
    6880                 :            :     }
    6881                 :            :     // AST validator shouldn't let this happen, but if it does,
    6882                 :            :     // just fail, don't crash out of the interpreter
    6883                 :          0 :     const char *e = "invalid match pattern node in AST (kind=%d)";
    6884                 :          0 :     return compiler_error(c, LOC(p), e, p->kind);
    6885                 :            : }
    6886                 :            : 
    6887                 :            : static int
    6888                 :          4 : compiler_match_inner(struct compiler *c, stmt_ty s, pattern_context *pc)
    6889                 :            : {
    6890         [ -  + ]:          4 :     VISIT(c, expr, s->v.Match.subject);
    6891         [ -  + ]:          4 :     NEW_JUMP_TARGET_LABEL(c, end);
    6892         [ +  - ]:          4 :     Py_ssize_t cases = asdl_seq_LEN(s->v.Match.cases);
    6893                 :            :     assert(cases > 0);
    6894                 :          4 :     match_case_ty m = asdl_seq_GET(s->v.Match.cases, cases - 1);
    6895   [ +  +  +  -  :          4 :     int has_default = WILDCARD_CHECK(m->pattern) && 1 < cases;
                   +  - ]
    6896         [ +  + ]:         15 :     for (Py_ssize_t i = 0; i < cases - has_default; i++) {
    6897                 :         11 :         m = asdl_seq_GET(s->v.Match.cases, i);
    6898                 :            :         // Only copy the subject if we're *not* on the last case:
    6899         [ +  + ]:         11 :         if (i != cases - has_default - 1) {
    6900         [ -  + ]:          7 :             ADDOP_I(c, LOC(m->pattern), COPY, 1);
    6901                 :            :         }
    6902                 :         11 :         pc->stores = PyList_New(0);
    6903         [ -  + ]:         11 :         if (pc->stores == NULL) {
    6904                 :          0 :             return ERROR;
    6905                 :            :         }
    6906                 :            :         // Irrefutable cases must be either guarded, last, or both:
    6907   [ +  +  +  + ]:         11 :         pc->allow_irrefutable = m->guard != NULL || i == cases - 1;
    6908                 :         11 :         pc->fail_pop = NULL;
    6909                 :         11 :         pc->fail_pop_size = 0;
    6910                 :         11 :         pc->on_top = 0;
    6911                 :            :         // NOTE: Can't use returning macros here (they'll leak pc->stores)!
    6912         [ -  + ]:         11 :         if (compiler_pattern(c, m->pattern, pc) < 0) {
    6913                 :          0 :             Py_DECREF(pc->stores);
    6914                 :          0 :             return ERROR;
    6915                 :            :         }
    6916                 :            :         assert(!pc->on_top);
    6917                 :            :         // It's a match! Store all of the captured names (they're on the stack).
    6918                 :         11 :         Py_ssize_t nstores = PyList_GET_SIZE(pc->stores);
    6919         [ +  + ]:         15 :         for (Py_ssize_t n = 0; n < nstores; n++) {
    6920                 :          4 :             PyObject *name = PyList_GET_ITEM(pc->stores, n);
    6921         [ -  + ]:          4 :             if (compiler_nameop(c, LOC(m->pattern), name, Store) < 0) {
    6922                 :          0 :                 Py_DECREF(pc->stores);
    6923                 :          0 :                 return ERROR;
    6924                 :            :             }
    6925                 :            :         }
    6926                 :         11 :         Py_DECREF(pc->stores);
    6927                 :            :         // NOTE: Returning macros are safe again.
    6928         [ +  + ]:         11 :         if (m->guard) {
    6929         [ -  + ]:          1 :             RETURN_IF_ERROR(ensure_fail_pop(c, pc, 0));
    6930         [ -  + ]:          1 :             RETURN_IF_ERROR(compiler_jump_if(c, LOC(m->pattern), m->guard, pc->fail_pop[0], 0));
    6931                 :            :         }
    6932                 :            :         // Success! Pop the subject off, we're done with it:
    6933         [ +  + ]:         11 :         if (i != cases - has_default - 1) {
    6934         [ -  + ]:          7 :             ADDOP(c, LOC(m->pattern), POP_TOP);
    6935                 :            :         }
    6936   [ -  +  +  -  :         31 :         VISIT_SEQ(c, stmt, m->body);
                   +  + ]
    6937         [ -  + ]:         11 :         ADDOP_JUMP(c, NO_LOCATION, JUMP, end);
    6938                 :            :         // If the pattern fails to match, we want the line number of the
    6939                 :            :         // cleanup to be associated with the failed pattern, not the last line
    6940                 :            :         // of the body
    6941         [ -  + ]:         11 :         RETURN_IF_ERROR(emit_and_reset_fail_pop(c, LOC(m->pattern), pc));
    6942                 :            :     }
    6943         [ +  + ]:          4 :     if (has_default) {
    6944                 :            :         // A trailing "case _" is common, and lets us save a bit of redundant
    6945                 :            :         // pushing and popping in the loop above:
    6946                 :          1 :         m = asdl_seq_GET(s->v.Match.cases, cases - 1);
    6947         [ -  + ]:          1 :         if (cases == 1) {
    6948                 :            :             // No matches. Done with the subject:
    6949         [ #  # ]:          0 :             ADDOP(c, LOC(m->pattern), POP_TOP);
    6950                 :            :         }
    6951                 :            :         else {
    6952                 :            :             // Show line coverage for default case (it doesn't create bytecode)
    6953         [ -  + ]:          1 :             ADDOP(c, LOC(m->pattern), NOP);
    6954                 :            :         }
    6955         [ -  + ]:          1 :         if (m->guard) {
    6956         [ #  # ]:          0 :             RETURN_IF_ERROR(compiler_jump_if(c, LOC(m->pattern), m->guard, end, 0));
    6957                 :            :         }
    6958   [ -  +  +  -  :          2 :         VISIT_SEQ(c, stmt, m->body);
                   +  + ]
    6959                 :            :     }
    6960         [ -  + ]:          4 :     USE_LABEL(c, end);
    6961                 :          4 :     return SUCCESS;
    6962                 :            : }
    6963                 :            : 
    6964                 :            : static int
    6965                 :          4 : compiler_match(struct compiler *c, stmt_ty s)
    6966                 :            : {
    6967                 :            :     pattern_context pc;
    6968                 :          4 :     pc.fail_pop = NULL;
    6969                 :          4 :     int result = compiler_match_inner(c, s, &pc);
    6970                 :          4 :     PyObject_Free(pc.fail_pop);
    6971                 :          4 :     return result;
    6972                 :            : }
    6973                 :            : 
    6974                 :            : #undef WILDCARD_CHECK
    6975                 :            : #undef WILDCARD_STAR_CHECK
    6976                 :            : 
    6977                 :            : 
    6978                 :            : /* End of the compiler section, beginning of the assembler section */
    6979                 :            : 
    6980                 :            : 
    6981                 :            : struct assembler {
    6982                 :            :     PyObject *a_bytecode;  /* bytes containing bytecode */
    6983                 :            :     int a_offset;              /* offset into bytecode */
    6984                 :            :     PyObject *a_except_table;  /* bytes containing exception table */
    6985                 :            :     int a_except_table_off;    /* offset into exception table */
    6986                 :            :     /* Location Info */
    6987                 :            :     int a_lineno;          /* lineno of last emitted instruction */
    6988                 :            :     PyObject* a_linetable; /* bytes containing location info */
    6989                 :            :     int a_location_off;    /* offset of last written location info frame */
    6990                 :            : };
    6991                 :            : 
    6992                 :            : static basicblock**
    6993                 :      39288 : make_cfg_traversal_stack(basicblock *entryblock) {
    6994                 :      39288 :     int nblocks = 0;
    6995         [ +  + ]:     352190 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    6996                 :     312902 :         b->b_visited = 0;
    6997                 :     312902 :         nblocks++;
    6998                 :            :     }
    6999                 :      39288 :     basicblock **stack = (basicblock **)PyMem_Malloc(sizeof(basicblock *) * nblocks);
    7000         [ -  + ]:      39288 :     if (!stack) {
    7001                 :          0 :         PyErr_NoMemory();
    7002                 :            :     }
    7003                 :      39288 :     return stack;
    7004                 :            : }
    7005                 :            : 
    7006                 :            : Py_LOCAL_INLINE(void)
    7007                 :      61955 : stackdepth_push(basicblock ***sp, basicblock *b, int depth)
    7008                 :            : {
    7009                 :            :     assert(b->b_startdepth < 0 || b->b_startdepth == depth);
    7010   [ +  +  +  - ]:      61955 :     if (b->b_startdepth < depth && b->b_startdepth < 100) {
    7011                 :            :         assert(b->b_startdepth < 0);
    7012                 :      51311 :         b->b_startdepth = depth;
    7013                 :      51311 :         *(*sp)++ = b;
    7014                 :            :     }
    7015                 :      61955 : }
    7016                 :            : 
    7017                 :            : /* Find the flow path that needs the largest stack.  We assume that
    7018                 :            :  * cycles in the flow graph have no net effect on the stack depth.
    7019                 :            :  */
    7020                 :            : static int
    7021                 :       8041 : stackdepth(basicblock *entryblock, int code_flags)
    7022                 :            : {
    7023         [ +  + ]:      59352 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    7024                 :      51311 :         b->b_startdepth = INT_MIN;
    7025                 :            :     }
    7026                 :       8041 :     basicblock **stack = make_cfg_traversal_stack(entryblock);
    7027         [ -  + ]:       8041 :     if (!stack) {
    7028                 :          0 :         return ERROR;
    7029                 :            :     }
    7030                 :            : 
    7031                 :       8041 :     int maxdepth = 0;
    7032                 :       8041 :     basicblock **sp = stack;
    7033         [ +  + ]:       8041 :     if (code_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) {
    7034                 :        532 :         stackdepth_push(&sp, entryblock, 1);
    7035                 :            :     } else {
    7036                 :       7509 :         stackdepth_push(&sp, entryblock, 0);
    7037                 :            :     }
    7038                 :            : 
    7039         [ +  + ]:      59352 :     while (sp != stack) {
    7040                 :      51311 :         basicblock *b = *--sp;
    7041                 :      51311 :         int depth = b->b_startdepth;
    7042                 :            :         assert(depth >= 0);
    7043                 :      51311 :         basicblock *next = b->b_next;
    7044         [ +  + ]:     377664 :         for (int i = 0; i < b->b_iused; i++) {
    7045                 :     349175 :             struct cfg_instr *instr = &b->b_instr[i];
    7046                 :     349175 :             int effect = stack_effect(instr->i_opcode, instr->i_oparg, 0);
    7047         [ -  + ]:     349175 :             if (effect == PY_INVALID_STACK_EFFECT) {
    7048                 :          0 :                 PyErr_Format(PyExc_SystemError,
    7049                 :            :                              "compiler stack_effect(opcode=%d, arg=%i) failed",
    7050                 :            :                              instr->i_opcode, instr->i_oparg);
    7051                 :          0 :                 return ERROR;
    7052                 :            :             }
    7053                 :     349175 :             int new_depth = depth + effect;
    7054                 :            :             assert(new_depth >= 0); /* invalid code or bug in stackdepth() */
    7055         [ +  + ]:     349175 :             if (new_depth > maxdepth) {
    7056                 :      30259 :                 maxdepth = new_depth;
    7057                 :            :             }
    7058   [ +  +  +  +  :     349175 :             if (HAS_TARGET(instr->i_opcode)) {
             +  +  +  + ]
    7059                 :      25425 :                 effect = stack_effect(instr->i_opcode, instr->i_oparg, 1);
    7060                 :            :                 assert(effect != PY_INVALID_STACK_EFFECT);
    7061                 :      25425 :                 int target_depth = depth + effect;
    7062                 :            :                 assert(target_depth >= 0); /* invalid code or bug in stackdepth() */
    7063         [ +  + ]:      25425 :                 if (target_depth > maxdepth) {
    7064                 :        994 :                     maxdepth = target_depth;
    7065                 :            :                 }
    7066                 :      25425 :                 stackdepth_push(&sp, instr->i_target, target_depth);
    7067                 :            :             }
    7068                 :     349175 :             depth = new_depth;
    7069                 :            :             assert(!IS_ASSEMBLER_OPCODE(instr->i_opcode));
    7070   [ +  +  +  +  :     349175 :             if (IS_UNCONDITIONAL_JUMP_OPCODE(instr->i_opcode) ||
          +  -  +  -  +  
                      - ]
    7071   [ +  +  +  +  :     344150 :                 IS_SCOPE_EXIT_OPCODE(instr->i_opcode))
             +  +  +  + ]
    7072                 :            :             {
    7073                 :            :                 /* remaining code is dead */
    7074                 :      22822 :                 next = NULL;
    7075                 :      22822 :                 break;
    7076                 :            :             }
    7077                 :            :         }
    7078         [ +  + ]:      51311 :         if (next != NULL) {
    7079                 :            :             assert(BB_HAS_FALLTHROUGH(b));
    7080                 :      28489 :             stackdepth_push(&sp, next, depth);
    7081                 :            :         }
    7082                 :            :     }
    7083                 :       8041 :     PyMem_Free(stack);
    7084                 :       8041 :     return maxdepth;
    7085                 :            : }
    7086                 :            : 
    7087                 :            : static int
    7088                 :       8041 : assemble_init(struct assembler *a, int firstlineno)
    7089                 :            : {
    7090                 :       8041 :     memset(a, 0, sizeof(struct assembler));
    7091                 :       8041 :     a->a_lineno = firstlineno;
    7092                 :       8041 :     a->a_linetable = NULL;
    7093                 :       8041 :     a->a_location_off = 0;
    7094                 :       8041 :     a->a_except_table = NULL;
    7095                 :       8041 :     a->a_bytecode = PyBytes_FromStringAndSize(NULL, DEFAULT_CODE_SIZE);
    7096         [ -  + ]:       8041 :     if (a->a_bytecode == NULL) {
    7097                 :          0 :         goto error;
    7098                 :            :     }
    7099                 :       8041 :     a->a_linetable = PyBytes_FromStringAndSize(NULL, DEFAULT_CNOTAB_SIZE);
    7100         [ -  + ]:       8041 :     if (a->a_linetable == NULL) {
    7101                 :          0 :         goto error;
    7102                 :            :     }
    7103                 :       8041 :     a->a_except_table = PyBytes_FromStringAndSize(NULL, DEFAULT_LNOTAB_SIZE);
    7104         [ -  + ]:       8041 :     if (a->a_except_table == NULL) {
    7105                 :          0 :         goto error;
    7106                 :            :     }
    7107                 :       8041 :     return SUCCESS;
    7108                 :          0 : error:
    7109                 :          0 :     Py_XDECREF(a->a_bytecode);
    7110                 :          0 :     Py_XDECREF(a->a_linetable);
    7111                 :          0 :     Py_XDECREF(a->a_except_table);
    7112                 :          0 :     return ERROR;
    7113                 :            : }
    7114                 :            : 
    7115                 :            : static void
    7116                 :       8041 : assemble_free(struct assembler *a)
    7117                 :            : {
    7118                 :       8041 :     Py_XDECREF(a->a_bytecode);
    7119                 :       8041 :     Py_XDECREF(a->a_linetable);
    7120                 :       8041 :     Py_XDECREF(a->a_except_table);
    7121                 :       8041 : }
    7122                 :            : 
    7123                 :            : static int
    7124                 :      61502 : blocksize(basicblock *b)
    7125                 :            : {
    7126                 :      61502 :     int size = 0;
    7127         [ +  + ]:     465669 :     for (int i = 0; i < b->b_iused; i++) {
    7128                 :     404167 :         size += instr_size(&b->b_instr[i]);
    7129                 :            :     }
    7130                 :      61502 :     return size;
    7131                 :            : }
    7132                 :            : 
    7133                 :            : static basicblock *
    7134                 :       4732 : push_except_block(ExceptStack *stack, struct cfg_instr *setup) {
    7135                 :            :     assert(is_block_push(setup));
    7136                 :       4732 :     int opcode = setup->i_opcode;
    7137                 :       4732 :     basicblock * target = setup->i_target;
    7138   [ +  +  +  + ]:       4732 :     if (opcode == SETUP_WITH || opcode == SETUP_CLEANUP) {
    7139                 :       3055 :         target->b_preserve_lasti = 1;
    7140                 :            :     }
    7141                 :       4732 :     stack->handlers[++stack->depth] = target;
    7142                 :       4732 :     return target;
    7143                 :            : }
    7144                 :            : 
    7145                 :            : static basicblock *
    7146                 :       3949 : pop_except_block(ExceptStack *stack) {
    7147                 :            :     assert(stack->depth > 0);
    7148                 :       3949 :     return stack->handlers[--stack->depth];
    7149                 :            : }
    7150                 :            : 
    7151                 :            : static basicblock *
    7152                 :      54053 : except_stack_top(ExceptStack *stack) {
    7153                 :      54053 :     return stack->handlers[stack->depth];
    7154                 :            : }
    7155                 :            : 
    7156                 :            : static ExceptStack *
    7157                 :       8041 : make_except_stack(void) {
    7158                 :       8041 :     ExceptStack *new = PyMem_Malloc(sizeof(ExceptStack));
    7159         [ -  + ]:       8041 :     if (new == NULL) {
    7160                 :          0 :         PyErr_NoMemory();
    7161                 :          0 :         return NULL;
    7162                 :            :     }
    7163                 :       8041 :     new->depth = 0;
    7164                 :       8041 :     new->handlers[0] = NULL;
    7165                 :       8041 :     return new;
    7166                 :            : }
    7167                 :            : 
    7168                 :            : static ExceptStack *
    7169                 :      18779 : copy_except_stack(ExceptStack *stack) {
    7170                 :      18779 :     ExceptStack *copy = PyMem_Malloc(sizeof(ExceptStack));
    7171         [ -  + ]:      18779 :     if (copy == NULL) {
    7172                 :          0 :         PyErr_NoMemory();
    7173                 :          0 :         return NULL;
    7174                 :            :     }
    7175                 :      18779 :     memcpy(copy, stack, sizeof(ExceptStack));
    7176                 :      18779 :     return copy;
    7177                 :            : }
    7178                 :            : 
    7179                 :            : static int
    7180                 :       8041 : label_exception_targets(basicblock *entryblock) {
    7181                 :       8041 :     basicblock **todo_stack = make_cfg_traversal_stack(entryblock);
    7182         [ -  + ]:       8041 :     if (todo_stack == NULL) {
    7183                 :          0 :         return ERROR;
    7184                 :            :     }
    7185                 :       8041 :     ExceptStack *except_stack = make_except_stack();
    7186         [ -  + ]:       8041 :     if (except_stack == NULL) {
    7187                 :          0 :         PyMem_Free(todo_stack);
    7188                 :          0 :         PyErr_NoMemory();
    7189                 :          0 :         return ERROR;
    7190                 :            :     }
    7191                 :       8041 :     except_stack->depth = 0;
    7192                 :       8041 :     todo_stack[0] = entryblock;
    7193                 :       8041 :     entryblock->b_visited = 1;
    7194                 :       8041 :     entryblock->b_exceptstack = except_stack;
    7195                 :       8041 :     basicblock **todo = &todo_stack[1];
    7196                 :       8041 :     basicblock *handler = NULL;
    7197         [ +  + ]:      62094 :     while (todo > todo_stack) {
    7198                 :      54053 :         todo--;
    7199                 :      54053 :         basicblock *b = todo[0];
    7200                 :            :         assert(b->b_visited == 1);
    7201                 :      54053 :         except_stack = b->b_exceptstack;
    7202                 :            :         assert(except_stack != NULL);
    7203                 :      54053 :         b->b_exceptstack = NULL;
    7204                 :      54053 :         handler = except_stack_top(except_stack);
    7205         [ +  + ]:     424982 :         for (int i = 0; i < b->b_iused; i++) {
    7206                 :     370929 :             struct cfg_instr *instr = &b->b_instr[i];
    7207         [ +  + ]:     370929 :             if (is_block_push(instr)) {
    7208         [ +  - ]:       4732 :                 if (!instr->i_target->b_visited) {
    7209                 :       4732 :                     ExceptStack *copy = copy_except_stack(except_stack);
    7210         [ -  + ]:       4732 :                     if (copy == NULL) {
    7211                 :          0 :                         goto error;
    7212                 :            :                     }
    7213                 :       4732 :                     instr->i_target->b_exceptstack = copy;
    7214                 :       4732 :                     todo[0] = instr->i_target;
    7215                 :       4732 :                     instr->i_target->b_visited = 1;
    7216                 :       4732 :                     todo++;
    7217                 :            :                 }
    7218                 :       4732 :                 handler = push_except_block(except_stack, instr);
    7219                 :            :             }
    7220         [ +  + ]:     366197 :             else if (instr->i_opcode == POP_BLOCK) {
    7221                 :       3949 :                 handler = pop_except_block(except_stack);
    7222                 :            :             }
    7223         [ +  + ]:     362248 :             else if (is_jump(instr)) {
    7224                 :      23254 :                 instr->i_except = handler;
    7225                 :            :                 assert(i == b->b_iused -1);
    7226         [ +  + ]:      23254 :                 if (!instr->i_target->b_visited) {
    7227         [ +  + ]:      17544 :                     if (BB_HAS_FALLTHROUGH(b)) {
    7228                 :      14047 :                         ExceptStack *copy = copy_except_stack(except_stack);
    7229         [ -  + ]:      14047 :                         if (copy == NULL) {
    7230                 :          0 :                             goto error;
    7231                 :            :                         }
    7232                 :      14047 :                         instr->i_target->b_exceptstack = copy;
    7233                 :            :                     }
    7234                 :            :                     else {
    7235                 :       3497 :                         instr->i_target->b_exceptstack = except_stack;
    7236                 :       3497 :                         except_stack = NULL;
    7237                 :            :                     }
    7238                 :      17544 :                     todo[0] = instr->i_target;
    7239                 :      17544 :                     instr->i_target->b_visited = 1;
    7240                 :      17544 :                     todo++;
    7241                 :            :                 }
    7242                 :            :             }
    7243                 :            :             else {
    7244         [ +  + ]:     338994 :                 if (instr->i_opcode == YIELD_VALUE) {
    7245                 :        640 :                     instr->i_oparg = except_stack->depth;
    7246                 :            :                 }
    7247                 :     338994 :                 instr->i_except = handler;
    7248                 :            :             }
    7249                 :            :         }
    7250   [ +  +  +  + ]:      54053 :         if (BB_HAS_FALLTHROUGH(b) && !b->b_next->b_visited) {
    7251                 :            :             assert(except_stack != NULL);
    7252                 :      23736 :             b->b_next->b_exceptstack = except_stack;
    7253                 :      23736 :             todo[0] = b->b_next;
    7254                 :      23736 :             b->b_next->b_visited = 1;
    7255                 :      23736 :             todo++;
    7256                 :            :         }
    7257         [ +  + ]:      30317 :         else if (except_stack != NULL) {
    7258                 :      26820 :            PyMem_Free(except_stack);
    7259                 :            :         }
    7260                 :            :     }
    7261                 :            : #ifdef Py_DEBUG
    7262                 :            :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    7263                 :            :         assert(b->b_exceptstack == NULL);
    7264                 :            :     }
    7265                 :            : #endif
    7266                 :       8041 :     PyMem_Free(todo_stack);
    7267                 :       8041 :     return SUCCESS;
    7268                 :          0 : error:
    7269                 :          0 :     PyMem_Free(todo_stack);
    7270                 :          0 :     PyMem_Free(except_stack);
    7271                 :          0 :     return ERROR;
    7272                 :            : }
    7273                 :            : 
    7274                 :            : 
    7275                 :            : static int
    7276                 :       8041 : mark_except_handlers(basicblock *entryblock) {
    7277                 :            : #ifndef NDEBUG
    7278                 :            :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    7279                 :            :         assert(!b->b_except_handler);
    7280                 :            :     }
    7281                 :            : #endif
    7282         [ +  + ]:      69608 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    7283         [ +  + ]:     448179 :         for (int i=0; i < b->b_iused; i++) {
    7284                 :     386612 :             struct cfg_instr *instr = &b->b_instr[i];
    7285         [ +  + ]:     386612 :             if (is_block_push(instr)) {
    7286                 :       4742 :                 instr->i_target->b_except_handler = 1;
    7287                 :            :             }
    7288                 :            :         }
    7289                 :            :     }
    7290                 :       8041 :     return SUCCESS;
    7291                 :            : }
    7292                 :            : 
    7293                 :            : static int
    7294                 :       4163 : mark_warm(basicblock *entryblock) {
    7295                 :       4163 :     basicblock **stack = make_cfg_traversal_stack(entryblock);
    7296         [ -  + ]:       4163 :     if (stack == NULL) {
    7297                 :          0 :         return ERROR;
    7298                 :            :     }
    7299                 :       4163 :     basicblock **sp = stack;
    7300                 :            : 
    7301                 :       4163 :     *sp++ = entryblock;
    7302                 :       4163 :     entryblock->b_visited = 1;
    7303         [ +  + ]:      40123 :     while (sp > stack) {
    7304                 :      35960 :         basicblock *b = *(--sp);
    7305                 :            :         assert(!b->b_except_handler);
    7306                 :      35960 :         b->b_warm = 1;
    7307                 :      35960 :         basicblock *next = b->b_next;
    7308   [ +  +  +  +  :      35960 :         if (next && BB_HAS_FALLTHROUGH(b) && !next->b_visited) {
                   +  + ]
    7309                 :      19933 :             *sp++ = next;
    7310                 :      19933 :             next->b_visited = 1;
    7311                 :            :         }
    7312         [ +  + ]:     270596 :         for (int i=0; i < b->b_iused; i++) {
    7313                 :     234636 :             struct cfg_instr *instr = &b->b_instr[i];
    7314   [ +  +  +  + ]:     234636 :             if (is_jump(instr) && !instr->i_target->b_visited) {
    7315                 :      11864 :                 *sp++ = instr->i_target;
    7316                 :      11864 :                 instr->i_target->b_visited = 1;
    7317                 :            :             }
    7318                 :            :         }
    7319                 :            :     }
    7320                 :       4163 :     PyMem_Free(stack);
    7321                 :       4163 :     return SUCCESS;
    7322                 :            : }
    7323                 :            : 
    7324                 :            : static int
    7325                 :       4163 : mark_cold(basicblock *entryblock) {
    7326         [ +  + ]:      50901 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    7327                 :            :         assert(!b->b_cold && !b->b_warm);
    7328                 :            :     }
    7329         [ -  + ]:       4163 :     if (mark_warm(entryblock) < 0) {
    7330                 :          0 :         return ERROR;
    7331                 :            :     }
    7332                 :            : 
    7333                 :       4163 :     basicblock **stack = make_cfg_traversal_stack(entryblock);
    7334         [ -  + ]:       4163 :     if (stack == NULL) {
    7335                 :          0 :         return ERROR;
    7336                 :            :     }
    7337                 :            : 
    7338                 :       4163 :     basicblock **sp = stack;
    7339         [ +  + ]:      50901 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    7340         [ +  + ]:      46738 :         if (b->b_except_handler) {
    7341                 :            :             assert(!b->b_warm);
    7342                 :       4731 :             *sp++ = b;
    7343                 :       4731 :             b->b_visited = 1;
    7344                 :            :         }
    7345                 :            :     }
    7346                 :            : 
    7347         [ +  + ]:      14941 :     while (sp > stack) {
    7348                 :      10778 :         basicblock *b = *(--sp);
    7349                 :      10778 :         b->b_cold = 1;
    7350                 :      10778 :         basicblock *next = b->b_next;
    7351   [ +  +  +  + ]:      10778 :         if (next && BB_HAS_FALLTHROUGH(b)) {
    7352   [ +  +  +  + ]:       4154 :             if (!next->b_warm && !next->b_visited) {
    7353                 :       3828 :                 *sp++ = next;
    7354                 :       3828 :                 next->b_visited = 1;
    7355                 :            :             }
    7356                 :            :         }
    7357         [ +  + ]:      49664 :         for (int i = 0; i < b->b_iused; i++) {
    7358                 :      38886 :             struct cfg_instr *instr = &b->b_instr[i];
    7359         [ +  + ]:      38886 :             if (is_jump(instr)) {
    7360                 :            :                 assert(i == b->b_iused - 1);
    7361                 :       3191 :                 basicblock *target = b->b_instr[i].i_target;
    7362   [ +  +  +  + ]:       3191 :                 if (!target->b_warm && !target->b_visited) {
    7363                 :       2219 :                     *sp++ = target;
    7364                 :       2219 :                     target->b_visited = 1;
    7365                 :            :                 }
    7366                 :            :             }
    7367                 :            :         }
    7368                 :            :     }
    7369                 :       4163 :     PyMem_Free(stack);
    7370                 :       4163 :     return SUCCESS;
    7371                 :            : }
    7372                 :            : 
    7373                 :            : static int
    7374                 :            : remove_redundant_jumps(cfg_builder *g);
    7375                 :            : 
    7376                 :            : static int
    7377                 :       8041 : push_cold_blocks_to_end(cfg_builder *g, int code_flags) {
    7378                 :       8041 :     basicblock *entryblock = g->g_entryblock;
    7379         [ +  + ]:       8041 :     if (entryblock->b_next == NULL) {
    7380                 :            :         /* single basicblock, no need to reorder */
    7381                 :       3878 :         return SUCCESS;
    7382                 :            :     }
    7383         [ -  + ]:       4163 :     RETURN_IF_ERROR(mark_cold(entryblock));
    7384                 :            : 
    7385                 :            :     /* If we have a cold block with fallthrough to a warm block, add */
    7386                 :            :     /* an explicit jump instead of fallthrough */
    7387         [ +  + ]:      51082 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    7388   [ +  +  +  +  :      46919 :         if (b->b_cold && BB_HAS_FALLTHROUGH(b) && b->b_next && b->b_next->b_warm) {
             +  -  +  + ]
    7389                 :        181 :             basicblock *explicit_jump = cfg_builder_new_block(g);
    7390         [ -  + ]:        181 :             if (explicit_jump == NULL) {
    7391                 :          0 :                 return ERROR;
    7392                 :            :             }
    7393                 :        181 :             basicblock_addop(explicit_jump, JUMP, b->b_next->b_label.id, NO_LOCATION);
    7394                 :        181 :             explicit_jump->b_cold = 1;
    7395                 :        181 :             explicit_jump->b_next = b->b_next;
    7396                 :        181 :             b->b_next = explicit_jump;
    7397                 :            : 
    7398                 :            :             /* set target */
    7399                 :        181 :             struct cfg_instr *last = basicblock_last_instr(explicit_jump);
    7400                 :        181 :             last->i_target = explicit_jump->b_next;
    7401                 :            :         }
    7402                 :            :     }
    7403                 :            : 
    7404                 :            :     assert(!entryblock->b_cold);  /* First block can't be cold */
    7405                 :       4163 :     basicblock *cold_blocks = NULL;
    7406                 :       4163 :     basicblock *cold_blocks_tail = NULL;
    7407                 :            : 
    7408                 :       4163 :     basicblock *b = entryblock;
    7409         [ +  + ]:       6539 :     while(b->b_next) {
    7410                 :            :         assert(!b->b_cold);
    7411   [ +  +  +  + ]:      37263 :         while (b->b_next && !b->b_next->b_cold) {
    7412                 :      31797 :             b = b->b_next;
    7413                 :            :         }
    7414         [ +  + ]:       5466 :         if (b->b_next == NULL) {
    7415                 :            :             /* no more cold blocks */
    7416                 :       3090 :             break;
    7417                 :            :         }
    7418                 :            : 
    7419                 :            :         /* b->b_next is the beginning of a cold streak */
    7420                 :            :         assert(!b->b_cold && b->b_next->b_cold);
    7421                 :            : 
    7422                 :       2376 :         basicblock *b_end = b->b_next;
    7423   [ +  +  +  + ]:      10959 :         while (b_end->b_next && b_end->b_next->b_cold) {
    7424                 :       8583 :             b_end = b_end->b_next;
    7425                 :            :         }
    7426                 :            : 
    7427                 :            :         /* b_end is the end of the cold streak */
    7428                 :            :         assert(b_end && b_end->b_cold);
    7429                 :            :         assert(b_end->b_next == NULL || !b_end->b_next->b_cold);
    7430                 :            : 
    7431         [ +  + ]:       2376 :         if (cold_blocks == NULL) {
    7432                 :       1599 :             cold_blocks = b->b_next;
    7433                 :            :         }
    7434                 :            :         else {
    7435                 :        777 :             cold_blocks_tail->b_next = b->b_next;
    7436                 :            :         }
    7437                 :       2376 :         cold_blocks_tail = b_end;
    7438                 :       2376 :         b->b_next = b_end->b_next;
    7439                 :       2376 :         b_end->b_next = NULL;
    7440                 :            :     }
    7441                 :            :     assert(b != NULL && b->b_next == NULL);
    7442                 :       4163 :     b->b_next = cold_blocks;
    7443                 :            : 
    7444         [ +  + ]:       4163 :     if (cold_blocks != NULL) {
    7445         [ -  + ]:       1599 :         RETURN_IF_ERROR(remove_redundant_jumps(g));
    7446                 :            :     }
    7447                 :       4163 :     return SUCCESS;
    7448                 :            : }
    7449                 :            : 
    7450                 :            : static void
    7451                 :       8041 : convert_exception_handlers_to_nops(basicblock *entryblock) {
    7452         [ +  + ]:      59352 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    7453         [ +  + ]:     400486 :         for (int i = 0; i < b->b_iused; i++) {
    7454                 :     349175 :             struct cfg_instr *instr = &b->b_instr[i];
    7455   [ +  +  +  + ]:     349175 :             if (is_block_push(instr) || instr->i_opcode == POP_BLOCK) {
    7456                 :       8731 :                 INSTR_SET_OP0(instr, NOP);
    7457                 :            :             }
    7458                 :            :         }
    7459                 :            :     }
    7460         [ +  + ]:      59352 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    7461                 :      51311 :         remove_redundant_nops(b);
    7462                 :            :     }
    7463                 :       8041 : }
    7464                 :            : 
    7465                 :            : static inline void
    7466                 :      41949 : write_except_byte(struct assembler *a, int byte) {
    7467                 :      41949 :     unsigned char *p = (unsigned char *) PyBytes_AS_STRING(a->a_except_table);
    7468                 :      41949 :     p[a->a_except_table_off++] = byte;
    7469                 :      41949 : }
    7470                 :            : 
    7471                 :            : #define CONTINUATION_BIT 64
    7472                 :            : 
    7473                 :            : static void
    7474                 :      29760 : assemble_emit_exception_table_item(struct assembler *a, int value, int msb)
    7475                 :            : {
    7476                 :            :     assert ((msb | 128) == 128);
    7477                 :            :     assert(value >= 0 && value < (1 << 30));
    7478         [ -  + ]:      29760 :     if (value >= 1 << 24) {
    7479                 :          0 :         write_except_byte(a, (value >> 24) | CONTINUATION_BIT | msb);
    7480                 :          0 :         msb = 0;
    7481                 :            :     }
    7482         [ -  + ]:      29760 :     if (value >= 1 << 18) {
    7483                 :          0 :         write_except_byte(a, ((value >> 18)&0x3f) | CONTINUATION_BIT | msb);
    7484                 :          0 :         msb = 0;
    7485                 :            :     }
    7486         [ +  + ]:      29760 :     if (value >= 1 << 12) {
    7487                 :         21 :         write_except_byte(a, ((value >> 12)&0x3f) | CONTINUATION_BIT | msb);
    7488                 :         21 :         msb = 0;
    7489                 :            :     }
    7490         [ +  + ]:      29760 :     if (value >= 1 << 6) {
    7491                 :      12168 :         write_except_byte(a, ((value >> 6)&0x3f) | CONTINUATION_BIT | msb);
    7492                 :      12168 :         msb = 0;
    7493                 :            :     }
    7494                 :      29760 :     write_except_byte(a, (value&0x3f) | msb);
    7495                 :      29760 : }
    7496                 :            : 
    7497                 :            : /* See Objects/exception_handling_notes.txt for details of layout */
    7498                 :            : #define MAX_SIZE_OF_ENTRY 20
    7499                 :            : 
    7500                 :            : static int
    7501                 :       7440 : assemble_emit_exception_table_entry(struct assembler *a, int start, int end, basicblock *handler)
    7502                 :            : {
    7503                 :       7440 :     Py_ssize_t len = PyBytes_GET_SIZE(a->a_except_table);
    7504         [ +  + ]:       7440 :     if (a->a_except_table_off + MAX_SIZE_OF_ENTRY >= len) {
    7505         [ -  + ]:       2546 :         RETURN_IF_ERROR(_PyBytes_Resize(&a->a_except_table, len * 2));
    7506                 :            :     }
    7507                 :       7440 :     int size = end-start;
    7508                 :            :     assert(end > start);
    7509                 :       7440 :     int target = handler->b_offset;
    7510                 :       7440 :     int depth = handler->b_startdepth - 1;
    7511         [ +  + ]:       7440 :     if (handler->b_preserve_lasti) {
    7512                 :       5296 :         depth -= 1;
    7513                 :            :     }
    7514                 :            :     assert(depth >= 0);
    7515                 :       7440 :     int depth_lasti = (depth<<1) | handler->b_preserve_lasti;
    7516                 :       7440 :     assemble_emit_exception_table_item(a, start, (1<<7));
    7517                 :       7440 :     assemble_emit_exception_table_item(a, size, 0);
    7518                 :       7440 :     assemble_emit_exception_table_item(a, target, 0);
    7519                 :       7440 :     assemble_emit_exception_table_item(a, depth_lasti, 0);
    7520                 :       7440 :     return SUCCESS;
    7521                 :            : }
    7522                 :            : 
    7523                 :            : static int
    7524                 :       8041 : assemble_exception_table(struct assembler *a, basicblock *entryblock)
    7525                 :            : {
    7526                 :            :     basicblock *b;
    7527                 :       8041 :     int ioffset = 0;
    7528                 :       8041 :     basicblock *handler = NULL;
    7529                 :       8041 :     int start = -1;
    7530         [ +  + ]:      60209 :     for (b = entryblock; b != NULL; b = b->b_next) {
    7531                 :      52168 :         ioffset = b->b_offset;
    7532         [ +  + ]:     394204 :         for (int i = 0; i < b->b_iused; i++) {
    7533                 :     342036 :             struct cfg_instr *instr = &b->b_instr[i];
    7534         [ +  + ]:     342036 :             if (instr->i_except != handler) {
    7535         [ +  + ]:      12492 :                 if (handler != NULL) {
    7536         [ -  + ]:       7440 :                     RETURN_IF_ERROR(
    7537                 :            :                         assemble_emit_exception_table_entry(a, start, ioffset, handler));
    7538                 :            :                 }
    7539                 :      12492 :                 start = ioffset;
    7540                 :      12492 :                 handler = instr->i_except;
    7541                 :            :             }
    7542                 :     342036 :             ioffset += instr_size(instr);
    7543                 :            :         }
    7544                 :            :     }
    7545         [ -  + ]:       8041 :     if (handler != NULL) {
    7546         [ #  # ]:          0 :         RETURN_IF_ERROR(assemble_emit_exception_table_entry(a, start, ioffset, handler));
    7547                 :            :     }
    7548                 :       8041 :     return SUCCESS;
    7549                 :            : }
    7550                 :            : 
    7551                 :            : /* Code location emitting code. See locations.md for a description of the format. */
    7552                 :            : 
    7553                 :            : #define MSB 0x80
    7554                 :            : 
    7555                 :            : static void
    7556                 :     346578 : write_location_byte(struct assembler* a, int val)
    7557                 :            : {
    7558                 :     346578 :     PyBytes_AS_STRING(a->a_linetable)[a->a_location_off] = val&255;
    7559                 :     346578 :     a->a_location_off++;
    7560                 :     346578 : }
    7561                 :            : 
    7562                 :            : 
    7563                 :            : static uint8_t *
    7564                 :     445463 : location_pointer(struct assembler* a)
    7565                 :            : {
    7566                 :     445463 :     return (uint8_t *)PyBytes_AS_STRING(a->a_linetable) +
    7567                 :     445463 :         a->a_location_off;
    7568                 :            : }
    7569                 :            : 
    7570                 :            : static void
    7571                 :     286095 : write_location_first_byte(struct assembler* a, int code, int length)
    7572                 :            : {
    7573                 :     286095 :     a->a_location_off += write_location_entry_start(
    7574                 :            :         location_pointer(a), code, length);
    7575                 :     286095 : }
    7576                 :            : 
    7577                 :            : static void
    7578                 :     119127 : write_location_varint(struct assembler* a, unsigned int val)
    7579                 :            : {
    7580                 :     119127 :     uint8_t *ptr = location_pointer(a);
    7581                 :     119127 :     a->a_location_off += write_varint(ptr, val);
    7582                 :     119127 : }
    7583                 :            : 
    7584                 :            : 
    7585                 :            : static void
    7586                 :      40241 : write_location_signed_varint(struct assembler* a, int val)
    7587                 :            : {
    7588                 :      40241 :     uint8_t *ptr = location_pointer(a);
    7589                 :      40241 :     a->a_location_off += write_signed_varint(ptr, val);
    7590                 :      40241 : }
    7591                 :            : 
    7592                 :            : static void
    7593                 :     133188 : write_location_info_short_form(struct assembler* a, int length, int column, int end_column)
    7594                 :            : {
    7595                 :            :     assert(length > 0 &&  length <= 8);
    7596                 :     133188 :     int column_low_bits = column & 7;
    7597                 :     133188 :     int column_group = column >> 3;
    7598                 :            :     assert(column < 80);
    7599                 :            :     assert(end_column >= column);
    7600                 :            :     assert(end_column - column < 16);
    7601                 :     133188 :     write_location_first_byte(a, PY_CODE_LOCATION_INFO_SHORT0 + column_group, length);
    7602                 :     133188 :     write_location_byte(a, (column_low_bits << 4) | (end_column - column));
    7603                 :     133188 : }
    7604                 :            : 
    7605                 :            : static void
    7606                 :     106695 : write_location_info_oneline_form(struct assembler* a, int length, int line_delta, int column, int end_column)
    7607                 :            : {
    7608                 :            :     assert(length > 0 &&  length <= 8);
    7609                 :            :     assert(line_delta >= 0 && line_delta < 3);
    7610                 :            :     assert(column < 128);
    7611                 :            :     assert(end_column < 128);
    7612                 :     106695 :     write_location_first_byte(a, PY_CODE_LOCATION_INFO_ONE_LINE0 + line_delta, length);
    7613                 :     106695 :     write_location_byte(a, column);
    7614                 :     106695 :     write_location_byte(a, end_column);
    7615                 :     106695 : }
    7616                 :            : 
    7617                 :            : static void
    7618                 :      39709 : write_location_info_long_form(struct assembler* a, location loc, int length)
    7619                 :            : {
    7620                 :            :     assert(length > 0 &&  length <= 8);
    7621                 :      39709 :     write_location_first_byte(a, PY_CODE_LOCATION_INFO_LONG, length);
    7622                 :      39709 :     write_location_signed_varint(a, loc.lineno - a->a_lineno);
    7623                 :            :     assert(loc.end_lineno >= loc.lineno);
    7624                 :      39709 :     write_location_varint(a, loc.end_lineno - loc.lineno);
    7625                 :      39709 :     write_location_varint(a, loc.col_offset + 1);
    7626                 :      39709 :     write_location_varint(a, loc.end_col_offset + 1);
    7627                 :      39709 : }
    7628                 :            : 
    7629                 :            : static void
    7630                 :       5971 : write_location_info_none(struct assembler* a, int length)
    7631                 :            : {
    7632                 :       5971 :     write_location_first_byte(a, PY_CODE_LOCATION_INFO_NONE, length);
    7633                 :       5971 : }
    7634                 :            : 
    7635                 :            : static void
    7636                 :        532 : write_location_info_no_column(struct assembler* a, int length, int line_delta)
    7637                 :            : {
    7638                 :        532 :     write_location_first_byte(a, PY_CODE_LOCATION_INFO_NO_COLUMNS, length);
    7639                 :        532 :     write_location_signed_varint(a, line_delta);
    7640                 :        532 : }
    7641                 :            : 
    7642                 :            : #define THEORETICAL_MAX_ENTRY_SIZE 25 /* 1 + 6 + 6 + 6 + 6 */
    7643                 :            : 
    7644                 :            : static int
    7645                 :     286095 : write_location_info_entry(struct assembler* a, location loc, int isize)
    7646                 :            : {
    7647                 :     286095 :     Py_ssize_t len = PyBytes_GET_SIZE(a->a_linetable);
    7648         [ +  + ]:     286095 :     if (a->a_location_off + THEORETICAL_MAX_ENTRY_SIZE >= len) {
    7649                 :            :         assert(len > THEORETICAL_MAX_ENTRY_SIZE);
    7650         [ -  + ]:      14595 :         RETURN_IF_ERROR(_PyBytes_Resize(&a->a_linetable, len*2));
    7651                 :            :     }
    7652         [ +  + ]:     286095 :     if (loc.lineno < 0) {
    7653                 :       5971 :         write_location_info_none(a, isize);
    7654                 :       5971 :         return SUCCESS;
    7655                 :            :     }
    7656                 :     280124 :     int line_delta = loc.lineno - a->a_lineno;
    7657                 :     280124 :     int column = loc.col_offset;
    7658                 :     280124 :     int end_column = loc.end_col_offset;
    7659                 :            :     assert(column >= -1);
    7660                 :            :     assert(end_column >= -1);
    7661   [ +  +  -  + ]:     280124 :     if (column < 0 || end_column < 0) {
    7662   [ -  +  -  - ]:        532 :         if (loc.end_lineno == loc.lineno || loc.end_lineno == -1) {
    7663                 :        532 :             write_location_info_no_column(a, isize, line_delta);
    7664                 :        532 :             a->a_lineno = loc.lineno;
    7665                 :        532 :             return SUCCESS;
    7666                 :            :         }
    7667                 :            :     }
    7668         [ +  + ]:     279592 :     else if (loc.end_lineno == loc.lineno) {
    7669   [ +  +  +  +  :     254138 :         if (line_delta == 0 && column < 80 && end_column - column < 16 && end_column >= column) {
             +  +  +  - ]
    7670                 :     133188 :             write_location_info_short_form(a, isize, column, end_column);
    7671                 :     133188 :             return SUCCESS;
    7672                 :            :         }
    7673   [ +  +  +  +  :     120950 :         if (line_delta >= 0 && line_delta < 3 && column < 128 && end_column < 128) {
             +  +  +  + ]
    7674                 :     106695 :             write_location_info_oneline_form(a, isize, line_delta, column, end_column);
    7675                 :     106695 :             a->a_lineno = loc.lineno;
    7676                 :     106695 :             return SUCCESS;
    7677                 :            :         }
    7678                 :            :     }
    7679                 :      39709 :     write_location_info_long_form(a, loc, isize);
    7680                 :      39709 :     a->a_lineno = loc.lineno;
    7681                 :      39709 :     return SUCCESS;
    7682                 :            : }
    7683                 :            : 
    7684                 :            : static int
    7685                 :     264465 : assemble_emit_location(struct assembler* a, location loc, int isize)
    7686                 :            : {
    7687         [ +  + ]:     264465 :     if (isize == 0) {
    7688                 :       7033 :         return SUCCESS;
    7689                 :            :     }
    7690         [ +  + ]:     286095 :     while (isize > 8) {
    7691         [ -  + ]:      28663 :         RETURN_IF_ERROR(write_location_info_entry(a, loc, 8));
    7692                 :      28663 :         isize -= 8;
    7693                 :            :     }
    7694                 :     257432 :     return write_location_info_entry(a, loc, isize);
    7695                 :            : }
    7696                 :            : 
    7697                 :            : static int
    7698                 :       8041 : assemble_location_info(struct assembler *a, basicblock *entryblock, int firstlineno)
    7699                 :            : {
    7700                 :       8041 :     a->a_lineno = firstlineno;
    7701                 :       8041 :     location loc = NO_LOCATION;
    7702                 :       8041 :     int size = 0;
    7703         [ +  + ]:      60209 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    7704         [ +  + ]:     394204 :         for (int j = 0; j < b->b_iused; j++) {
    7705         [ +  + ]:     342036 :             if (!same_location(loc, b->b_instr[j].i_loc)) {
    7706         [ -  + ]:     256424 :                 RETURN_IF_ERROR(assemble_emit_location(a, loc, size));
    7707                 :     256424 :                 loc = b->b_instr[j].i_loc;
    7708                 :     256424 :                 size = 0;
    7709                 :            :             }
    7710                 :     342036 :             size += instr_size(&b->b_instr[j]);
    7711                 :            :         }
    7712                 :            :     }
    7713         [ -  + ]:       8041 :     RETURN_IF_ERROR(assemble_emit_location(a, loc, size));
    7714                 :       8041 :     return SUCCESS;
    7715                 :            : }
    7716                 :            : 
    7717                 :            : /* assemble_emit_instr()
    7718                 :            :    Extend the bytecode with a new instruction.
    7719                 :            :    Update lnotab if necessary.
    7720                 :            : */
    7721                 :            : 
    7722                 :            : static int
    7723                 :     342036 : assemble_emit_instr(struct assembler *a, struct cfg_instr *i)
    7724                 :            : {
    7725                 :     342036 :     Py_ssize_t len = PyBytes_GET_SIZE(a->a_bytecode);
    7726                 :            :     _Py_CODEUNIT *code;
    7727                 :            : 
    7728                 :     342036 :     int size = instr_size(i);
    7729         [ +  + ]:     342036 :     if (a->a_offset + size >= len / (int)sizeof(_Py_CODEUNIT)) {
    7730         [ -  + ]:       5892 :         if (len > PY_SSIZE_T_MAX / 2) {
    7731                 :          0 :             return ERROR;
    7732                 :            :         }
    7733         [ -  + ]:       5892 :         RETURN_IF_ERROR(_PyBytes_Resize(&a->a_bytecode, len * 2));
    7734                 :            :     }
    7735                 :     342036 :     code = (_Py_CODEUNIT *)PyBytes_AS_STRING(a->a_bytecode) + a->a_offset;
    7736                 :     342036 :     a->a_offset += size;
    7737                 :     342036 :     write_instr(code, i, size);
    7738                 :     342036 :     return SUCCESS;
    7739                 :            : }
    7740                 :            : 
    7741                 :            : static int merge_const_one(PyObject *const_cache, PyObject **obj);
    7742                 :            : 
    7743                 :            : static int
    7744                 :       8041 : assemble_emit(struct assembler *a, basicblock *entryblock, int first_lineno,
    7745                 :            :               PyObject *const_cache)
    7746                 :            : {
    7747         [ -  + ]:       8041 :     RETURN_IF_ERROR(assemble_init(a, first_lineno));
    7748                 :            : 
    7749         [ +  + ]:      60209 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    7750         [ +  + ]:     394204 :         for (int j = 0; j < b->b_iused; j++) {
    7751         [ -  + ]:     342036 :             RETURN_IF_ERROR(assemble_emit_instr(a, &b->b_instr[j]));
    7752                 :            :         }
    7753                 :            :     }
    7754                 :            : 
    7755         [ -  + ]:       8041 :     RETURN_IF_ERROR(assemble_location_info(a, entryblock, a->a_lineno));
    7756                 :            : 
    7757         [ -  + ]:       8041 :     RETURN_IF_ERROR(assemble_exception_table(a, entryblock));
    7758                 :            : 
    7759         [ -  + ]:       8041 :     RETURN_IF_ERROR(_PyBytes_Resize(&a->a_except_table, a->a_except_table_off));
    7760         [ -  + ]:       8041 :     RETURN_IF_ERROR(merge_const_one(const_cache, &a->a_except_table));
    7761                 :            : 
    7762         [ -  + ]:       8041 :     RETURN_IF_ERROR(_PyBytes_Resize(&a->a_linetable, a->a_location_off));
    7763         [ -  + ]:       8041 :     RETURN_IF_ERROR(merge_const_one(const_cache, &a->a_linetable));
    7764                 :            : 
    7765         [ -  + ]:       8041 :     RETURN_IF_ERROR(_PyBytes_Resize(&a->a_bytecode, a->a_offset * sizeof(_Py_CODEUNIT)));
    7766         [ -  + ]:       8041 :     RETURN_IF_ERROR(merge_const_one(const_cache, &a->a_bytecode));
    7767                 :       8041 :     return SUCCESS;
    7768                 :            : }
    7769                 :            : 
    7770                 :            : static int
    7771                 :      52168 : normalize_jumps_in_block(cfg_builder *g, basicblock *b) {
    7772                 :      52168 :     struct cfg_instr *last = basicblock_last_instr(b);
    7773   [ +  +  +  + ]:      52168 :     if (last == NULL || !is_jump(last)) {
    7774                 :      30617 :         return SUCCESS;
    7775                 :            :     }
    7776                 :            :     assert(!IS_ASSEMBLER_OPCODE(last->i_opcode));
    7777                 :      21551 :     bool is_forward = last->i_target->b_visited == 0;
    7778      [ +  +  + ]:      21551 :     switch(last->i_opcode) {
    7779                 :       5692 :         case JUMP:
    7780         [ +  + ]:       5692 :             last->i_opcode = is_forward ? JUMP_FORWARD : JUMP_BACKWARD;
    7781                 :       5692 :             return SUCCESS;
    7782                 :        190 :         case JUMP_NO_INTERRUPT:
    7783                 :        190 :             last->i_opcode = is_forward ?
    7784         [ -  + ]:        190 :                 JUMP_FORWARD : JUMP_BACKWARD_NO_INTERRUPT;
    7785                 :        190 :             return SUCCESS;
    7786                 :            :     }
    7787                 :      15669 :     int reversed_opcode = 0;
    7788   [ +  +  +  +  :      15669 :     switch(last->i_opcode) {
                   +  + ]
    7789                 :        884 :         case POP_JUMP_IF_NOT_NONE:
    7790                 :        884 :             reversed_opcode = POP_JUMP_IF_NONE;
    7791                 :        884 :             break;
    7792                 :        889 :         case POP_JUMP_IF_NONE:
    7793                 :        889 :             reversed_opcode = POP_JUMP_IF_NOT_NONE;
    7794                 :        889 :             break;
    7795                 :       9096 :         case POP_JUMP_IF_FALSE:
    7796                 :       9096 :             reversed_opcode = POP_JUMP_IF_TRUE;
    7797                 :       9096 :             break;
    7798                 :       2468 :         case POP_JUMP_IF_TRUE:
    7799                 :       2468 :             reversed_opcode = POP_JUMP_IF_FALSE;
    7800                 :       2468 :             break;
    7801                 :        437 :         case JUMP_IF_TRUE_OR_POP:
    7802                 :            :         case JUMP_IF_FALSE_OR_POP:
    7803         [ -  + ]:        437 :             if (!is_forward) {
    7804                 :            :                 /* As far as we can tell, the compiler never emits
    7805                 :            :                  * these jumps with a backwards target. If/when this
    7806                 :            :                  * exception is raised, we have found a use case for
    7807                 :            :                  * a backwards version of this jump (or to replace
    7808                 :            :                  * it with the sequence (COPY 1, POP_JUMP_IF_T/F, POP)
    7809                 :            :                  */
    7810                 :          0 :                 PyErr_Format(PyExc_SystemError,
    7811                 :            :                     "unexpected %s jumping backwards",
    7812         [ #  # ]:          0 :                     last->i_opcode == JUMP_IF_TRUE_OR_POP ?
    7813                 :            :                         "JUMP_IF_TRUE_OR_POP" : "JUMP_IF_FALSE_OR_POP");
    7814                 :            :             }
    7815                 :        437 :             return SUCCESS;
    7816                 :            :     }
    7817         [ +  + ]:      15232 :     if (is_forward) {
    7818                 :      14375 :         return SUCCESS;
    7819                 :            :     }
    7820                 :            : 
    7821                 :            :     /* transform 'conditional jump T' to
    7822                 :            :      * 'reversed_jump b_next' followed by 'jump_backwards T'
    7823                 :            :      */
    7824                 :            : 
    7825                 :        857 :     basicblock *target = last->i_target;
    7826                 :        857 :     basicblock *backwards_jump = cfg_builder_new_block(g);
    7827         [ -  + ]:        857 :     if (backwards_jump == NULL) {
    7828                 :          0 :         return ERROR;
    7829                 :            :     }
    7830                 :        857 :     basicblock_addop(backwards_jump, JUMP, target->b_label.id, NO_LOCATION);
    7831                 :        857 :     backwards_jump->b_instr[0].i_target = target;
    7832                 :        857 :     last->i_opcode = reversed_opcode;
    7833                 :        857 :     last->i_target = b->b_next;
    7834                 :            : 
    7835                 :        857 :     backwards_jump->b_cold = b->b_cold;
    7836                 :        857 :     backwards_jump->b_next = b->b_next;
    7837                 :        857 :     b->b_next = backwards_jump;
    7838                 :        857 :     return SUCCESS;
    7839                 :            : }
    7840                 :            : 
    7841                 :            : static int
    7842                 :       8041 : normalize_jumps(cfg_builder *g)
    7843                 :            : {
    7844                 :       8041 :     basicblock *entryblock = g->g_entryblock;
    7845         [ +  + ]:      59352 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    7846                 :      51311 :         b->b_visited = 0;
    7847                 :            :     }
    7848         [ +  + ]:      60209 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    7849                 :      52168 :         b->b_visited = 1;
    7850         [ -  + ]:      52168 :         RETURN_IF_ERROR(normalize_jumps_in_block(g, b));
    7851                 :            :     }
    7852                 :       8041 :     return SUCCESS;
    7853                 :            : }
    7854                 :            : 
    7855                 :            : static void
    7856                 :       8225 : assemble_jump_offsets(basicblock *entryblock)
    7857                 :            : {
    7858                 :            :     int bsize, totsize, extended_arg_recompile;
    7859                 :            : 
    7860                 :            :     /* Compute the size of each block and fixup jump args.
    7861                 :            :        Replace block pointer with position in bytecode. */
    7862                 :            :     do {
    7863                 :       8225 :         totsize = 0;
    7864         [ +  + ]:      69727 :         for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    7865                 :      61502 :             bsize = blocksize(b);
    7866                 :      61502 :             b->b_offset = totsize;
    7867                 :      61502 :             totsize += bsize;
    7868                 :            :         }
    7869                 :       8225 :         extended_arg_recompile = 0;
    7870         [ +  + ]:      69727 :         for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    7871                 :      61502 :             bsize = b->b_offset;
    7872         [ +  + ]:     465669 :             for (int i = 0; i < b->b_iused; i++) {
    7873                 :     404167 :                 struct cfg_instr *instr = &b->b_instr[i];
    7874                 :     404167 :                 int isize = instr_size(instr);
    7875                 :            :                 /* Relative jumps are computed relative to
    7876                 :            :                    the instruction pointer after fetching
    7877                 :            :                    the jump instruction.
    7878                 :            :                 */
    7879                 :     404167 :                 bsize += isize;
    7880         [ +  + ]:     404167 :                 if (is_jump(instr)) {
    7881                 :      26506 :                     instr->i_oparg = instr->i_target->b_offset;
    7882         [ +  - ]:      26506 :                     if (is_relative_jump(instr)) {
    7883         [ +  + ]:      26506 :                         if (instr->i_oparg < bsize) {
    7884                 :            :                             assert(IS_BACKWARDS_JUMP_OPCODE(instr->i_opcode));
    7885                 :       5048 :                             instr->i_oparg = bsize - instr->i_oparg;
    7886                 :            :                         }
    7887                 :            :                         else {
    7888                 :            :                             assert(!IS_BACKWARDS_JUMP_OPCODE(instr->i_opcode));
    7889                 :      21458 :                             instr->i_oparg -= bsize;
    7890                 :            :                         }
    7891                 :            :                     }
    7892                 :            :                     else {
    7893                 :            :                         assert(!IS_BACKWARDS_JUMP_OPCODE(instr->i_opcode));
    7894                 :            :                     }
    7895         [ +  + ]:      26506 :                     if (instr_size(instr) != isize) {
    7896                 :        647 :                         extended_arg_recompile = 1;
    7897                 :            :                     }
    7898                 :            :                 }
    7899                 :            :             }
    7900                 :            :         }
    7901                 :            : 
    7902                 :            :     /* XXX: This is an awful hack that could hurt performance, but
    7903                 :            :         on the bright side it should work until we come up
    7904                 :            :         with a better solution.
    7905                 :            : 
    7906                 :            :         The issue is that in the first loop blocksize() is called
    7907                 :            :         which calls instr_size() which requires i_oparg be set
    7908                 :            :         appropriately. There is a bootstrap problem because
    7909                 :            :         i_oparg is calculated in the second loop above.
    7910                 :            : 
    7911                 :            :         So we loop until we stop seeing new EXTENDED_ARGs.
    7912                 :            :         The only EXTENDED_ARGs that could be popping up are
    7913                 :            :         ones in jump instructions.  So this should converge
    7914                 :            :         fairly quickly.
    7915                 :            :     */
    7916         [ +  + ]:       8225 :     } while (extended_arg_recompile);
    7917                 :       8041 : }
    7918                 :            : 
    7919                 :            : 
    7920                 :            : // helper functions for add_checks_for_loads_of_unknown_variables
    7921                 :            : static inline void
    7922                 :     204644 : maybe_push(basicblock *b, uint64_t unsafe_mask, basicblock ***sp)
    7923                 :            : {
    7924                 :            :     // Push b if the unsafe mask is giving us any new information.
    7925                 :            :     // To avoid overflowing the stack, only allow each block once.
    7926                 :            :     // Use b->b_visited=1 to mean that b is currently on the stack.
    7927                 :     204644 :     uint64_t both = b->b_unsafe_locals_mask | unsafe_mask;
    7928         [ +  + ]:     204644 :     if (b->b_unsafe_locals_mask != both) {
    7929                 :      33427 :         b->b_unsafe_locals_mask = both;
    7930                 :            :         // More work left to do.
    7931         [ +  + ]:      33427 :         if (!b->b_visited) {
    7932                 :            :             // not on the stack, so push it.
    7933                 :      33175 :             *(*sp)++ = b;
    7934                 :      33175 :             b->b_visited = 1;
    7935                 :            :         }
    7936                 :            :     }
    7937                 :     204644 : }
    7938                 :            : 
    7939                 :            : static void
    7940                 :      80806 : scan_block_for_locals(basicblock *b, basicblock ***sp)
    7941                 :            : {
    7942                 :            :     // bit i is set if local i is potentially uninitialized
    7943                 :      80806 :     uint64_t unsafe_mask = b->b_unsafe_locals_mask;
    7944         [ +  + ]:     549175 :     for (int i = 0; i < b->b_iused; i++) {
    7945                 :     468369 :         struct cfg_instr *instr = &b->b_instr[i];
    7946                 :            :         assert(instr->i_opcode != EXTENDED_ARG);
    7947                 :            :         assert(!IS_SUPERINSTRUCTION_OPCODE(instr->i_opcode));
    7948         [ +  + ]:     468369 :         if (instr->i_except != NULL) {
    7949                 :     114747 :             maybe_push(instr->i_except, unsafe_mask, sp);
    7950                 :            :         }
    7951         [ +  + ]:     468369 :         if (instr->i_oparg >= 64) {
    7952                 :       3041 :             continue;
    7953                 :            :         }
    7954                 :            :         assert(instr->i_oparg >= 0);
    7955                 :     465328 :         uint64_t bit = (uint64_t)1 << instr->i_oparg;
    7956   [ +  +  +  +  :     465328 :         switch (instr->i_opcode) {
                      + ]
    7957                 :        817 :             case DELETE_FAST:
    7958                 :        817 :                 unsafe_mask |= bit;
    7959                 :        817 :                 break;
    7960                 :      29474 :             case STORE_FAST:
    7961                 :      29474 :                 unsafe_mask &= ~bit;
    7962                 :      29474 :                 break;
    7963                 :        157 :             case LOAD_FAST_CHECK:
    7964                 :            :                 // If this doesn't raise, then the local is defined.
    7965                 :        157 :                 unsafe_mask &= ~bit;
    7966                 :        157 :                 break;
    7967                 :      94654 :             case LOAD_FAST:
    7968         [ +  + ]:      94654 :                 if (unsafe_mask & bit) {
    7969                 :        157 :                     instr->i_opcode = LOAD_FAST_CHECK;
    7970                 :            :                 }
    7971                 :      94654 :                 unsafe_mask &= ~bit;
    7972                 :      94654 :                 break;
    7973                 :            :         }
    7974                 :     468369 :     }
    7975   [ +  +  +  + ]:      80806 :     if (b->b_next && BB_HAS_FALLTHROUGH(b)) {
    7976                 :      46996 :         maybe_push(b->b_next, unsafe_mask, sp);
    7977                 :            :     }
    7978                 :      80806 :     struct cfg_instr *last = basicblock_last_instr(b);
    7979   [ +  -  +  + ]:      80806 :     if (last && is_jump(last)) {
    7980                 :            :         assert(last->i_target != NULL);
    7981                 :      36062 :         maybe_push(last->i_target, unsafe_mask, sp);
    7982                 :            :     }
    7983                 :      80806 : }
    7984                 :            : 
    7985                 :            : static int
    7986                 :          0 : fast_scan_many_locals(basicblock *entryblock, int nlocals)
    7987                 :            : {
    7988                 :            :     assert(nlocals > 64);
    7989                 :          0 :     Py_ssize_t *states = PyMem_Calloc(nlocals - 64, sizeof(Py_ssize_t));
    7990         [ #  # ]:          0 :     if (states == NULL) {
    7991                 :          0 :         PyErr_NoMemory();
    7992                 :          0 :         return ERROR;
    7993                 :            :     }
    7994                 :          0 :     Py_ssize_t blocknum = 0;
    7995                 :            :     // state[i - 64] == blocknum if local i is guaranteed to
    7996                 :            :     // be initialized, i.e., if it has had a previous LOAD_FAST or
    7997                 :            :     // STORE_FAST within that basicblock (not followed by DELETE_FAST).
    7998         [ #  # ]:          0 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    7999                 :          0 :         blocknum++;
    8000         [ #  # ]:          0 :         for (int i = 0; i < b->b_iused; i++) {
    8001                 :          0 :             struct cfg_instr *instr = &b->b_instr[i];
    8002                 :            :             assert(instr->i_opcode != EXTENDED_ARG);
    8003                 :            :             assert(!IS_SUPERINSTRUCTION_OPCODE(instr->i_opcode));
    8004                 :          0 :             int arg = instr->i_oparg;
    8005         [ #  # ]:          0 :             if (arg < 64) {
    8006                 :          0 :                 continue;
    8007                 :            :             }
    8008                 :            :             assert(arg >= 0);
    8009   [ #  #  #  # ]:          0 :             switch (instr->i_opcode) {
    8010                 :          0 :                 case DELETE_FAST:
    8011                 :          0 :                     states[arg - 64] = blocknum - 1;
    8012                 :          0 :                     break;
    8013                 :          0 :                 case STORE_FAST:
    8014                 :          0 :                     states[arg - 64] = blocknum;
    8015                 :          0 :                     break;
    8016                 :          0 :                 case LOAD_FAST:
    8017         [ #  # ]:          0 :                     if (states[arg - 64] != blocknum) {
    8018                 :          0 :                         instr->i_opcode = LOAD_FAST_CHECK;
    8019                 :            :                     }
    8020                 :          0 :                     states[arg - 64] = blocknum;
    8021                 :          0 :                     break;
    8022                 :            :                 case LOAD_FAST_CHECK:
    8023                 :            :                     Py_UNREACHABLE();
    8024                 :            :             }
    8025                 :          0 :         }
    8026                 :            :     }
    8027                 :          0 :     PyMem_Free(states);
    8028                 :          0 :     return SUCCESS;
    8029                 :            : }
    8030                 :            : 
    8031                 :            : static int
    8032                 :       8041 : add_checks_for_loads_of_uninitialized_variables(basicblock *entryblock,
    8033                 :            :                                                 int nlocals,
    8034                 :            :                                                 int nparams)
    8035                 :            : {
    8036         [ +  + ]:       8041 :     if (nlocals == 0) {
    8037                 :       1202 :         return SUCCESS;
    8038                 :            :     }
    8039         [ -  + ]:       6839 :     if (nlocals > 64) {
    8040                 :            :         // To avoid O(nlocals**2) compilation, locals beyond the first
    8041                 :            :         // 64 are only analyzed one basicblock at a time: initialization
    8042                 :            :         // info is not passed between basicblocks.
    8043         [ #  # ]:          0 :         if (fast_scan_many_locals(entryblock, nlocals) < 0) {
    8044                 :          0 :             return ERROR;
    8045                 :            :         }
    8046                 :          0 :         nlocals = 64;
    8047                 :            :     }
    8048                 :       6839 :     basicblock **stack = make_cfg_traversal_stack(entryblock);
    8049         [ -  + ]:       6839 :     if (stack == NULL) {
    8050                 :          0 :         return ERROR;
    8051                 :            :     }
    8052                 :       6839 :     basicblock **sp = stack;
    8053                 :            : 
    8054                 :            :     // First origin of being uninitialized:
    8055                 :            :     // The non-parameter locals in the entry block.
    8056                 :       6839 :     uint64_t start_mask = 0;
    8057         [ +  + ]:      16575 :     for (int i = nparams; i < nlocals; i++) {
    8058                 :       9736 :         start_mask |= (uint64_t)1 << i;
    8059                 :            :     }
    8060                 :       6839 :     maybe_push(entryblock, start_mask, &sp);
    8061                 :            : 
    8062                 :            :     // Second origin of being uninitialized:
    8063                 :            :     // There could be DELETE_FAST somewhere, so
    8064                 :            :     // be sure to scan each basicblock at least once.
    8065         [ +  + ]:      54470 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    8066                 :      47631 :         scan_block_for_locals(b, &sp);
    8067                 :            :     }
    8068                 :            : 
    8069                 :            :     // Now propagate the uncertainty from the origins we found: Use
    8070                 :            :     // LOAD_FAST_CHECK for any LOAD_FAST where the local could be undefined.
    8071         [ +  + ]:      40014 :     while (sp > stack) {
    8072                 :      33175 :         basicblock *b = *--sp;
    8073                 :            :         // mark as no longer on stack
    8074                 :      33175 :         b->b_visited = 0;
    8075                 :      33175 :         scan_block_for_locals(b, &sp);
    8076                 :            :     }
    8077                 :       6839 :     PyMem_Free(stack);
    8078                 :       6839 :     return SUCCESS;
    8079                 :            : }
    8080                 :            : 
    8081                 :            : static PyObject *
    8082                 :       8041 : dict_keys_inorder(PyObject *dict, Py_ssize_t offset)
    8083                 :            : {
    8084                 :            :     PyObject *tuple, *k, *v;
    8085                 :       8041 :     Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict);
    8086                 :            : 
    8087                 :       8041 :     tuple = PyTuple_New(size);
    8088         [ -  + ]:       8041 :     if (tuple == NULL)
    8089                 :          0 :         return NULL;
    8090         [ +  + ]:      58190 :     while (PyDict_Next(dict, &pos, &k, &v)) {
    8091                 :      50149 :         i = PyLong_AS_LONG(v);
    8092                 :            :         assert((i - offset) < size);
    8093                 :            :         assert((i - offset) >= 0);
    8094                 :      50149 :         PyTuple_SET_ITEM(tuple, i - offset, Py_NewRef(k));
    8095                 :            :     }
    8096                 :       8041 :     return tuple;
    8097                 :            : }
    8098                 :            : 
    8099                 :            : static PyObject *
    8100                 :       8041 : consts_dict_keys_inorder(PyObject *dict)
    8101                 :            : {
    8102                 :            :     PyObject *consts, *k, *v;
    8103                 :       8041 :     Py_ssize_t i, pos = 0, size = PyDict_GET_SIZE(dict);
    8104                 :            : 
    8105                 :       8041 :     consts = PyList_New(size);   /* PyCode_Optimize() requires a list */
    8106         [ -  + ]:       8041 :     if (consts == NULL)
    8107                 :          0 :         return NULL;
    8108         [ +  + ]:      50324 :     while (PyDict_Next(dict, &pos, &k, &v)) {
    8109                 :      42283 :         i = PyLong_AS_LONG(v);
    8110                 :            :         /* The keys of the dictionary can be tuples wrapping a constant.
    8111                 :            :          * (see dict_add_o and _PyCode_ConstantKey). In that case
    8112                 :            :          * the object we want is always second. */
    8113         [ +  + ]:      42283 :         if (PyTuple_CheckExact(k)) {
    8114                 :       4446 :             k = PyTuple_GET_ITEM(k, 1);
    8115                 :            :         }
    8116                 :            :         assert(i < size);
    8117                 :            :         assert(i >= 0);
    8118                 :      42283 :         PyList_SET_ITEM(consts, i, Py_NewRef(k));
    8119                 :            :     }
    8120                 :       8041 :     return consts;
    8121                 :            : }
    8122                 :            : 
    8123                 :            : static int
    8124                 :       8041 : compute_code_flags(struct compiler *c)
    8125                 :            : {
    8126                 :       8041 :     PySTEntryObject *ste = c->u->u_ste;
    8127                 :       8041 :     int flags = 0;
    8128         [ +  + ]:       8041 :     if (ste->ste_type == FunctionBlock) {
    8129                 :       6989 :         flags |= CO_NEWLOCALS | CO_OPTIMIZED;
    8130         [ +  + ]:       6989 :         if (ste->ste_nested)
    8131                 :        758 :             flags |= CO_NESTED;
    8132   [ +  +  +  + ]:       6989 :         if (ste->ste_generator && !ste->ste_coroutine)
    8133                 :        374 :             flags |= CO_GENERATOR;
    8134   [ +  +  +  + ]:       6989 :         if (!ste->ste_generator && ste->ste_coroutine)
    8135                 :        155 :             flags |= CO_COROUTINE;
    8136   [ +  +  +  + ]:       6989 :         if (ste->ste_generator && ste->ste_coroutine)
    8137                 :          3 :             flags |= CO_ASYNC_GENERATOR;
    8138         [ +  + ]:       6989 :         if (ste->ste_varargs)
    8139                 :        309 :             flags |= CO_VARARGS;
    8140         [ +  + ]:       6989 :         if (ste->ste_varkeywords)
    8141                 :        216 :             flags |= CO_VARKEYWORDS;
    8142                 :            :     }
    8143                 :            : 
    8144                 :            :     /* (Only) inherit compilerflags in PyCF_MASK */
    8145                 :       8041 :     flags |= (c->c_flags.cf_flags & PyCF_MASK);
    8146                 :            : 
    8147   [ -  +  -  -  :       8041 :     if ((IS_TOP_LEVEL_AWAIT(c)) &&
                   -  - ]
    8148                 :          0 :          ste->ste_coroutine &&
    8149         [ #  # ]:          0 :          !ste->ste_generator) {
    8150                 :          0 :         flags |= CO_COROUTINE;
    8151                 :            :     }
    8152                 :            : 
    8153                 :       8041 :     return flags;
    8154                 :            : }
    8155                 :            : 
    8156                 :            : // Merge *obj* with constant cache.
    8157                 :            : // Unlike merge_consts_recursive(), this function doesn't work recursively.
    8158                 :            : static int
    8159                 :      49146 : merge_const_one(PyObject *const_cache, PyObject **obj)
    8160                 :            : {
    8161                 :            :     assert(PyDict_CheckExact(const_cache));
    8162                 :      49146 :     PyObject *key = _PyCode_ConstantKey(*obj);
    8163         [ -  + ]:      49146 :     if (key == NULL) {
    8164                 :          0 :         return ERROR;
    8165                 :            :     }
    8166                 :            : 
    8167                 :            :     // t is borrowed reference
    8168                 :      49146 :     PyObject *t = PyDict_SetDefault(const_cache, key, key);
    8169                 :      49146 :     Py_DECREF(key);
    8170         [ -  + ]:      49146 :     if (t == NULL) {
    8171                 :          0 :         return ERROR;
    8172                 :            :     }
    8173         [ +  + ]:      49146 :     if (t == key) {  // obj is new constant.
    8174                 :      33484 :         return SUCCESS;
    8175                 :            :     }
    8176                 :            : 
    8177         [ +  - ]:      15662 :     if (PyTuple_CheckExact(t)) {
    8178                 :            :         // t is still borrowed reference
    8179                 :      15662 :         t = PyTuple_GET_ITEM(t, 1);
    8180                 :            :     }
    8181                 :            : 
    8182                 :      15662 :     Py_SETREF(*obj, Py_NewRef(t));
    8183                 :      15662 :     return SUCCESS;
    8184                 :            : }
    8185                 :            : 
    8186                 :            : // This is in codeobject.c.
    8187                 :            : extern void _Py_set_localsplus_info(int, PyObject *, unsigned char,
    8188                 :            :                                    PyObject *, PyObject *);
    8189                 :            : 
    8190                 :            : static void
    8191                 :       8041 : compute_localsplus_info(struct compiler_unit *u, int nlocalsplus,
    8192                 :            :                         PyObject *names, PyObject *kinds)
    8193                 :            : {
    8194                 :            :     PyObject *k, *v;
    8195                 :       8041 :     Py_ssize_t pos = 0;
    8196         [ +  + ]:      31750 :     while (PyDict_Next(u->u_varnames, &pos, &k, &v)) {
    8197                 :      23709 :         int offset = (int)PyLong_AS_LONG(v);
    8198                 :            :         assert(offset >= 0);
    8199                 :            :         assert(offset < nlocalsplus);
    8200                 :            :         // For now we do not distinguish arg kinds.
    8201                 :      23709 :         _PyLocals_Kind kind = CO_FAST_LOCAL;
    8202         [ +  + ]:      23709 :         if (PyDict_GetItem(u->u_cellvars, k) != NULL) {
    8203                 :        303 :             kind |= CO_FAST_CELL;
    8204                 :            :         }
    8205                 :      23709 :         _Py_set_localsplus_info(offset, k, kind, names, kinds);
    8206                 :            :     }
    8207                 :       8041 :     int nlocals = (int)PyDict_GET_SIZE(u->u_varnames);
    8208                 :            : 
    8209                 :            :     // This counter mirrors the fix done in fix_cell_offsets().
    8210                 :       8041 :     int numdropped = 0;
    8211                 :       8041 :     pos = 0;
    8212         [ +  + ]:       8740 :     while (PyDict_Next(u->u_cellvars, &pos, &k, &v)) {
    8213         [ +  + ]:        699 :         if (PyDict_GetItem(u->u_varnames, k) != NULL) {
    8214                 :            :             // Skip cells that are already covered by locals.
    8215                 :        303 :             numdropped += 1;
    8216                 :        303 :             continue;
    8217                 :            :         }
    8218                 :        396 :         int offset = (int)PyLong_AS_LONG(v);
    8219                 :            :         assert(offset >= 0);
    8220                 :        396 :         offset += nlocals - numdropped;
    8221                 :            :         assert(offset < nlocalsplus);
    8222                 :        396 :         _Py_set_localsplus_info(offset, k, CO_FAST_CELL, names, kinds);
    8223                 :            :     }
    8224                 :            : 
    8225                 :       8041 :     pos = 0;
    8226         [ +  + ]:       8979 :     while (PyDict_Next(u->u_freevars, &pos, &k, &v)) {
    8227                 :        938 :         int offset = (int)PyLong_AS_LONG(v);
    8228                 :            :         assert(offset >= 0);
    8229                 :        938 :         offset += nlocals - numdropped;
    8230                 :            :         assert(offset < nlocalsplus);
    8231                 :        938 :         _Py_set_localsplus_info(offset, k, CO_FAST_FREE, names, kinds);
    8232                 :            :     }
    8233                 :       8041 : }
    8234                 :            : 
    8235                 :            : static PyCodeObject *
    8236                 :       8041 : makecode(struct compiler_unit *u, struct assembler *a, PyObject *const_cache,
    8237                 :            :          PyObject *constslist, int maxdepth, int nlocalsplus, int code_flags,
    8238                 :            :          PyObject *filename)
    8239                 :            : {
    8240                 :       8041 :     PyCodeObject *co = NULL;
    8241                 :       8041 :     PyObject *names = NULL;
    8242                 :       8041 :     PyObject *consts = NULL;
    8243                 :       8041 :     PyObject *localsplusnames = NULL;
    8244                 :       8041 :     PyObject *localspluskinds = NULL;
    8245                 :       8041 :     names = dict_keys_inorder(u->u_names, 0);
    8246         [ -  + ]:       8041 :     if (!names) {
    8247                 :          0 :         goto error;
    8248                 :            :     }
    8249         [ -  + ]:       8041 :     if (merge_const_one(const_cache, &names) < 0) {
    8250                 :          0 :         goto error;
    8251                 :            :     }
    8252                 :            : 
    8253                 :       8041 :     consts = PyList_AsTuple(constslist); /* PyCode_New requires a tuple */
    8254         [ -  + ]:       8041 :     if (consts == NULL) {
    8255                 :          0 :         goto error;
    8256                 :            :     }
    8257         [ -  + ]:       8041 :     if (merge_const_one(const_cache, &consts) < 0) {
    8258                 :          0 :         goto error;
    8259                 :            :     }
    8260                 :            : 
    8261                 :            :     assert(u->u_posonlyargcount < INT_MAX);
    8262                 :            :     assert(u->u_argcount < INT_MAX);
    8263                 :            :     assert(u->u_kwonlyargcount < INT_MAX);
    8264                 :       8041 :     int posonlyargcount = (int)u->u_posonlyargcount;
    8265                 :       8041 :     int posorkwargcount = (int)u->u_argcount;
    8266                 :            :     assert(INT_MAX - posonlyargcount - posorkwargcount > 0);
    8267                 :       8041 :     int kwonlyargcount = (int)u->u_kwonlyargcount;
    8268                 :            : 
    8269                 :       8041 :     localsplusnames = PyTuple_New(nlocalsplus);
    8270         [ -  + ]:       8041 :     if (localsplusnames == NULL) {
    8271                 :          0 :         goto error;
    8272                 :            :     }
    8273                 :       8041 :     localspluskinds = PyBytes_FromStringAndSize(NULL, nlocalsplus);
    8274         [ -  + ]:       8041 :     if (localspluskinds == NULL) {
    8275                 :          0 :         goto error;
    8276                 :            :     }
    8277                 :       8041 :     compute_localsplus_info(u, nlocalsplus, localsplusnames, localspluskinds);
    8278                 :            : 
    8279                 :      16082 :     struct _PyCodeConstructor con = {
    8280                 :            :         .filename = filename,
    8281                 :       8041 :         .name = u->u_name,
    8282         [ +  + ]:       8041 :         .qualname = u->u_qualname ? u->u_qualname : u->u_name,
    8283                 :            :         .flags = code_flags,
    8284                 :            : 
    8285                 :       8041 :         .code = a->a_bytecode,
    8286                 :       8041 :         .firstlineno = u->u_firstlineno,
    8287                 :       8041 :         .linetable = a->a_linetable,
    8288                 :            : 
    8289                 :            :         .consts = consts,
    8290                 :            :         .names = names,
    8291                 :            : 
    8292                 :            :         .localsplusnames = localsplusnames,
    8293                 :            :         .localspluskinds = localspluskinds,
    8294                 :            : 
    8295                 :       8041 :         .argcount = posonlyargcount + posorkwargcount,
    8296                 :            :         .posonlyargcount = posonlyargcount,
    8297                 :            :         .kwonlyargcount = kwonlyargcount,
    8298                 :            : 
    8299                 :            :         .stacksize = maxdepth,
    8300                 :            : 
    8301                 :       8041 :         .exceptiontable = a->a_except_table,
    8302                 :            :     };
    8303                 :            : 
    8304         [ -  + ]:       8041 :     if (_PyCode_Validate(&con) < 0) {
    8305                 :          0 :         goto error;
    8306                 :            :     }
    8307                 :            : 
    8308         [ -  + ]:       8041 :     if (merge_const_one(const_cache, &localsplusnames) < 0) {
    8309                 :          0 :         goto error;
    8310                 :            :     }
    8311                 :       8041 :     con.localsplusnames = localsplusnames;
    8312                 :            : 
    8313                 :       8041 :     co = _PyCode_New(&con);
    8314         [ +  - ]:       8041 :     if (co == NULL) {
    8315                 :          0 :         goto error;
    8316                 :            :     }
    8317                 :            : 
    8318                 :       8041 :  error:
    8319                 :       8041 :     Py_XDECREF(names);
    8320                 :       8041 :     Py_XDECREF(consts);
    8321                 :       8041 :     Py_XDECREF(localsplusnames);
    8322                 :       8041 :     Py_XDECREF(localspluskinds);
    8323                 :       8041 :     return co;
    8324                 :            : }
    8325                 :            : 
    8326                 :            : 
    8327                 :            : /* For debugging purposes only */
    8328                 :            : #if 0
    8329                 :            : static void
    8330                 :            : dump_instr(struct cfg_instr *i)
    8331                 :            : {
    8332                 :            :     const char *jrel = (is_relative_jump(i)) ? "jrel " : "";
    8333                 :            :     const char *jabs = (is_jump(i) && !is_relative_jump(i))? "jabs " : "";
    8334                 :            : 
    8335                 :            :     char arg[128];
    8336                 :            : 
    8337                 :            :     *arg = '\0';
    8338                 :            :     if (HAS_ARG(i->i_opcode)) {
    8339                 :            :         sprintf(arg, "arg: %d ", i->i_oparg);
    8340                 :            :     }
    8341                 :            :     if (HAS_TARGET(i->i_opcode)) {
    8342                 :            :         sprintf(arg, "target: %p [%d] ", i->i_target, i->i_oparg);
    8343                 :            :     }
    8344                 :            :     fprintf(stderr, "line: %d, opcode: %d %s%s%s\n",
    8345                 :            :                     i->i_loc.lineno, i->i_opcode, arg, jabs, jrel);
    8346                 :            : }
    8347                 :            : 
    8348                 :            : static inline int
    8349                 :            : basicblock_returns(const basicblock *b) {
    8350                 :            :     struct cfg_instr *last = basicblock_last_instr(b);
    8351                 :            :     return last && (last->i_opcode == RETURN_VALUE || last->i_opcode == RETURN_CONST);
    8352                 :            : }
    8353                 :            : 
    8354                 :            : static void
    8355                 :            : dump_basicblock(const basicblock *b)
    8356                 :            : {
    8357                 :            :     const char *b_return = basicblock_returns(b) ? "return " : "";
    8358                 :            :     fprintf(stderr, "%d: [EH=%d CLD=%d WRM=%d NO_FT=%d %p] used: %d, depth: %d, offset: %d %s\n",
    8359                 :            :         b->b_label.id, b->b_except_handler, b->b_cold, b->b_warm, BB_NO_FALLTHROUGH(b), b, b->b_iused,
    8360                 :            :         b->b_startdepth, b->b_offset, b_return);
    8361                 :            :     if (b->b_instr) {
    8362                 :            :         int i;
    8363                 :            :         for (i = 0; i < b->b_iused; i++) {
    8364                 :            :             fprintf(stderr, "  [%02d] ", i);
    8365                 :            :             dump_instr(b->b_instr + i);
    8366                 :            :         }
    8367                 :            :     }
    8368                 :            : }
    8369                 :            : #endif
    8370                 :            : 
    8371                 :            : 
    8372                 :            : static int
    8373                 :            : translate_jump_labels_to_targets(basicblock *entryblock);
    8374                 :            : 
    8375                 :            : static int
    8376                 :            : optimize_cfg(cfg_builder *g, PyObject *consts, PyObject *const_cache);
    8377                 :            : 
    8378                 :            : static int
    8379                 :            : remove_unused_consts(basicblock *entryblock, PyObject *consts);
    8380                 :            : 
    8381                 :            : /* Duplicates exit BBs, so that line numbers can be propagated to them */
    8382                 :            : static int
    8383                 :            : duplicate_exits_without_lineno(cfg_builder *g);
    8384                 :            : 
    8385                 :            : static int *
    8386                 :       8041 : build_cellfixedoffsets(struct compiler_unit *u)
    8387                 :            : {
    8388                 :       8041 :     int nlocals = (int)PyDict_GET_SIZE(u->u_varnames);
    8389                 :       8041 :     int ncellvars = (int)PyDict_GET_SIZE(u->u_cellvars);
    8390                 :       8041 :     int nfreevars = (int)PyDict_GET_SIZE(u->u_freevars);
    8391                 :            : 
    8392                 :       8041 :     int noffsets = ncellvars + nfreevars;
    8393         [ +  - ]:       8041 :     int *fixed = PyMem_New(int, noffsets);
    8394         [ -  + ]:       8041 :     if (fixed == NULL) {
    8395                 :          0 :         PyErr_NoMemory();
    8396                 :          0 :         return NULL;
    8397                 :            :     }
    8398         [ +  + ]:       9678 :     for (int i = 0; i < noffsets; i++) {
    8399                 :       1637 :         fixed[i] = nlocals + i;
    8400                 :            :     }
    8401                 :            : 
    8402                 :            :     PyObject *varname, *cellindex;
    8403                 :       8041 :     Py_ssize_t pos = 0;
    8404         [ +  + ]:       8740 :     while (PyDict_Next(u->u_cellvars, &pos, &varname, &cellindex)) {
    8405                 :        699 :         PyObject *varindex = PyDict_GetItem(u->u_varnames, varname);
    8406         [ +  + ]:        699 :         if (varindex != NULL) {
    8407                 :            :             assert(PyLong_AS_LONG(cellindex) < INT_MAX);
    8408                 :            :             assert(PyLong_AS_LONG(varindex) < INT_MAX);
    8409                 :        303 :             int oldindex = (int)PyLong_AS_LONG(cellindex);
    8410                 :        303 :             int argoffset = (int)PyLong_AS_LONG(varindex);
    8411                 :        303 :             fixed[oldindex] = argoffset;
    8412                 :            :         }
    8413                 :            :     }
    8414                 :            : 
    8415                 :       8041 :     return fixed;
    8416                 :            : }
    8417                 :            : 
    8418                 :            : static int
    8419                 :       8041 : insert_prefix_instructions(struct compiler_unit *u, basicblock *entryblock,
    8420                 :            :                            int *fixed, int nfreevars, int code_flags)
    8421                 :            : {
    8422                 :            :     assert(u->u_firstlineno > 0);
    8423                 :            : 
    8424                 :            :     /* Add the generator prefix instructions. */
    8425         [ +  + ]:       8041 :     if (code_flags & (CO_GENERATOR | CO_COROUTINE | CO_ASYNC_GENERATOR)) {
    8426                 :        532 :         struct cfg_instr make_gen = {
    8427                 :            :             .i_opcode = RETURN_GENERATOR,
    8428                 :            :             .i_oparg = 0,
    8429                 :        532 :             .i_loc = LOCATION(u->u_firstlineno, u->u_firstlineno, -1, -1),
    8430                 :            :             .i_target = NULL,
    8431                 :            :         };
    8432         [ -  + ]:        532 :         RETURN_IF_ERROR(insert_instruction(entryblock, 0, &make_gen));
    8433                 :        532 :         struct cfg_instr pop_top = {
    8434                 :            :             .i_opcode = POP_TOP,
    8435                 :            :             .i_oparg = 0,
    8436                 :            :             .i_loc = NO_LOCATION,
    8437                 :            :             .i_target = NULL,
    8438                 :            :         };
    8439         [ -  + ]:        532 :         RETURN_IF_ERROR(insert_instruction(entryblock, 1, &pop_top));
    8440                 :            :     }
    8441                 :            : 
    8442                 :            :     /* Set up cells for any variable that escapes, to be put in a closure. */
    8443                 :       8041 :     const int ncellvars = (int)PyDict_GET_SIZE(u->u_cellvars);
    8444         [ +  + ]:       8041 :     if (ncellvars) {
    8445                 :            :         // u->u_cellvars has the cells out of order so we sort them
    8446                 :            :         // before adding the MAKE_CELL instructions.  Note that we
    8447                 :            :         // adjust for arg cells, which come first.
    8448                 :        399 :         const int nvars = ncellvars + (int)PyDict_GET_SIZE(u->u_varnames);
    8449                 :        399 :         int *sorted = PyMem_RawCalloc(nvars, sizeof(int));
    8450         [ -  + ]:        399 :         if (sorted == NULL) {
    8451                 :          0 :             PyErr_NoMemory();
    8452                 :          0 :             return ERROR;
    8453                 :            :         }
    8454         [ +  + ]:       1098 :         for (int i = 0; i < ncellvars; i++) {
    8455                 :        699 :             sorted[fixed[i]] = i + 1;
    8456                 :            :         }
    8457         [ +  + ]:       2146 :         for (int i = 0, ncellsused = 0; ncellsused < ncellvars; i++) {
    8458                 :       1747 :             int oldindex = sorted[i] - 1;
    8459         [ +  + ]:       1747 :             if (oldindex == -1) {
    8460                 :       1048 :                 continue;
    8461                 :            :             }
    8462                 :        699 :             struct cfg_instr make_cell = {
    8463                 :            :                 .i_opcode = MAKE_CELL,
    8464                 :            :                 // This will get fixed in offset_derefs().
    8465                 :            :                 .i_oparg = oldindex,
    8466                 :            :                 .i_loc = NO_LOCATION,
    8467                 :            :                 .i_target = NULL,
    8468                 :            :             };
    8469         [ -  + ]:        699 :             RETURN_IF_ERROR(insert_instruction(entryblock, ncellsused, &make_cell));
    8470                 :        699 :             ncellsused += 1;
    8471                 :            :         }
    8472                 :        399 :         PyMem_RawFree(sorted);
    8473                 :            :     }
    8474                 :            : 
    8475         [ +  + ]:       8041 :     if (nfreevars) {
    8476                 :        627 :         struct cfg_instr copy_frees = {
    8477                 :            :             .i_opcode = COPY_FREE_VARS,
    8478                 :            :             .i_oparg = nfreevars,
    8479                 :            :             .i_loc = NO_LOCATION,
    8480                 :            :             .i_target = NULL,
    8481                 :            :         };
    8482         [ -  + ]:        627 :         RETURN_IF_ERROR(insert_instruction(entryblock, 0, &copy_frees));
    8483                 :            :     }
    8484                 :            : 
    8485                 :       8041 :     return SUCCESS;
    8486                 :            : }
    8487                 :            : 
    8488                 :            : /* Make sure that all returns have a line number, even if early passes
    8489                 :            :  * have failed to propagate a correct line number.
    8490                 :            :  * The resulting line number may not be correct according to PEP 626,
    8491                 :            :  * but should be "good enough", and no worse than in older versions. */
    8492                 :            : static void
    8493                 :       8041 : guarantee_lineno_for_exits(basicblock *entryblock, int firstlineno) {
    8494                 :       8041 :     int lineno = firstlineno;
    8495                 :            :     assert(lineno > 0);
    8496         [ +  + ]:      59352 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    8497                 :      51311 :         struct cfg_instr *last = basicblock_last_instr(b);
    8498         [ -  + ]:      51311 :         if (last == NULL) {
    8499                 :          0 :             continue;
    8500                 :            :         }
    8501         [ +  + ]:      51311 :         if (last->i_loc.lineno < 0) {
    8502         [ -  + ]:       2747 :             if (last->i_opcode == RETURN_VALUE) {
    8503         [ #  # ]:          0 :                 for (int i = 0; i < b->b_iused; i++) {
    8504                 :            :                     assert(b->b_instr[i].i_loc.lineno < 0);
    8505                 :            : 
    8506                 :          0 :                     b->b_instr[i].i_loc.lineno = lineno;
    8507                 :            :                 }
    8508                 :            :             }
    8509                 :            :         }
    8510                 :            :         else {
    8511                 :      48564 :             lineno = last->i_loc.lineno;
    8512                 :            :         }
    8513                 :            :     }
    8514                 :       8041 : }
    8515                 :            : 
    8516                 :            : static int
    8517                 :       8041 : fix_cell_offsets(struct compiler_unit *u, basicblock *entryblock, int *fixedmap)
    8518                 :            : {
    8519                 :       8041 :     int nlocals = (int)PyDict_GET_SIZE(u->u_varnames);
    8520                 :       8041 :     int ncellvars = (int)PyDict_GET_SIZE(u->u_cellvars);
    8521                 :       8041 :     int nfreevars = (int)PyDict_GET_SIZE(u->u_freevars);
    8522                 :       8041 :     int noffsets = ncellvars + nfreevars;
    8523                 :            : 
    8524                 :            :     // First deal with duplicates (arg cells).
    8525                 :       8041 :     int numdropped = 0;
    8526         [ +  + ]:       9678 :     for (int i = 0; i < noffsets ; i++) {
    8527         [ +  + ]:       1637 :         if (fixedmap[i] == i + nlocals) {
    8528                 :       1334 :             fixedmap[i] -= numdropped;
    8529                 :            :         }
    8530                 :            :         else {
    8531                 :            :             // It was a duplicate (cell/arg).
    8532                 :        303 :             numdropped += 1;
    8533                 :            :         }
    8534                 :            :     }
    8535                 :            : 
    8536                 :            :     // Then update offsets, either relative to locals or by cell2arg.
    8537         [ +  + ]:      59352 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    8538         [ +  + ]:     400486 :         for (int i = 0; i < b->b_iused; i++) {
    8539                 :     349175 :             struct cfg_instr *inst = &b->b_instr[i];
    8540                 :            :             // This is called before extended args are generated.
    8541                 :            :             assert(inst->i_opcode != EXTENDED_ARG);
    8542                 :     349175 :             int oldoffset = inst->i_oparg;
    8543         [ +  + ]:     349175 :             switch(inst->i_opcode) {
    8544                 :       4195 :                 case MAKE_CELL:
    8545                 :            :                 case LOAD_CLOSURE:
    8546                 :            :                 case LOAD_DEREF:
    8547                 :            :                 case STORE_DEREF:
    8548                 :            :                 case DELETE_DEREF:
    8549                 :            :                 case LOAD_CLASSDEREF:
    8550                 :            :                     assert(oldoffset >= 0);
    8551                 :            :                     assert(oldoffset < noffsets);
    8552                 :            :                     assert(fixedmap[oldoffset] >= 0);
    8553                 :       4195 :                     inst->i_oparg = fixedmap[oldoffset];
    8554                 :            :             }
    8555                 :            :         }
    8556                 :            :     }
    8557                 :            : 
    8558                 :       8041 :     return numdropped;
    8559                 :            : }
    8560                 :            : 
    8561                 :            : 
    8562                 :            : #ifndef NDEBUG
    8563                 :            : 
    8564                 :            : static bool
    8565                 :            : no_redundant_nops(cfg_builder *g) {
    8566                 :            :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
    8567                 :            :         if (remove_redundant_nops(b) != 0) {
    8568                 :            :             return false;
    8569                 :            :         }
    8570                 :            :     }
    8571                 :            :     return true;
    8572                 :            : }
    8573                 :            : 
    8574                 :            : static bool
    8575                 :            : no_redundant_jumps(cfg_builder *g) {
    8576                 :            :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
    8577                 :            :         struct cfg_instr *last = basicblock_last_instr(b);
    8578                 :            :         if (last != NULL) {
    8579                 :            :             if (IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) {
    8580                 :            :                 assert(last->i_target != b->b_next);
    8581                 :            :                 if (last->i_target == b->b_next) {
    8582                 :            :                     return false;
    8583                 :            :                 }
    8584                 :            :             }
    8585                 :            :         }
    8586                 :            :     }
    8587                 :            :     return true;
    8588                 :            : }
    8589                 :            : 
    8590                 :            : static bool
    8591                 :            : opcode_metadata_is_sane(cfg_builder *g) {
    8592                 :            :     bool result = true;
    8593                 :            :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
    8594                 :            :         for (int i = 0; i < b->b_iused; i++) {
    8595                 :            :             struct cfg_instr *instr = &b->b_instr[i];
    8596                 :            :             int opcode = instr->i_opcode;
    8597                 :            :             int oparg = instr->i_oparg;
    8598                 :            :             assert(opcode <= MAX_REAL_OPCODE);
    8599                 :            :             for (int jump = 0; jump <= 1; jump++) {
    8600                 :            :                 int popped = _PyOpcode_num_popped(opcode, oparg, jump ? true : false);
    8601                 :            :                 int pushed = _PyOpcode_num_pushed(opcode, oparg, jump ? true : false);
    8602                 :            :                 assert((pushed < 0) == (popped < 0));
    8603                 :            :                 if (pushed >= 0) {
    8604                 :            :                     assert(_PyOpcode_opcode_metadata[opcode].valid_entry);
    8605                 :            :                     int effect = stack_effect(opcode, instr->i_oparg, jump);
    8606                 :            :                     if (effect != pushed - popped) {
    8607                 :            :                        fprintf(stderr,
    8608                 :            :                                "op=%d arg=%d jump=%d: stack_effect (%d) != pushed (%d) - popped (%d)\n",
    8609                 :            :                                opcode, oparg, jump, effect, pushed, popped);
    8610                 :            :                        result = false;
    8611                 :            :                     }
    8612                 :            :                 }
    8613                 :            :             }
    8614                 :            :         }
    8615                 :            :     }
    8616                 :            :     return result;
    8617                 :            : }
    8618                 :            : 
    8619                 :            : static bool
    8620                 :            : no_empty_basic_blocks(cfg_builder *g) {
    8621                 :            :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
    8622                 :            :         if (b->b_iused == 0) {
    8623                 :            :             return false;
    8624                 :            :         }
    8625                 :            :     }
    8626                 :            :     return true;
    8627                 :            : }
    8628                 :            : #endif
    8629                 :            : 
    8630                 :            : static int
    8631                 :       9640 : remove_redundant_jumps(cfg_builder *g) {
    8632                 :            :     /* If a non-empty block ends with a jump instruction, check if the next
    8633                 :            :      * non-empty block reached through normal flow control is the target
    8634                 :            :      * of that jump. If it is, then the jump instruction is redundant and
    8635                 :            :      * can be deleted.
    8636                 :            :      */
    8637                 :            :     assert(no_empty_basic_blocks(g));
    8638         [ +  + ]:      87571 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
    8639                 :      77931 :         struct cfg_instr *last = basicblock_last_instr(b);
    8640                 :            :         assert(last != NULL);
    8641                 :            :         assert(!IS_ASSEMBLER_OPCODE(last->i_opcode));
    8642   [ +  +  +  +  :      77931 :         if (IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) {
          +  -  +  -  -  
                      + ]
    8643         [ -  + ]:       9591 :             if (last->i_target == NULL) {
    8644                 :          0 :                 PyErr_SetString(PyExc_SystemError, "jump with NULL target");
    8645                 :          0 :                 return ERROR;
    8646                 :            :             }
    8647         [ +  + ]:       9591 :             if (last->i_target == b->b_next) {
    8648                 :            :                 assert(b->b_next->b_iused);
    8649                 :        871 :                 INSTR_SET_OP0(last, NOP);
    8650                 :            :             }
    8651                 :            :         }
    8652                 :            :     }
    8653                 :       9640 :     return SUCCESS;
    8654                 :            : }
    8655                 :            : 
    8656                 :            : static int
    8657                 :       8041 : prepare_localsplus(struct compiler_unit* u, cfg_builder *g, int code_flags)
    8658                 :            : {
    8659                 :            :     assert(PyDict_GET_SIZE(u->u_varnames) < INT_MAX);
    8660                 :            :     assert(PyDict_GET_SIZE(u->u_cellvars) < INT_MAX);
    8661                 :            :     assert(PyDict_GET_SIZE(u->u_freevars) < INT_MAX);
    8662                 :       8041 :     int nlocals = (int)PyDict_GET_SIZE(u->u_varnames);
    8663                 :       8041 :     int ncellvars = (int)PyDict_GET_SIZE(u->u_cellvars);
    8664                 :       8041 :     int nfreevars = (int)PyDict_GET_SIZE(u->u_freevars);
    8665                 :            :     assert(INT_MAX - nlocals - ncellvars > 0);
    8666                 :            :     assert(INT_MAX - nlocals - ncellvars - nfreevars > 0);
    8667                 :       8041 :     int nlocalsplus = nlocals + ncellvars + nfreevars;
    8668                 :       8041 :     int* cellfixedoffsets = build_cellfixedoffsets(u);
    8669         [ -  + ]:       8041 :     if (cellfixedoffsets == NULL) {
    8670                 :          0 :         return ERROR;
    8671                 :            :     }
    8672                 :            : 
    8673                 :            : 
    8674                 :            :     // This must be called before fix_cell_offsets().
    8675         [ -  + ]:       8041 :     if (insert_prefix_instructions(u, g->g_entryblock, cellfixedoffsets, nfreevars, code_flags)) {
    8676                 :          0 :         PyMem_Free(cellfixedoffsets);
    8677                 :          0 :         return ERROR;
    8678                 :            :     }
    8679                 :            : 
    8680                 :       8041 :     int numdropped = fix_cell_offsets(u, g->g_entryblock, cellfixedoffsets);
    8681                 :       8041 :     PyMem_Free(cellfixedoffsets);  // At this point we're done with it.
    8682                 :       8041 :     cellfixedoffsets = NULL;
    8683         [ -  + ]:       8041 :     if (numdropped < 0) {
    8684                 :          0 :         return ERROR;
    8685                 :            :     }
    8686                 :            : 
    8687                 :       8041 :     nlocalsplus -= numdropped;
    8688                 :       8041 :     return nlocalsplus;
    8689                 :            : }
    8690                 :            : 
    8691                 :            : static int
    8692                 :       8041 : add_return_at_end(struct compiler *c, int addNone)
    8693                 :            : {
    8694                 :            :     /* Make sure every instruction stream that falls off the end returns None.
    8695                 :            :      * This also ensures that no jump target offsets are out of bounds.
    8696                 :            :      */
    8697         [ +  + ]:       8041 :     if (addNone) {
    8698         [ -  + ]:       7982 :         ADDOP_LOAD_CONST(c, NO_LOCATION, Py_None);
    8699                 :            :     }
    8700         [ -  + ]:       8041 :     ADDOP(c, NO_LOCATION, RETURN_VALUE);
    8701                 :       8041 :     return SUCCESS;
    8702                 :            : }
    8703                 :            : 
    8704                 :            : static void propagate_line_numbers(basicblock *entryblock);
    8705                 :            : 
    8706                 :            : static int
    8707                 :       8041 : resolve_line_numbers(struct compiler_unit *u, cfg_builder *g)
    8708                 :            : {
    8709                 :            :     /* Set firstlineno if it wasn't explicitly set. */
    8710         [ -  + ]:       8041 :     if (!u->u_firstlineno) {
    8711   [ #  #  #  # ]:          0 :         if (g->g_entryblock->b_instr && g->g_entryblock->b_instr->i_loc.lineno) {
    8712                 :          0 :             u->u_firstlineno = g->g_entryblock->b_instr->i_loc.lineno;
    8713                 :            :         }
    8714                 :            :         else {
    8715                 :          0 :             u->u_firstlineno = 1;
    8716                 :            :         }
    8717                 :            :     }
    8718         [ -  + ]:       8041 :     RETURN_IF_ERROR(duplicate_exits_without_lineno(g));
    8719                 :       8041 :     propagate_line_numbers(g->g_entryblock);
    8720                 :       8041 :     guarantee_lineno_for_exits(g->g_entryblock, u->u_firstlineno);
    8721                 :       8041 :     return SUCCESS;
    8722                 :            : }
    8723                 :            : 
    8724                 :            : static int
    8725                 :       8041 : optimize_code_unit(cfg_builder *g, PyObject *consts, PyObject *const_cache,
    8726                 :            :                    int code_flags, int nlocals, int nparams)
    8727                 :            : {
    8728                 :            :     assert(cfg_builder_check(g));
    8729                 :            :     /** Preprocessing **/
    8730                 :            :     /* Map labels to targets and mark exception handlers */
    8731         [ -  + ]:       8041 :     RETURN_IF_ERROR(translate_jump_labels_to_targets(g->g_entryblock));
    8732         [ -  + ]:       8041 :     RETURN_IF_ERROR(mark_except_handlers(g->g_entryblock));
    8733         [ -  + ]:       8041 :     RETURN_IF_ERROR(label_exception_targets(g->g_entryblock));
    8734                 :            : 
    8735                 :            :     /** Optimization **/
    8736         [ -  + ]:       8041 :     RETURN_IF_ERROR(optimize_cfg(g, consts, const_cache));
    8737         [ -  + ]:       8041 :     RETURN_IF_ERROR(remove_unused_consts(g->g_entryblock, consts));
    8738         [ -  + ]:       8041 :     RETURN_IF_ERROR(
    8739                 :            :         add_checks_for_loads_of_uninitialized_variables(
    8740                 :            :             g->g_entryblock, nlocals, nparams));
    8741                 :            : 
    8742         [ -  + ]:       8041 :     RETURN_IF_ERROR(push_cold_blocks_to_end(g, code_flags));
    8743                 :       8041 :     return SUCCESS;
    8744                 :            : }
    8745                 :            : 
    8746                 :            : static PyCodeObject *
    8747                 :       8041 : assemble_code_unit(struct compiler_unit *u, PyObject *const_cache,
    8748                 :            :                    int code_flags, PyObject *filename)
    8749                 :            : {
    8750                 :       8041 :     PyCodeObject *co = NULL;
    8751                 :       8041 :     PyObject *consts = consts_dict_keys_inorder(u->u_consts);
    8752         [ -  + ]:       8041 :     if (consts == NULL) {
    8753                 :          0 :         goto error;
    8754                 :            :     }
    8755                 :            :     cfg_builder g;
    8756         [ -  + ]:       8041 :     if (instr_sequence_to_cfg(&u->u_instr_sequence, &g) < 0) {
    8757                 :          0 :         goto error;
    8758                 :            :     }
    8759                 :       8041 :     int nparams = (int)PyList_GET_SIZE(u->u_ste->ste_varnames);
    8760                 :       8041 :     int nlocals = (int)PyDict_GET_SIZE(u->u_varnames);
    8761         [ -  + ]:       8041 :     if (optimize_code_unit(&g, consts, const_cache, code_flags, nlocals, nparams) < 0) {
    8762                 :          0 :         goto error;
    8763                 :            :     }
    8764                 :            : 
    8765                 :            :     /** Assembly **/
    8766                 :            : 
    8767         [ -  + ]:       8041 :     if (resolve_line_numbers(u, &g) < 0) {
    8768                 :          0 :         goto error;
    8769                 :            :     }
    8770                 :            : 
    8771                 :       8041 :     int nlocalsplus = prepare_localsplus(u, &g, code_flags);
    8772         [ -  + ]:       8041 :     if (nlocalsplus < 0) {
    8773                 :          0 :         goto error;
    8774                 :            :     }
    8775                 :            : 
    8776                 :       8041 :     int maxdepth = stackdepth(g.g_entryblock, code_flags);
    8777         [ -  + ]:       8041 :     if (maxdepth < 0) {
    8778                 :          0 :         goto error;
    8779                 :            :     }
    8780                 :            :     /* TO DO -- For 3.12, make sure that `maxdepth <= MAX_ALLOWED_STACK_USE` */
    8781                 :            : 
    8782                 :       8041 :     convert_exception_handlers_to_nops(g.g_entryblock);
    8783                 :            : 
    8784                 :            :     /* Order of basic blocks must have been determined by now */
    8785         [ -  + ]:       8041 :     if (normalize_jumps(&g) < 0) {
    8786                 :          0 :         goto error;
    8787                 :            :     }
    8788                 :            :     assert(no_redundant_jumps(&g));
    8789                 :            :     assert(opcode_metadata_is_sane(&g));
    8790                 :            : 
    8791                 :            :     /* Can't modify the bytecode after computing jump offsets. */
    8792                 :       8041 :     assemble_jump_offsets(g.g_entryblock);
    8793                 :            : 
    8794                 :            :     struct assembler a;
    8795                 :       8041 :     int res = assemble_emit(&a, g.g_entryblock, u->u_firstlineno, const_cache);
    8796         [ +  - ]:       8041 :     if (res == SUCCESS) {
    8797                 :       8041 :         co = makecode(u, &a, const_cache, consts, maxdepth, nlocalsplus,
    8798                 :            :                       code_flags, filename);
    8799                 :            :     }
    8800                 :       8041 :     assemble_free(&a);
    8801                 :            : 
    8802                 :       8041 :  error:
    8803                 :       8041 :     Py_XDECREF(consts);
    8804                 :       8041 :     cfg_builder_fini(&g);
    8805                 :       8041 :     return co;
    8806                 :            : }
    8807                 :            : 
    8808                 :            : static PyCodeObject *
    8809                 :       8041 : assemble(struct compiler *c, int addNone)
    8810                 :            : {
    8811                 :       8041 :     struct compiler_unit *u = c->u;
    8812                 :       8041 :     PyObject *const_cache = c->c_const_cache;
    8813                 :       8041 :     PyObject *filename = c->c_filename;
    8814                 :            : 
    8815                 :       8041 :     int code_flags = compute_code_flags(c);
    8816         [ -  + ]:       8041 :     if (code_flags < 0) {
    8817                 :          0 :         return NULL;
    8818                 :            :     }
    8819                 :            : 
    8820         [ -  + ]:       8041 :     if (add_return_at_end(c, addNone) < 0) {
    8821                 :          0 :         return NULL;
    8822                 :            :     }
    8823                 :            : 
    8824                 :       8041 :     return assemble_code_unit(u, const_cache, code_flags, filename);
    8825                 :            : }
    8826                 :            : 
    8827                 :            : static PyObject*
    8828                 :       3579 : get_const_value(int opcode, int oparg, PyObject *co_consts)
    8829                 :            : {
    8830                 :       3579 :     PyObject *constant = NULL;
    8831                 :            :     assert(HAS_CONST(opcode));
    8832         [ +  - ]:       3579 :     if (opcode == LOAD_CONST) {
    8833                 :       3579 :         constant = PyList_GET_ITEM(co_consts, oparg);
    8834                 :            :     }
    8835                 :            : 
    8836         [ -  + ]:       3579 :     if (constant == NULL) {
    8837                 :          0 :         PyErr_SetString(PyExc_SystemError,
    8838                 :            :                         "Internal error: failed to get value of a constant");
    8839                 :          0 :         return NULL;
    8840                 :            :     }
    8841                 :       3579 :     return Py_NewRef(constant);
    8842                 :            : }
    8843                 :            : 
    8844                 :            : /* Replace LOAD_CONST c1, LOAD_CONST c2 ... LOAD_CONST cn, BUILD_TUPLE n
    8845                 :            :    with    LOAD_CONST (c1, c2, ... cn).
    8846                 :            :    The consts table must still be in list form so that the
    8847                 :            :    new constant (c1, c2, ... cn) can be appended.
    8848                 :            :    Called with codestr pointing to the first LOAD_CONST.
    8849                 :            : */
    8850                 :            : static int
    8851                 :       3656 : fold_tuple_on_constants(PyObject *const_cache,
    8852                 :            :                         struct cfg_instr *inst,
    8853                 :            :                         int n, PyObject *consts)
    8854                 :            : {
    8855                 :            :     /* Pre-conditions */
    8856                 :            :     assert(PyDict_CheckExact(const_cache));
    8857                 :            :     assert(PyList_CheckExact(consts));
    8858                 :            :     assert(inst[n].i_opcode == BUILD_TUPLE);
    8859                 :            :     assert(inst[n].i_oparg == n);
    8860                 :            : 
    8861         [ +  + ]:       5606 :     for (int i = 0; i < n; i++) {
    8862   [ +  +  +  -  :       4706 :         if (!HAS_CONST(inst[i].i_opcode)) {
                   +  + ]
    8863                 :       2756 :             return SUCCESS;
    8864                 :            :         }
    8865                 :            :     }
    8866                 :            : 
    8867                 :            :     /* Buildup new tuple of constants */
    8868                 :        900 :     PyObject *newconst = PyTuple_New(n);
    8869         [ -  + ]:        900 :     if (newconst == NULL) {
    8870                 :          0 :         return ERROR;
    8871                 :            :     }
    8872         [ +  + ]:       2412 :     for (int i = 0; i < n; i++) {
    8873                 :       1512 :         int op = inst[i].i_opcode;
    8874                 :       1512 :         int arg = inst[i].i_oparg;
    8875                 :       1512 :         PyObject *constant = get_const_value(op, arg, consts);
    8876         [ -  + ]:       1512 :         if (constant == NULL) {
    8877                 :          0 :             return ERROR;
    8878                 :            :         }
    8879                 :       1512 :         PyTuple_SET_ITEM(newconst, i, constant);
    8880                 :            :     }
    8881         [ -  + ]:        900 :     if (merge_const_one(const_cache, &newconst) < 0) {
    8882                 :          0 :         Py_DECREF(newconst);
    8883                 :          0 :         return ERROR;
    8884                 :            :     }
    8885                 :            : 
    8886                 :            :     Py_ssize_t index;
    8887         [ +  + ]:      60079 :     for (index = 0; index < PyList_GET_SIZE(consts); index++) {
    8888         [ +  + ]:      59427 :         if (PyList_GET_ITEM(consts, index) == newconst) {
    8889                 :        248 :             break;
    8890                 :            :         }
    8891                 :            :     }
    8892         [ +  + ]:        900 :     if (index == PyList_GET_SIZE(consts)) {
    8893         [ -  + ]:        652 :         if ((size_t)index >= (size_t)INT_MAX - 1) {
    8894                 :          0 :             Py_DECREF(newconst);
    8895                 :          0 :             PyErr_SetString(PyExc_OverflowError, "too many constants");
    8896                 :          0 :             return ERROR;
    8897                 :            :         }
    8898         [ -  + ]:        652 :         if (PyList_Append(consts, newconst)) {
    8899                 :          0 :             Py_DECREF(newconst);
    8900                 :          0 :             return ERROR;
    8901                 :            :         }
    8902                 :            :     }
    8903                 :        900 :     Py_DECREF(newconst);
    8904         [ +  + ]:       2412 :     for (int i = 0; i < n; i++) {
    8905                 :       1512 :         INSTR_SET_OP0(&inst[i], NOP);
    8906                 :            :     }
    8907                 :        900 :     INSTR_SET_OP1(&inst[n], LOAD_CONST, (int)index);
    8908                 :        900 :     return SUCCESS;
    8909                 :            : }
    8910                 :            : 
    8911                 :            : #define VISITED (-1)
    8912                 :            : 
    8913                 :            : // Replace an arbitrary run of SWAPs and NOPs with an optimal one that has the
    8914                 :            : // same effect.
    8915                 :            : static int
    8916                 :        774 : swaptimize(basicblock *block, int *ix)
    8917                 :            : {
    8918                 :            :     // NOTE: "./python -m test test_patma" serves as a good, quick stress test
    8919                 :            :     // for this function. Make sure to blow away cached *.pyc files first!
    8920                 :            :     assert(*ix < block->b_iused);
    8921                 :        774 :     struct cfg_instr *instructions = &block->b_instr[*ix];
    8922                 :            :     // Find the length of the current sequence of SWAPs and NOPs, and record the
    8923                 :            :     // maximum depth of the stack manipulations:
    8924                 :            :     assert(instructions[0].i_opcode == SWAP);
    8925                 :        774 :     int depth = instructions[0].i_oparg;
    8926                 :        774 :     int len = 0;
    8927                 :        774 :     int more = false;
    8928                 :        774 :     int limit = block->b_iused - *ix;
    8929         [ +  - ]:        792 :     while (++len < limit) {
    8930                 :        792 :         int opcode = instructions[len].i_opcode;
    8931         [ +  + ]:        792 :         if (opcode == SWAP) {
    8932                 :         18 :             depth = Py_MAX(depth, instructions[len].i_oparg);
    8933                 :         18 :             more = true;
    8934                 :            :         }
    8935         [ +  - ]:        774 :         else if (opcode != NOP) {
    8936                 :        774 :             break;
    8937                 :            :         }
    8938                 :            :     }
    8939                 :            :     // It's already optimal if there's only one SWAP:
    8940         [ +  + ]:        774 :     if (!more) {
    8941                 :        756 :         return SUCCESS;
    8942                 :            :     }
    8943                 :            :     // Create an array with elements {0, 1, 2, ..., depth - 1}:
    8944                 :         18 :     int *stack = PyMem_Malloc(depth * sizeof(int));
    8945         [ -  + ]:         18 :     if (stack == NULL) {
    8946                 :          0 :         PyErr_NoMemory();
    8947                 :          0 :         return ERROR;
    8948                 :            :     }
    8949         [ +  + ]:         72 :     for (int i = 0; i < depth; i++) {
    8950                 :         54 :         stack[i] = i;
    8951                 :            :     }
    8952                 :            :     // Simulate the combined effect of these instructions by "running" them on
    8953                 :            :     // our "stack":
    8954         [ +  + ]:         54 :     for (int i = 0; i < len; i++) {
    8955         [ +  - ]:         36 :         if (instructions[i].i_opcode == SWAP) {
    8956                 :         36 :             int oparg = instructions[i].i_oparg;
    8957                 :         36 :             int top = stack[0];
    8958                 :            :             // SWAPs are 1-indexed:
    8959                 :         36 :             stack[0] = stack[oparg - 1];
    8960                 :         36 :             stack[oparg - 1] = top;
    8961                 :            :         }
    8962                 :            :     }
    8963                 :            :     // Now we can begin! Our approach here is based on a solution to a closely
    8964                 :            :     // related problem (https://cs.stackexchange.com/a/13938). It's easiest to
    8965                 :            :     // think of this algorithm as determining the steps needed to efficiently
    8966                 :            :     // "un-shuffle" our stack. By performing the moves in *reverse* order,
    8967                 :            :     // though, we can efficiently *shuffle* it! For this reason, we will be
    8968                 :            :     // replacing instructions starting from the *end* of the run. Since the
    8969                 :            :     // solution is optimal, we don't need to worry about running out of space:
    8970                 :         18 :     int current = len - 1;
    8971         [ +  + ]:         72 :     for (int i = 0; i < depth; i++) {
    8972                 :            :         // Skip items that have already been visited, or just happen to be in
    8973                 :            :         // the correct location:
    8974   [ +  +  -  + ]:         54 :         if (stack[i] == VISITED || stack[i] == i) {
    8975                 :         36 :             continue;
    8976                 :            :         }
    8977                 :            :         // Okay, we've found an item that hasn't been visited. It forms a cycle
    8978                 :            :         // with other items; traversing the cycle and swapping each item with
    8979                 :            :         // the next will put them all in the correct place. The weird
    8980                 :            :         // loop-and-a-half is necessary to insert 0 into every cycle, since we
    8981                 :            :         // can only swap from that position:
    8982                 :         18 :         int j = i;
    8983                 :         54 :         while (true) {
    8984                 :            :             // Skip the actual swap if our item is zero, since swapping the top
    8985                 :            :             // item with itself is pointless:
    8986         [ +  + ]:         72 :             if (j) {
    8987                 :            :                 assert(0 <= current);
    8988                 :            :                 // SWAPs are 1-indexed:
    8989                 :         36 :                 instructions[current].i_opcode = SWAP;
    8990                 :         36 :                 instructions[current--].i_oparg = j + 1;
    8991                 :            :             }
    8992         [ +  + ]:         72 :             if (stack[j] == VISITED) {
    8993                 :            :                 // Completed the cycle:
    8994                 :            :                 assert(j == i);
    8995                 :         18 :                 break;
    8996                 :            :             }
    8997                 :         54 :             int next_j = stack[j];
    8998                 :         54 :             stack[j] = VISITED;
    8999                 :         54 :             j = next_j;
    9000                 :            :         }
    9001                 :            :     }
    9002                 :            :     // NOP out any unused instructions:
    9003         [ -  + ]:         18 :     while (0 <= current) {
    9004                 :          0 :         INSTR_SET_OP0(&instructions[current--], NOP);
    9005                 :            :     }
    9006                 :         18 :     PyMem_Free(stack);
    9007                 :         18 :     *ix += len - 1;
    9008                 :         18 :     return SUCCESS;
    9009                 :            : }
    9010                 :            : 
    9011                 :            : // This list is pretty small, since it's only okay to reorder opcodes that:
    9012                 :            : // - can't affect control flow (like jumping or raising exceptions)
    9013                 :            : // - can't invoke arbitrary code (besides finalizers)
    9014                 :            : // - only touch the TOS (and pop it when finished)
    9015                 :            : #define SWAPPABLE(opcode) \
    9016                 :            :     ((opcode) == STORE_FAST || (opcode) == POP_TOP)
    9017                 :            : 
    9018                 :            : static int
    9019                 :       1174 : next_swappable_instruction(basicblock *block, int i, int lineno)
    9020                 :            : {
    9021         [ +  + ]:       1174 :     while (++i < block->b_iused) {
    9022                 :       1170 :         struct cfg_instr *instruction = &block->b_instr[i];
    9023   [ +  +  +  + ]:       1170 :         if (0 <= lineno && instruction->i_loc.lineno != lineno) {
    9024                 :            :             // Optimizing across this instruction could cause user-visible
    9025                 :            :             // changes in the names bound between line tracing events!
    9026                 :        120 :             return -1;
    9027                 :            :         }
    9028         [ -  + ]:       1050 :         if (instruction->i_opcode == NOP) {
    9029                 :          0 :             continue;
    9030                 :            :         }
    9031   [ +  +  +  + ]:       1050 :         if (SWAPPABLE(instruction->i_opcode)) {
    9032                 :        528 :             return i;
    9033                 :            :         }
    9034                 :        522 :         return -1;
    9035                 :            :     }
    9036                 :          4 :     return -1;
    9037                 :            : }
    9038                 :            : 
    9039                 :            : // Attempt to apply SWAPs statically by swapping *instructions* rather than
    9040                 :            : // stack items. For example, we can replace SWAP(2), POP_TOP, STORE_FAST(42)
    9041                 :            : // with the more efficient NOP, STORE_FAST(42), POP_TOP.
    9042                 :            : static void
    9043                 :        774 : apply_static_swaps(basicblock *block, int i)
    9044                 :            : {
    9045                 :            :     // SWAPs are to our left, and potential swaperands are to our right:
    9046         [ +  + ]:       1002 :     for (; 0 <= i; i--) {
    9047                 :            :         assert(i < block->b_iused);
    9048                 :        974 :         struct cfg_instr *swap = &block->b_instr[i];
    9049         [ +  + ]:        974 :         if (swap->i_opcode != SWAP) {
    9050   [ +  +  +  -  :        200 :             if (swap->i_opcode == NOP || SWAPPABLE(swap->i_opcode)) {
                   -  + ]
    9051                 :            :                 // Nope, but we know how to handle these. Keep looking:
    9052                 :        100 :                 continue;
    9053                 :            :             }
    9054                 :            :             // We can't reason about what this instruction does. Bail:
    9055                 :        746 :             return;
    9056                 :            :         }
    9057                 :        774 :         int j = next_swappable_instruction(block, i, -1);
    9058         [ +  + ]:        774 :         if (j < 0) {
    9059                 :        390 :             return;
    9060                 :            :         }
    9061                 :        384 :         int k = j;
    9062                 :        384 :         int lineno = block->b_instr[j].i_loc.lineno;
    9063         [ +  + ]:        528 :         for (int count = swap->i_oparg - 1; 0 < count; count--) {
    9064                 :        400 :             k = next_swappable_instruction(block, k, lineno);
    9065         [ +  + ]:        400 :             if (k < 0) {
    9066                 :        256 :                 return;
    9067                 :            :             }
    9068                 :            :         }
    9069                 :            :         // Success!
    9070                 :        128 :         INSTR_SET_OP0(swap, NOP);
    9071                 :        128 :         struct cfg_instr temp = block->b_instr[j];
    9072                 :        128 :         block->b_instr[j] = block->b_instr[k];
    9073                 :        128 :         block->b_instr[k] = temp;
    9074                 :            :     }
    9075                 :            : }
    9076                 :            : 
    9077                 :            : // Attempt to eliminate jumps to jumps by updating inst to jump to
    9078                 :            : // target->i_target using the provided opcode. Return whether or not the
    9079                 :            : // optimization was successful.
    9080                 :            : static bool
    9081                 :       1741 : jump_thread(struct cfg_instr *inst, struct cfg_instr *target, int opcode)
    9082                 :            : {
    9083                 :            :     assert(is_jump(inst));
    9084                 :            :     assert(is_jump(target));
    9085                 :            :     // bpo-45773: If inst->i_target == target->i_target, then nothing actually
    9086                 :            :     // changes (and we fall into an infinite loop):
    9087   [ +  +  +  + ]:       1741 :     if ((inst->i_loc.lineno == target->i_loc.lineno || target->i_loc.lineno == -1) &&
    9088         [ +  - ]:       1686 :         inst->i_target != target->i_target)
    9089                 :            :     {
    9090                 :       1686 :         inst->i_target = target->i_target;
    9091                 :       1686 :         inst->i_opcode = opcode;
    9092                 :       1686 :         return true;
    9093                 :            :     }
    9094                 :         55 :     return false;
    9095                 :            : }
    9096                 :            : 
    9097                 :            : /* Maximum size of basic block that should be copied in optimizer */
    9098                 :            : #define MAX_COPY_SIZE 4
    9099                 :            : 
    9100                 :            : /* Optimization */
    9101                 :            : static int
    9102                 :      58917 : optimize_basic_block(PyObject *const_cache, basicblock *bb, PyObject *consts)
    9103                 :            : {
    9104                 :            :     assert(PyDict_CheckExact(const_cache));
    9105                 :            :     assert(PyList_CheckExact(consts));
    9106                 :            :     struct cfg_instr nop;
    9107                 :      58917 :     INSTR_SET_OP0(&nop, NOP);
    9108                 :            :     struct cfg_instr *target;
    9109         [ +  + ]:     439462 :     for (int i = 0; i < bb->b_iused; i++) {
    9110                 :     380545 :         struct cfg_instr *inst = &bb->b_instr[i];
    9111                 :     380545 :         int oparg = inst->i_oparg;
    9112         [ +  + ]:     380545 :         int nextop = i+1 < bb->b_iused ? bb->b_instr[i+1].i_opcode : 0;
    9113   [ +  +  +  +  :     380545 :         if (HAS_TARGET(inst->i_opcode)) {
             +  +  +  + ]
    9114                 :            :             assert(inst->i_target->b_iused > 0);
    9115                 :      29208 :             target = &inst->i_target->b_instr[0];
    9116                 :      29208 :             assert(!IS_ASSEMBLER_OPCODE(target->i_opcode));
    9117                 :            :         }
    9118                 :            :         else {
    9119                 :     351337 :             target = &nop;
    9120                 :            :         }
    9121                 :            :         assert(!IS_ASSEMBLER_OPCODE(inst->i_opcode));
    9122   [ +  +  +  +  :     380545 :         switch (inst->i_opcode) {
          +  +  +  +  +  
             +  +  +  + ]
    9123                 :            :             /* Remove LOAD_CONST const; conditional jump */
    9124   [ +  -  +  +  :      59096 :             case LOAD_CONST:
                      + ]
    9125                 :            :             {
    9126                 :            :                 PyObject* cnt;
    9127                 :            :                 int is_true;
    9128                 :            :                 int jump_if_true;
    9129                 :            :                 switch(nextop) {
    9130                 :        225 :                     case POP_JUMP_IF_FALSE:
    9131                 :            :                     case POP_JUMP_IF_TRUE:
    9132                 :        225 :                         cnt = get_const_value(inst->i_opcode, oparg, consts);
    9133         [ -  + ]:        225 :                         if (cnt == NULL) {
    9134                 :          0 :                             goto error;
    9135                 :            :                         }
    9136                 :        225 :                         is_true = PyObject_IsTrue(cnt);
    9137                 :        225 :                         Py_DECREF(cnt);
    9138         [ -  + ]:        225 :                         if (is_true == -1) {
    9139                 :          0 :                             goto error;
    9140                 :            :                         }
    9141                 :        225 :                         INSTR_SET_OP0(inst, NOP);
    9142                 :        225 :                         jump_if_true = nextop == POP_JUMP_IF_TRUE;
    9143         [ +  + ]:        225 :                         if (is_true == jump_if_true) {
    9144                 :        111 :                             bb->b_instr[i+1].i_opcode = JUMP;
    9145                 :            :                         }
    9146                 :            :                         else {
    9147                 :        114 :                             INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
    9148                 :            :                         }
    9149                 :        225 :                         break;
    9150                 :          0 :                     case JUMP_IF_FALSE_OR_POP:
    9151                 :            :                     case JUMP_IF_TRUE_OR_POP:
    9152                 :          0 :                         cnt = get_const_value(inst->i_opcode, oparg, consts);
    9153         [ #  # ]:          0 :                         if (cnt == NULL) {
    9154                 :          0 :                             goto error;
    9155                 :            :                         }
    9156                 :          0 :                         is_true = PyObject_IsTrue(cnt);
    9157                 :          0 :                         Py_DECREF(cnt);
    9158         [ #  # ]:          0 :                         if (is_true == -1) {
    9159                 :          0 :                             goto error;
    9160                 :            :                         }
    9161                 :          0 :                         jump_if_true = nextop == JUMP_IF_TRUE_OR_POP;
    9162         [ #  # ]:          0 :                         if (is_true == jump_if_true) {
    9163                 :          0 :                             bb->b_instr[i+1].i_opcode = JUMP;
    9164                 :            :                         }
    9165                 :            :                         else {
    9166                 :          0 :                             INSTR_SET_OP0(inst, NOP);
    9167                 :          0 :                             INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
    9168                 :            :                         }
    9169                 :          0 :                         break;
    9170                 :       1842 :                     case IS_OP:
    9171                 :       1842 :                         cnt = get_const_value(inst->i_opcode, oparg, consts);
    9172         [ -  + ]:       1842 :                         if (cnt == NULL) {
    9173                 :          0 :                             goto error;
    9174                 :            :                         }
    9175         [ +  + ]:       1842 :                         int jump_op = i+2 < bb->b_iused ? bb->b_instr[i+2].i_opcode : 0;
    9176   [ +  +  +  +  :       1842 :                         if (Py_IsNone(cnt) && (jump_op == POP_JUMP_IF_FALSE || jump_op == POP_JUMP_IF_TRUE)) {
                   +  + ]
    9177                 :       1776 :                             unsigned char nextarg = bb->b_instr[i+1].i_oparg;
    9178                 :       1776 :                             INSTR_SET_OP0(inst, NOP);
    9179                 :       1776 :                             INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
    9180                 :       1776 :                             bb->b_instr[i+2].i_opcode = nextarg ^ (jump_op == POP_JUMP_IF_FALSE) ?
    9181         [ +  + ]:       1776 :                                     POP_JUMP_IF_NOT_NONE : POP_JUMP_IF_NONE;
    9182                 :            :                         }
    9183                 :       1842 :                         Py_DECREF(cnt);
    9184                 :       1842 :                         break;
    9185                 :      11689 :                     case RETURN_VALUE:
    9186                 :      11689 :                         INSTR_SET_OP0(inst, NOP);
    9187                 :      11689 :                         INSTR_SET_OP1(&bb->b_instr[++i], RETURN_CONST, oparg);
    9188                 :      11689 :                         break;
    9189                 :            :                 }
    9190                 :      59096 :                 break;
    9191                 :            :             }
    9192                 :            : 
    9193                 :            :                 /* Try to fold tuples of constants.
    9194                 :            :                    Skip over BUILD_TUPLE(1) UNPACK_SEQUENCE(1).
    9195                 :            :                    Replace BUILD_TUPLE(2) UNPACK_SEQUENCE(2) with SWAP(2).
    9196                 :            :                    Replace BUILD_TUPLE(3) UNPACK_SEQUENCE(3) with SWAP(3). */
    9197                 :       3790 :             case BUILD_TUPLE:
    9198   [ +  +  +  - ]:       3790 :                 if (nextop == UNPACK_SEQUENCE && oparg == bb->b_instr[i+1].i_oparg) {
    9199                 :            :                     switch(oparg) {
    9200                 :          0 :                         case 1:
    9201                 :          0 :                             INSTR_SET_OP0(inst, NOP);
    9202                 :          0 :                             INSTR_SET_OP0(&bb->b_instr[i + 1], NOP);
    9203                 :          0 :                             continue;
    9204                 :        116 :                         case 2:
    9205                 :            :                         case 3:
    9206                 :        116 :                             INSTR_SET_OP0(inst, NOP);
    9207                 :        116 :                             bb->b_instr[i+1].i_opcode = SWAP;
    9208                 :        116 :                             continue;
    9209                 :            :                     }
    9210                 :            :                 }
    9211         [ +  + ]:       3674 :                 if (i >= oparg) {
    9212         [ -  + ]:       3656 :                     if (fold_tuple_on_constants(const_cache, inst-oparg, oparg, consts)) {
    9213                 :          0 :                         goto error;
    9214                 :            :                     }
    9215                 :            :                 }
    9216                 :       3674 :                 break;
    9217                 :            : 
    9218                 :            :                 /* Simplify conditional jump to conditional jump where the
    9219                 :            :                    result of the first test implies the success of a similar
    9220                 :            :                    test or the failure of the opposite test.
    9221                 :            :                    Arises in code like:
    9222                 :            :                    "a and b or c"
    9223                 :            :                    "(a and b) and c"
    9224                 :            :                    "(a or b) or c"
    9225                 :            :                    "(a or b) and c"
    9226                 :            :                    x:JUMP_IF_FALSE_OR_POP y   y:JUMP_IF_FALSE_OR_POP z
    9227                 :            :                       -->  x:JUMP_IF_FALSE_OR_POP z
    9228                 :            :                    x:JUMP_IF_FALSE_OR_POP y   y:JUMP_IF_TRUE_OR_POP z
    9229                 :            :                       -->  x:POP_JUMP_IF_FALSE y+1
    9230                 :            :                    where y+1 is the instruction following the second test.
    9231                 :            :                 */
    9232                 :        198 :             case JUMP_IF_FALSE_OR_POP:
    9233   [ -  -  +  + ]:        198 :                 switch (target->i_opcode) {
    9234                 :          0 :                     case POP_JUMP_IF_FALSE:
    9235                 :          0 :                         i -= jump_thread(inst, target, POP_JUMP_IF_FALSE);
    9236                 :          0 :                         break;
    9237                 :          0 :                     case JUMP:
    9238                 :            :                     case JUMP_IF_FALSE_OR_POP:
    9239                 :          0 :                         i -= jump_thread(inst, target, JUMP_IF_FALSE_OR_POP);
    9240                 :          0 :                         break;
    9241                 :         23 :                     case JUMP_IF_TRUE_OR_POP:
    9242                 :            :                     case POP_JUMP_IF_TRUE:
    9243         [ +  + ]:         23 :                         if (inst->i_loc.lineno == target->i_loc.lineno) {
    9244                 :            :                             // We don't need to bother checking for loops here,
    9245                 :            :                             // since a block's b_next cannot point to itself:
    9246                 :            :                             assert(inst->i_target != inst->i_target->b_next);
    9247                 :         20 :                             inst->i_opcode = POP_JUMP_IF_FALSE;
    9248                 :         20 :                             inst->i_target = inst->i_target->b_next;
    9249                 :         20 :                             --i;
    9250                 :            :                         }
    9251                 :         23 :                         break;
    9252                 :            :                 }
    9253                 :        198 :                 break;
    9254                 :        260 :             case JUMP_IF_TRUE_OR_POP:
    9255   [ -  -  +  + ]:        260 :                 switch (target->i_opcode) {
    9256                 :          0 :                     case POP_JUMP_IF_TRUE:
    9257                 :          0 :                         i -= jump_thread(inst, target, POP_JUMP_IF_TRUE);
    9258                 :          0 :                         break;
    9259                 :          0 :                     case JUMP:
    9260                 :            :                     case JUMP_IF_TRUE_OR_POP:
    9261                 :          0 :                         i -= jump_thread(inst, target, JUMP_IF_TRUE_OR_POP);
    9262                 :          0 :                         break;
    9263                 :          3 :                     case JUMP_IF_FALSE_OR_POP:
    9264                 :            :                     case POP_JUMP_IF_FALSE:
    9265         [ +  + ]:          3 :                         if (inst->i_loc.lineno == target->i_loc.lineno) {
    9266                 :            :                             // We don't need to bother checking for loops here,
    9267                 :            :                             // since a block's b_next cannot point to itself:
    9268                 :            :                             assert(inst->i_target != inst->i_target->b_next);
    9269                 :          1 :                             inst->i_opcode = POP_JUMP_IF_TRUE;
    9270                 :          1 :                             inst->i_target = inst->i_target->b_next;
    9271                 :          1 :                             --i;
    9272                 :            :                         }
    9273                 :          3 :                         break;
    9274                 :            :                 }
    9275                 :        260 :                 break;
    9276                 :       1858 :             case POP_JUMP_IF_NOT_NONE:
    9277                 :            :             case POP_JUMP_IF_NONE:
    9278         [ +  + ]:       1858 :                 switch (target->i_opcode) {
    9279                 :         88 :                     case JUMP:
    9280                 :         88 :                         i -= jump_thread(inst, target, inst->i_opcode);
    9281                 :            :                 }
    9282                 :       1858 :                 break;
    9283                 :       9842 :             case POP_JUMP_IF_FALSE:
    9284         [ +  + ]:       9842 :                 switch (target->i_opcode) {
    9285                 :        770 :                     case JUMP:
    9286                 :        770 :                         i -= jump_thread(inst, target, POP_JUMP_IF_FALSE);
    9287                 :            :                 }
    9288                 :       9842 :                 break;
    9289                 :       2568 :             case POP_JUMP_IF_TRUE:
    9290         [ +  + ]:       2568 :                 switch (target->i_opcode) {
    9291                 :        102 :                     case JUMP:
    9292                 :        102 :                         i -= jump_thread(inst, target, POP_JUMP_IF_TRUE);
    9293                 :            :                 }
    9294                 :       2568 :                 break;
    9295                 :       7643 :             case JUMP:
    9296         [ +  + ]:       7643 :                 switch (target->i_opcode) {
    9297                 :        781 :                     case JUMP:
    9298                 :        781 :                         i -= jump_thread(inst, target, JUMP);
    9299                 :            :                 }
    9300                 :       7643 :                 break;
    9301                 :       1707 :             case FOR_ITER:
    9302                 :       1707 :                 if (target->i_opcode == JUMP) {
    9303                 :            :                     /* This will not work now because the jump (at target) could
    9304                 :            :                      * be forward or backward and FOR_ITER only jumps forward. We
    9305                 :            :                      * can re-enable this if ever we implement a backward version
    9306                 :            :                      * of FOR_ITER.
    9307                 :            :                      */
    9308                 :            :                     /*
    9309                 :            :                     i -= jump_thread(inst, target, FOR_ITER);
    9310                 :            :                     */
    9311                 :            :                 }
    9312                 :       1707 :                 break;
    9313                 :        774 :             case SWAP:
    9314         [ -  + ]:        774 :                 if (oparg == 1) {
    9315                 :          0 :                     INSTR_SET_OP0(inst, NOP);
    9316                 :          0 :                     break;
    9317                 :            :                 }
    9318         [ -  + ]:        774 :                 if (swaptimize(bb, &i) < 0) {
    9319                 :          0 :                     goto error;
    9320                 :            :                 }
    9321                 :        774 :                 apply_static_swaps(bb, i);
    9322                 :        774 :                 break;
    9323                 :       1196 :             case KW_NAMES:
    9324                 :       1196 :                 break;
    9325                 :      16270 :             case PUSH_NULL:
    9326   [ +  +  +  - ]:      16270 :                 if (nextop == LOAD_GLOBAL && (inst[1].i_opcode & 1) == 0) {
    9327                 :      12538 :                     INSTR_SET_OP0(inst, NOP);
    9328                 :      12538 :                     inst[1].i_oparg |= 1;
    9329                 :            :                 }
    9330                 :      16270 :                 break;
    9331                 :     380545 :             default:
    9332                 :            :                 /* All HAS_CONST opcodes should be handled with LOAD_CONST */
    9333                 :            :                 assert (!HAS_CONST(inst->i_opcode));
    9334                 :            :         }
    9335                 :            :     }
    9336                 :      58917 :     return SUCCESS;
    9337                 :          0 : error:
    9338                 :          0 :     return ERROR;
    9339                 :            : }
    9340                 :            : 
    9341                 :            : /* If this block ends with an unconditional jump to a small exit block, then
    9342                 :            :  * remove the jump and extend this block with the target.
    9343                 :            :  * Returns 1 if extended, 0 if no change, and -1 on error.
    9344                 :            :  */
    9345                 :            : static int
    9346                 :     117834 : inline_small_exit_blocks(basicblock *bb) {
    9347                 :     117834 :     struct cfg_instr *last = basicblock_last_instr(bb);
    9348         [ +  + ]:     117834 :     if (last == NULL) {
    9349                 :          2 :         return 0;
    9350                 :            :     }
    9351   [ +  +  +  +  :     117832 :     if (!IS_UNCONDITIONAL_JUMP_OPCODE(last->i_opcode)) {
          +  -  +  -  +  
                      - ]
    9352                 :     101919 :         return 0;
    9353                 :            :     }
    9354                 :      15913 :     basicblock *target = last->i_target;
    9355   [ +  +  +  + ]:      15913 :     if (basicblock_exits_scope(target) && target->b_iused <= MAX_COPY_SIZE) {
    9356                 :       2155 :         INSTR_SET_OP0(last, NOP);
    9357         [ -  + ]:       2155 :         RETURN_IF_ERROR(basicblock_append_instructions(bb, target));
    9358                 :       2155 :         return 1;
    9359                 :            :     }
    9360                 :      13758 :     return 0;
    9361                 :            : }
    9362                 :            : 
    9363                 :            : static int
    9364                 :     169145 : remove_redundant_nops(basicblock *bb) {
    9365                 :            :     /* Remove NOPs when legal to do so. */
    9366                 :     169145 :     int dest = 0;
    9367                 :     169145 :     int prev_lineno = -1;
    9368         [ +  + ]:    1255026 :     for (int src = 0; src < bb->b_iused; src++) {
    9369                 :    1085881 :         int lineno = bb->b_instr[src].i_loc.lineno;
    9370         [ +  + ]:    1085881 :         if (bb->b_instr[src].i_opcode == NOP) {
    9371                 :            :             /* Eliminate no-op if it doesn't have a line number */
    9372         [ +  + ]:      44398 :             if (lineno < 0) {
    9373                 :      14631 :                 continue;
    9374                 :            :             }
    9375                 :            :             /* or, if the previous instruction had the same line number. */
    9376         [ +  + ]:      29767 :             if (prev_lineno == lineno) {
    9377                 :      10829 :                 continue;
    9378                 :            :             }
    9379                 :            :             /* or, if the next instruction has same line number or no line number */
    9380         [ +  + ]:      18938 :             if (src < bb->b_iused - 1) {
    9381                 :      17062 :                 int next_lineno = bb->b_instr[src+1].i_loc.lineno;
    9382         [ +  + ]:      17062 :                 if (next_lineno == lineno) {
    9383                 :      15529 :                     continue;
    9384                 :            :                 }
    9385         [ +  + ]:       1533 :                 if (next_lineno < 0) {
    9386                 :        620 :                     bb->b_instr[src+1].i_loc = bb->b_instr[src].i_loc;
    9387                 :        620 :                     continue;
    9388                 :            :                 }
    9389                 :            :             }
    9390                 :            :             else {
    9391                 :       1876 :                 basicblock* next = bb->b_next;
    9392   [ +  -  -  + ]:       1876 :                 while (next && next->b_iused == 0) {
    9393                 :          0 :                     next = next->b_next;
    9394                 :            :                 }
    9395                 :            :                 /* or if last instruction in BB and next BB has same line number */
    9396         [ +  - ]:       1876 :                 if (next) {
    9397         [ +  + ]:       1876 :                     if (lineno == next->b_instr[0].i_loc.lineno) {
    9398                 :         26 :                         continue;
    9399                 :            :                     }
    9400                 :            :                 }
    9401                 :            :             }
    9402                 :            : 
    9403                 :            :         }
    9404         [ +  + ]:    1044246 :         if (dest != src) {
    9405                 :     150272 :             bb->b_instr[dest] = bb->b_instr[src];
    9406                 :            :         }
    9407                 :    1044246 :         dest++;
    9408                 :    1044246 :         prev_lineno = lineno;
    9409                 :            :     }
    9410                 :            :     assert(dest <= bb->b_iused);
    9411                 :     169145 :     int num_removed = bb->b_iused - dest;
    9412                 :     169145 :     bb->b_iused = dest;
    9413                 :     169145 :     return num_removed;
    9414                 :            : }
    9415                 :            : 
    9416                 :            : static int
    9417                 :       8041 : check_cfg(cfg_builder *g) {
    9418         [ +  + ]:      69608 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
    9419                 :            :         /* Raise SystemError if jump or exit is not last instruction in the block. */
    9420         [ +  + ]:     448179 :         for (int i = 0; i < b->b_iused; i++) {
    9421                 :     386612 :             int opcode = b->b_instr[i].i_opcode;
    9422                 :            :             assert(!IS_ASSEMBLER_OPCODE(opcode));
    9423   [ +  +  +  +  :     386612 :             if (IS_TERMINATOR_OPCODE(opcode)) {
          +  -  +  +  +  
                      + ]
    9424         [ -  + ]:      47043 :                 if (i != b->b_iused - 1) {
    9425                 :          0 :                     PyErr_SetString(PyExc_SystemError, "malformed control flow graph.");
    9426                 :          0 :                     return ERROR;
    9427                 :            :                 }
    9428                 :            :             }
    9429                 :            :         }
    9430                 :            :     }
    9431                 :       8041 :     return SUCCESS;
    9432                 :            : }
    9433                 :            : 
    9434                 :            : static int
    9435                 :       8041 : mark_reachable(basicblock *entryblock) {
    9436                 :       8041 :     basicblock **stack = make_cfg_traversal_stack(entryblock);
    9437         [ -  + ]:       8041 :     if (stack == NULL) {
    9438                 :          0 :         return ERROR;
    9439                 :            :     }
    9440                 :       8041 :     basicblock **sp = stack;
    9441                 :       8041 :     entryblock->b_predecessors = 1;
    9442                 :       8041 :     *sp++ = entryblock;
    9443         [ +  + ]:      58659 :     while (sp > stack) {
    9444                 :      50618 :         basicblock *b = *(--sp);
    9445                 :      50618 :         b->b_visited = 1;
    9446   [ +  +  +  + ]:      50618 :         if (b->b_next && BB_HAS_FALLTHROUGH(b)) {
    9447         [ +  + ]:      27620 :             if (!b->b_next->b_visited) {
    9448                 :            :                 assert(b->b_next->b_predecessors == 0);
    9449                 :      23751 :                 *sp++ = b->b_next;
    9450                 :            :             }
    9451                 :      27620 :             b->b_next->b_predecessors++;
    9452                 :            :         }
    9453         [ +  + ]:     396779 :         for (int i = 0; i < b->b_iused; i++) {
    9454                 :            :             basicblock *target;
    9455                 :     346161 :             struct cfg_instr *instr = &b->b_instr[i];
    9456   [ +  +  +  + ]:     346161 :             if (is_jump(instr) || is_block_push(instr)) {
    9457                 :      26115 :                 target = instr->i_target;
    9458         [ +  + ]:      26115 :                 if (!target->b_visited) {
    9459                 :            :                     assert(target->b_predecessors == 0 || target == b->b_next);
    9460                 :      18826 :                     *sp++ = target;
    9461                 :            :                 }
    9462                 :      26115 :                 target->b_predecessors++;
    9463                 :            :             }
    9464                 :            :         }
    9465                 :            :     }
    9466                 :       8041 :     PyMem_Free(stack);
    9467                 :       8041 :     return SUCCESS;
    9468                 :            : }
    9469                 :            : 
    9470                 :            : static void
    9471                 :      16082 : eliminate_empty_basic_blocks(cfg_builder *g) {
    9472                 :            :     /* Eliminate empty blocks */
    9473         [ +  + ]:     125615 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
    9474                 :     109533 :         basicblock *next = b->b_next;
    9475   [ +  +  +  + ]:     120484 :         while (next && next->b_iused == 0) {
    9476                 :      10951 :             next = next->b_next;
    9477                 :            :         }
    9478                 :     109533 :         b->b_next = next;
    9479                 :            :     }
    9480   [ +  -  -  + ]:      16082 :     while(g->g_entryblock && g->g_entryblock->b_iused == 0) {
    9481                 :          0 :         g->g_entryblock = g->g_entryblock->b_next;
    9482                 :            :     }
    9483         [ +  + ]:     125615 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
    9484                 :            :         assert(b->b_iused > 0);
    9485         [ +  + ]:     842148 :         for (int i = 0; i < b->b_iused; i++) {
    9486                 :     732615 :             struct cfg_instr *instr = &b->b_instr[i];
    9487   [ +  +  +  +  :     732615 :             if (HAS_TARGET(instr->i_opcode)) {
             +  +  +  + ]
    9488                 :      55640 :                 basicblock *target = instr->i_target;
    9489         [ +  + ]:      59816 :                 while (target->b_iused == 0) {
    9490                 :       4176 :                     target = target->b_next;
    9491                 :            :                 }
    9492                 :      55640 :                 instr->i_target = target;
    9493                 :            :                 assert(instr->i_target && instr->i_target->b_iused > 0);
    9494                 :            :             }
    9495                 :            :         }
    9496                 :            :     }
    9497                 :      16082 : }
    9498                 :            : 
    9499                 :            : 
    9500                 :            : /* If an instruction has no line number, but it's predecessor in the BB does,
    9501                 :            :  * then copy the line number. If a successor block has no line number, and only
    9502                 :            :  * one predecessor, then inherit the line number.
    9503                 :            :  * This ensures that all exit blocks (with one predecessor) receive a line number.
    9504                 :            :  * Also reduces the size of the line number table,
    9505                 :            :  * but has no impact on the generated line number events.
    9506                 :            :  */
    9507                 :            : static void
    9508                 :       8041 : propagate_line_numbers(basicblock *entryblock) {
    9509         [ +  + ]:      59352 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    9510                 :      51311 :         struct cfg_instr *last = basicblock_last_instr(b);
    9511         [ -  + ]:      51311 :         if (last == NULL) {
    9512                 :          0 :             continue;
    9513                 :            :         }
    9514                 :            : 
    9515                 :      51311 :         location prev_location = NO_LOCATION;
    9516         [ +  + ]:     398096 :         for (int i = 0; i < b->b_iused; i++) {
    9517         [ +  + ]:     346785 :             if (b->b_instr[i].i_loc.lineno < 0) {
    9518                 :      32742 :                 b->b_instr[i].i_loc = prev_location;
    9519                 :            :             }
    9520                 :            :             else {
    9521                 :     314043 :                 prev_location = b->b_instr[i].i_loc;
    9522                 :            :             }
    9523                 :            :         }
    9524   [ +  +  +  + ]:      51311 :         if (BB_HAS_FALLTHROUGH(b) && b->b_next->b_predecessors == 1) {
    9525                 :            :             assert(b->b_next->b_iused);
    9526         [ +  + ]:      21271 :             if (b->b_next->b_instr[0].i_loc.lineno < 0) {
    9527                 :       1752 :                 b->b_next->b_instr[0].i_loc = prev_location;
    9528                 :            :             }
    9529                 :            :         }
    9530         [ +  + ]:      51311 :         if (is_jump(last)) {
    9531                 :      20694 :             basicblock *target = last->i_target;
    9532         [ +  + ]:      20694 :             if (target->b_predecessors == 1) {
    9533         [ +  + ]:       9137 :                 if (target->b_instr[0].i_loc.lineno < 0) {
    9534                 :       3522 :                     target->b_instr[0].i_loc = prev_location;
    9535                 :            :                 }
    9536                 :            :             }
    9537                 :            :         }
    9538                 :            :     }
    9539                 :       8041 : }
    9540                 :            : 
    9541                 :            : 
    9542                 :            : /* Calculate the actual jump target from the target_label */
    9543                 :            : static int
    9544                 :       8041 : translate_jump_labels_to_targets(basicblock *entryblock)
    9545                 :            : {
    9546                 :       8041 :     int max_label = -1;
    9547         [ +  + ]:      69608 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    9548         [ +  + ]:      61567 :         if (b->b_label.id > max_label) {
    9549                 :      20366 :             max_label = b->b_label.id;
    9550                 :            :         }
    9551                 :            :     }
    9552                 :       8041 :     size_t mapsize = sizeof(basicblock *) * (max_label + 1);
    9553                 :       8041 :     basicblock **label2block = (basicblock **)PyMem_Malloc(mapsize);
    9554         [ -  + ]:       8041 :     if (!label2block) {
    9555                 :          0 :         PyErr_NoMemory();
    9556                 :          0 :         return ERROR;
    9557                 :            :     }
    9558                 :       8041 :     memset(label2block, 0, mapsize);
    9559         [ +  + ]:      69608 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    9560         [ +  + ]:      61567 :         if (b->b_label.id >= 0) {
    9561                 :      33597 :             label2block[b->b_label.id] = b;
    9562                 :            :         }
    9563                 :            :     }
    9564         [ +  + ]:      69608 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    9565         [ +  + ]:     448179 :         for (int i = 0; i < b->b_iused; i++) {
    9566                 :     386612 :             struct cfg_instr *instr = &b->b_instr[i];
    9567                 :            :             assert(instr->i_target == NULL);
    9568   [ +  +  +  +  :     386612 :             if (HAS_TARGET(instr->i_opcode)) {
             +  +  +  + ]
    9569                 :      29525 :                 int lbl = instr->i_oparg;
    9570                 :            :                 assert(lbl >= 0 && lbl <= max_label);
    9571                 :      29525 :                 instr->i_target = label2block[lbl];
    9572                 :            :                 assert(instr->i_target != NULL);
    9573                 :            :                 assert(instr->i_target->b_label.id == lbl);
    9574                 :            :             }
    9575                 :            :         }
    9576                 :            :     }
    9577                 :       8041 :     PyMem_Free(label2block);
    9578                 :       8041 :     return SUCCESS;
    9579                 :            : }
    9580                 :            : 
    9581                 :            : /* Perform optimizations on a control flow graph.
    9582                 :            :    The consts object should still be in list form to allow new constants
    9583                 :            :    to be appended.
    9584                 :            : 
    9585                 :            :    Code trasnformations that reduce code size initially fill the gaps with
    9586                 :            :    NOPs.  Later those NOPs are removed.
    9587                 :            : */
    9588                 :            : 
    9589                 :            : static int
    9590                 :       8041 : optimize_cfg(cfg_builder *g, PyObject *consts, PyObject *const_cache)
    9591                 :            : {
    9592                 :            :     assert(PyDict_CheckExact(const_cache));
    9593         [ -  + ]:       8041 :     RETURN_IF_ERROR(check_cfg(g));
    9594                 :       8041 :     eliminate_empty_basic_blocks(g);
    9595         [ +  + ]:      66958 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
    9596         [ -  + ]:      58917 :         RETURN_IF_ERROR(inline_small_exit_blocks(b));
    9597                 :            :     }
    9598                 :            :     assert(no_empty_basic_blocks(g));
    9599         [ +  + ]:      66958 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
    9600         [ -  + ]:      58917 :         RETURN_IF_ERROR(optimize_basic_block(const_cache, b, consts));
    9601                 :      58917 :         remove_redundant_nops(b);
    9602                 :            :         assert(b->b_predecessors == 0);
    9603                 :            :     }
    9604         [ +  + ]:      66958 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
    9605         [ -  + ]:      58917 :         RETURN_IF_ERROR(inline_small_exit_blocks(b));
    9606                 :            :     }
    9607         [ -  + ]:       8041 :     RETURN_IF_ERROR(mark_reachable(g->g_entryblock));
    9608                 :            : 
    9609                 :            :     /* Delete unreachable instructions */
    9610         [ +  + ]:      66958 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
    9611         [ +  + ]:      58917 :        if (b->b_predecessors == 0) {
    9612                 :       8299 :             b->b_iused = 0;
    9613                 :            :        }
    9614                 :            :     }
    9615         [ +  + ]:      66958 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
    9616                 :      58917 :         remove_redundant_nops(b);
    9617                 :            :     }
    9618                 :       8041 :     eliminate_empty_basic_blocks(g);
    9619                 :            :     assert(no_redundant_nops(g));
    9620         [ -  + ]:       8041 :     RETURN_IF_ERROR(remove_redundant_jumps(g));
    9621                 :       8041 :     return SUCCESS;
    9622                 :            : }
    9623                 :            : 
    9624                 :            : 
    9625                 :            : static int
    9626                 :       8041 : remove_unused_consts(basicblock *entryblock, PyObject *consts)
    9627                 :            : {
    9628                 :            :     assert(PyList_CheckExact(consts));
    9629                 :       8041 :     Py_ssize_t nconsts = PyList_GET_SIZE(consts);
    9630         [ -  + ]:       8041 :     if (nconsts == 0) {
    9631                 :          0 :         return SUCCESS;  /* nothing to do */
    9632                 :            :     }
    9633                 :            : 
    9634                 :       8041 :     Py_ssize_t *index_map = NULL;
    9635                 :       8041 :     Py_ssize_t *reverse_index_map = NULL;
    9636                 :       8041 :     int err = ERROR;
    9637                 :            : 
    9638                 :       8041 :     index_map = PyMem_Malloc(nconsts * sizeof(Py_ssize_t));
    9639         [ -  + ]:       8041 :     if (index_map == NULL) {
    9640                 :          0 :         goto end;
    9641                 :            :     }
    9642         [ +  + ]:      42935 :     for (Py_ssize_t i = 1; i < nconsts; i++) {
    9643                 :      34894 :         index_map[i] = -1;
    9644                 :            :     }
    9645                 :            :     // The first constant may be docstring; keep it always.
    9646                 :       8041 :     index_map[0] = 0;
    9647                 :            : 
    9648                 :            :     /* mark used consts */
    9649         [ +  + ]:      58657 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    9650         [ +  + ]:     396619 :         for (int i = 0; i < b->b_iused; i++) {
    9651   [ +  +  +  +  :     346003 :             if (HAS_CONST(b->b_instr[i].i_opcode)) {
                   +  + ]
    9652                 :      50633 :                 int index = b->b_instr[i].i_oparg;
    9653                 :      50633 :                 index_map[index] = index;
    9654                 :            :             }
    9655                 :            :         }
    9656                 :            :     }
    9657                 :            :     /* now index_map[i] == i if consts[i] is used, -1 otherwise */
    9658                 :            : 
    9659                 :            :     /* condense consts */
    9660                 :       8041 :     Py_ssize_t n_used_consts = 0;
    9661         [ +  + ]:      50976 :     for (int i = 0; i < nconsts; i++) {
    9662         [ +  + ]:      42935 :         if (index_map[i] != -1) {
    9663                 :            :             assert(index_map[i] == i);
    9664                 :      41021 :             index_map[n_used_consts++] = index_map[i];
    9665                 :            :         }
    9666                 :            :     }
    9667         [ +  + ]:       8041 :     if (n_used_consts == nconsts) {
    9668                 :            :         /* nothing to do */
    9669                 :       6315 :         err = SUCCESS;
    9670                 :       6315 :         goto end;
    9671                 :            :     }
    9672                 :            : 
    9673                 :            :     /* move all used consts to the beginning of the consts list */
    9674                 :            :     assert(n_used_consts < nconsts);
    9675         [ +  + ]:      13141 :     for (Py_ssize_t i = 0; i < n_used_consts; i++) {
    9676                 :      11415 :         Py_ssize_t old_index = index_map[i];
    9677                 :            :         assert(i <= old_index && old_index < nconsts);
    9678         [ +  + ]:      11415 :         if (i != old_index) {
    9679                 :       5660 :             PyObject *value = PyList_GET_ITEM(consts, index_map[i]);
    9680                 :            :             assert(value != NULL);
    9681                 :       5660 :             PyList_SetItem(consts, i, Py_NewRef(value));
    9682                 :            :         }
    9683                 :            :     }
    9684                 :            : 
    9685                 :            :     /* truncate the consts list at its new size */
    9686         [ -  + ]:       1726 :     if (PyList_SetSlice(consts, n_used_consts, nconsts, NULL) < 0) {
    9687                 :          0 :         goto end;
    9688                 :            :     }
    9689                 :            : 
    9690                 :            :     /* adjust const indices in the bytecode */
    9691                 :       1726 :     reverse_index_map = PyMem_Malloc(nconsts * sizeof(Py_ssize_t));
    9692         [ -  + ]:       1726 :     if (reverse_index_map == NULL) {
    9693                 :          0 :         goto end;
    9694                 :            :     }
    9695         [ +  + ]:      15055 :     for (Py_ssize_t i = 0; i < nconsts; i++) {
    9696                 :      13329 :         reverse_index_map[i] = -1;
    9697                 :            :     }
    9698         [ +  + ]:      13141 :     for (Py_ssize_t i = 0; i < n_used_consts; i++) {
    9699                 :            :         assert(index_map[i] != -1);
    9700                 :            :         assert(reverse_index_map[index_map[i]] == -1);
    9701                 :      11415 :         reverse_index_map[index_map[i]] = i;
    9702                 :            :     }
    9703                 :            : 
    9704         [ +  + ]:      10610 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    9705         [ +  + ]:      81122 :         for (int i = 0; i < b->b_iused; i++) {
    9706   [ +  +  +  +  :      72238 :             if (HAS_CONST(b->b_instr[i].i_opcode)) {
                   +  + ]
    9707                 :      12700 :                 int index = b->b_instr[i].i_oparg;
    9708                 :            :                 assert(reverse_index_map[index] >= 0);
    9709                 :            :                 assert(reverse_index_map[index] < n_used_consts);
    9710                 :      12700 :                 b->b_instr[i].i_oparg = (int)reverse_index_map[index];
    9711                 :            :             }
    9712                 :            :         }
    9713                 :            :     }
    9714                 :            : 
    9715                 :       1726 :     err = SUCCESS;
    9716                 :       8041 : end:
    9717                 :       8041 :     PyMem_Free(index_map);
    9718                 :       8041 :     PyMem_Free(reverse_index_map);
    9719                 :       8041 :     return err;
    9720                 :            : }
    9721                 :            : 
    9722                 :            : static inline bool
    9723                 :      49183 : is_exit_without_lineno(basicblock *b) {
    9724         [ +  + ]:      49183 :     if (!basicblock_exits_scope(b)) {
    9725                 :      35956 :         return false;
    9726                 :            :     }
    9727         [ +  + ]:      18439 :     for (int i = 0; i < b->b_iused; i++) {
    9728         [ +  + ]:      15101 :         if (b->b_instr[i].i_loc.lineno >= 0) {
    9729                 :       9889 :             return false;
    9730                 :            :         }
    9731                 :            :     }
    9732                 :       3338 :     return true;
    9733                 :            : }
    9734                 :            : 
    9735                 :            : /* PEP 626 mandates that the f_lineno of a frame is correct
    9736                 :            :  * after a frame terminates. It would be prohibitively expensive
    9737                 :            :  * to continuously update the f_lineno field at runtime,
    9738                 :            :  * so we make sure that all exiting instruction (raises and returns)
    9739                 :            :  * have a valid line number, allowing us to compute f_lineno lazily.
    9740                 :            :  * We can do this by duplicating the exit blocks without line number
    9741                 :            :  * so that none have more than one predecessor. We can then safely
    9742                 :            :  * copy the line number from the sole predecessor block.
    9743                 :            :  */
    9744                 :            : static int
    9745                 :       8041 : duplicate_exits_without_lineno(cfg_builder *g)
    9746                 :            : {
    9747                 :            :     assert(no_empty_basic_blocks(g));
    9748                 :            :     /* Copy all exit blocks without line number that are targets of a jump.
    9749                 :            :      */
    9750                 :       8041 :     basicblock *entryblock = g->g_entryblock;
    9751         [ +  + ]:      59351 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    9752                 :      51310 :         struct cfg_instr *last = basicblock_last_instr(b);
    9753                 :            :         assert(last != NULL);
    9754         [ +  + ]:      51310 :         if (is_jump(last)) {
    9755                 :      20694 :             basicblock *target = last->i_target;
    9756   [ +  +  +  + ]:      20694 :             if (is_exit_without_lineno(target) && target->b_predecessors > 1) {
    9757                 :        514 :                 basicblock *new_target = copy_basicblock(g, target);
    9758         [ -  + ]:        514 :                 if (new_target == NULL) {
    9759                 :          0 :                     return ERROR;
    9760                 :            :                 }
    9761                 :        514 :                 new_target->b_instr[0].i_loc = last->i_loc;
    9762                 :        514 :                 last->i_target = new_target;
    9763                 :        514 :                 target->b_predecessors--;
    9764                 :        514 :                 new_target->b_predecessors = 1;
    9765                 :        514 :                 new_target->b_next = target->b_next;
    9766                 :        514 :                 target->b_next = new_target;
    9767                 :            :             }
    9768                 :            :         }
    9769                 :            :     }
    9770                 :            : 
    9771                 :            :     /* Any remaining reachable exit blocks without line number can only be reached by
    9772                 :            :      * fall through, and thus can only have a single predecessor */
    9773         [ +  + ]:      59352 :     for (basicblock *b = entryblock; b != NULL; b = b->b_next) {
    9774   [ +  +  +  -  :      51311 :         if (BB_HAS_FALLTHROUGH(b) && b->b_next && b->b_iused > 0) {
                   +  - ]
    9775         [ +  + ]:      28489 :             if (is_exit_without_lineno(b->b_next)) {
    9776                 :       1096 :                 struct cfg_instr *last = basicblock_last_instr(b);
    9777                 :            :                 assert(last != NULL);
    9778                 :       1096 :                 b->b_next->b_instr[0].i_loc = last->i_loc;
    9779                 :            :             }
    9780                 :            :         }
    9781                 :            :     }
    9782                 :       8041 :     return SUCCESS;
    9783                 :            : }
    9784                 :            : 
    9785                 :            : 
    9786                 :            : /* Access to compiler optimizations for unit tests.
    9787                 :            :  *
    9788                 :            :  * _PyCompile_CodeGen takes and AST, applies code-gen and
    9789                 :            :  * returns the unoptimized CFG as an instruction list.
    9790                 :            :  *
    9791                 :            :  * _PyCompile_OptimizeCfg takes an instruction list, constructs
    9792                 :            :  * a CFG, optimizes it and converts back to an instruction list.
    9793                 :            :  *
    9794                 :            :  * An instruction list is a PyList where each item is either
    9795                 :            :  * a tuple describing a single instruction:
    9796                 :            :  * (opcode, oparg, lineno, end_lineno, col, end_col), or
    9797                 :            :  * a jump target label marking the beginning of a basic block.
    9798                 :            :  */
    9799                 :            : 
    9800                 :            : static int
    9801                 :          0 : instructions_to_cfg(PyObject *instructions, cfg_builder *g)
    9802                 :            : {
    9803                 :            :     assert(PyList_Check(instructions));
    9804                 :            : 
    9805                 :          0 :     Py_ssize_t num_insts = PyList_GET_SIZE(instructions);
    9806                 :          0 :     bool *is_target = PyMem_Calloc(num_insts, sizeof(bool));
    9807         [ #  # ]:          0 :     if (is_target == NULL) {
    9808                 :          0 :         return ERROR;
    9809                 :            :     }
    9810         [ #  # ]:          0 :     for (Py_ssize_t i = 0; i < num_insts; i++) {
    9811                 :          0 :         PyObject *item = PyList_GET_ITEM(instructions, i);
    9812   [ #  #  #  # ]:          0 :         if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 6) {
    9813                 :          0 :             PyErr_SetString(PyExc_ValueError, "expected a 6-tuple");
    9814                 :          0 :             goto error;
    9815                 :            :         }
    9816                 :          0 :         int opcode = PyLong_AsLong(PyTuple_GET_ITEM(item, 0));
    9817         [ #  # ]:          0 :         if (PyErr_Occurred()) {
    9818                 :          0 :             goto error;
    9819                 :            :         }
    9820   [ #  #  #  #  :          0 :         if (HAS_TARGET(opcode)) {
             #  #  #  # ]
    9821                 :          0 :             int oparg = PyLong_AsLong(PyTuple_GET_ITEM(item, 1));
    9822         [ #  # ]:          0 :             if (PyErr_Occurred()) {
    9823                 :          0 :                 goto error;
    9824                 :            :             }
    9825   [ #  #  #  # ]:          0 :             if (oparg < 0 || oparg >= num_insts) {
    9826                 :          0 :                 PyErr_SetString(PyExc_ValueError, "label out of range");
    9827                 :          0 :                 goto error;
    9828                 :            :             }
    9829                 :          0 :             is_target[oparg] = true;
    9830                 :            :         }
    9831                 :            :     }
    9832                 :            : 
    9833         [ #  # ]:          0 :     for (int i = 0; i < num_insts; i++) {
    9834         [ #  # ]:          0 :         if (is_target[i]) {
    9835                 :          0 :             jump_target_label lbl = {i};
    9836         [ #  # ]:          0 :             RETURN_IF_ERROR(cfg_builder_use_label(g, lbl));
    9837                 :            :         }
    9838                 :          0 :         PyObject *item = PyList_GET_ITEM(instructions, i);
    9839   [ #  #  #  # ]:          0 :         if (!PyTuple_Check(item) || PyTuple_GET_SIZE(item) != 6) {
    9840                 :          0 :             PyErr_SetString(PyExc_ValueError, "expected a 6-tuple");
    9841                 :          0 :             goto error;
    9842                 :            :         }
    9843                 :          0 :         int opcode = PyLong_AsLong(PyTuple_GET_ITEM(item, 0));
    9844         [ #  # ]:          0 :         if (PyErr_Occurred()) {
    9845                 :          0 :             goto error;
    9846                 :            :         }
    9847                 :            :         int oparg;
    9848   [ #  #  #  #  :          0 :         if (HAS_ARG(opcode)) {
          #  #  #  #  #  
                #  #  # ]
    9849                 :          0 :             oparg = PyLong_AsLong(PyTuple_GET_ITEM(item, 1));
    9850         [ #  # ]:          0 :             if (PyErr_Occurred()) {
    9851                 :          0 :                 goto error;
    9852                 :            :             }
    9853                 :            :         }
    9854                 :            :         else {
    9855                 :          0 :             oparg = 0;
    9856                 :            :         }
    9857                 :            :         location loc;
    9858                 :          0 :         loc.lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 2));
    9859         [ #  # ]:          0 :         if (PyErr_Occurred()) {
    9860                 :          0 :             goto error;
    9861                 :            :         }
    9862                 :          0 :         loc.end_lineno = PyLong_AsLong(PyTuple_GET_ITEM(item, 3));
    9863         [ #  # ]:          0 :         if (PyErr_Occurred()) {
    9864                 :          0 :             goto error;
    9865                 :            :         }
    9866                 :          0 :         loc.col_offset = PyLong_AsLong(PyTuple_GET_ITEM(item, 4));
    9867         [ #  # ]:          0 :         if (PyErr_Occurred()) {
    9868                 :          0 :             goto error;
    9869                 :            :         }
    9870                 :          0 :         loc.end_col_offset = PyLong_AsLong(PyTuple_GET_ITEM(item, 5));
    9871         [ #  # ]:          0 :         if (PyErr_Occurred()) {
    9872                 :          0 :             goto error;
    9873                 :            :         }
    9874         [ #  # ]:          0 :         RETURN_IF_ERROR(cfg_builder_addop(g, opcode, oparg, loc));
    9875                 :            :     }
    9876                 :          0 :     struct cfg_instr *last = basicblock_last_instr(g->g_curblock);
    9877   [ #  #  #  #  :          0 :     if (last && !IS_TERMINATOR_OPCODE(last->i_opcode)) {
          #  #  #  #  #  
                #  #  # ]
    9878         [ #  # ]:          0 :         RETURN_IF_ERROR(cfg_builder_addop(g, RETURN_VALUE, 0, NO_LOCATION));
    9879                 :            :     }
    9880                 :          0 :     PyMem_Free(is_target);
    9881                 :          0 :     return SUCCESS;
    9882                 :          0 : error:
    9883                 :          0 :     PyMem_Free(is_target);
    9884                 :          0 :     return ERROR;
    9885                 :            : }
    9886                 :            : 
    9887                 :            : static PyObject *
    9888                 :          0 : instr_sequence_to_instructions(instr_sequence *seq) {
    9889                 :          0 :     PyObject *instructions = PyList_New(0);
    9890         [ #  # ]:          0 :     if (instructions == NULL) {
    9891                 :          0 :         return NULL;
    9892                 :            :     }
    9893         [ #  # ]:          0 :     for (int i = 0; i < seq->s_used; i++) {
    9894                 :          0 :         instruction *instr = &seq->s_instrs[i];
    9895                 :          0 :         location loc = instr->i_loc;
    9896   [ #  #  #  #  :          0 :         int arg = HAS_TARGET(instr->i_opcode) ?
                   #  # ]
    9897         [ #  # ]:          0 :                   seq->s_labelmap[instr->i_oparg] : instr->i_oparg;
    9898                 :            : 
    9899                 :          0 :         PyObject *inst_tuple = Py_BuildValue(
    9900                 :            :             "(iiiiii)", instr->i_opcode, arg,
    9901                 :            :             loc.lineno, loc.end_lineno,
    9902                 :            :             loc.col_offset, loc.end_col_offset);
    9903         [ #  # ]:          0 :         if (inst_tuple == NULL) {
    9904                 :          0 :             goto error;
    9905                 :            :         }
    9906                 :            : 
    9907                 :          0 :         int res = PyList_Append(instructions, inst_tuple);
    9908                 :          0 :         Py_DECREF(inst_tuple);
    9909         [ #  # ]:          0 :         if (res != 0) {
    9910                 :          0 :             goto error;
    9911                 :            :         }
    9912                 :            :     }
    9913                 :          0 :     return instructions;
    9914                 :          0 : error:
    9915                 :          0 :     Py_XDECREF(instructions);
    9916                 :          0 :     return NULL;
    9917                 :            : }
    9918                 :            : 
    9919                 :            : static PyObject *
    9920                 :          0 : cfg_to_instructions(cfg_builder *g)
    9921                 :            : {
    9922                 :          0 :     PyObject *instructions = PyList_New(0);
    9923         [ #  # ]:          0 :     if (instructions == NULL) {
    9924                 :          0 :         return NULL;
    9925                 :            :     }
    9926                 :          0 :     int lbl = 0;
    9927         [ #  # ]:          0 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
    9928                 :          0 :         b->b_label = (jump_target_label){lbl};
    9929                 :          0 :         lbl += b->b_iused;
    9930                 :            :     }
    9931         [ #  # ]:          0 :     for (basicblock *b = g->g_entryblock; b != NULL; b = b->b_next) {
    9932         [ #  # ]:          0 :         for (int i = 0; i < b->b_iused; i++) {
    9933                 :          0 :             struct cfg_instr *instr = &b->b_instr[i];
    9934                 :          0 :             location loc = instr->i_loc;
    9935   [ #  #  #  #  :          0 :             int arg = HAS_TARGET(instr->i_opcode) ?
                   #  # ]
    9936         [ #  # ]:          0 :                       instr->i_target->b_label.id : instr->i_oparg;
    9937                 :            : 
    9938                 :          0 :             PyObject *inst_tuple = Py_BuildValue(
    9939                 :            :                 "(iiiiii)", instr->i_opcode, arg,
    9940                 :            :                 loc.lineno, loc.end_lineno,
    9941                 :            :                 loc.col_offset, loc.end_col_offset);
    9942         [ #  # ]:          0 :             if (inst_tuple == NULL) {
    9943                 :          0 :                 goto error;
    9944                 :            :             }
    9945                 :            : 
    9946         [ #  # ]:          0 :             if (PyList_Append(instructions, inst_tuple) != 0) {
    9947                 :          0 :                 Py_DECREF(inst_tuple);
    9948                 :          0 :                 goto error;
    9949                 :            :             }
    9950                 :          0 :             Py_DECREF(inst_tuple);
    9951                 :            :         }
    9952                 :            :     }
    9953                 :            : 
    9954                 :          0 :     return instructions;
    9955                 :          0 : error:
    9956                 :          0 :     Py_DECREF(instructions);
    9957                 :          0 :     return NULL;
    9958                 :            : }
    9959                 :            : 
    9960                 :            : PyObject *
    9961                 :          0 : _PyCompile_CodeGen(PyObject *ast, PyObject *filename, PyCompilerFlags *pflags,
    9962                 :            :                    int optimize)
    9963                 :            : {
    9964                 :          0 :     PyObject *res = NULL;
    9965                 :            : 
    9966         [ #  # ]:          0 :     if (!PyAST_Check(ast)) {
    9967                 :          0 :         PyErr_SetString(PyExc_TypeError, "expected an AST");
    9968                 :          0 :         return NULL;
    9969                 :            :     }
    9970                 :            : 
    9971                 :          0 :     PyArena *arena = _PyArena_New();
    9972         [ #  # ]:          0 :     if (arena == NULL) {
    9973                 :          0 :         return NULL;
    9974                 :            :     }
    9975                 :            : 
    9976                 :          0 :     mod_ty mod = PyAST_obj2mod(ast, arena, 0 /* exec */);
    9977   [ #  #  #  # ]:          0 :     if (mod == NULL || !_PyAST_Validate(mod)) {
    9978                 :          0 :         _PyArena_Free(arena);
    9979                 :          0 :         return NULL;
    9980                 :            :     }
    9981                 :            : 
    9982                 :          0 :     struct compiler *c = new_compiler(mod, filename, pflags, optimize, arena);
    9983         [ #  # ]:          0 :     if (c == NULL) {
    9984                 :          0 :         _PyArena_Free(arena);
    9985                 :          0 :         return NULL;
    9986                 :            :     }
    9987                 :            : 
    9988         [ #  # ]:          0 :     if (compiler_codegen(c, mod) < 0) {
    9989                 :          0 :         goto finally;
    9990                 :            :     }
    9991                 :            : 
    9992                 :          0 :     res = instr_sequence_to_instructions(INSTR_SEQUENCE(c));
    9993                 :            : 
    9994                 :          0 : finally:
    9995                 :          0 :     compiler_exit_scope(c);
    9996                 :          0 :     compiler_free(c);
    9997                 :          0 :     _PyArena_Free(arena);
    9998                 :          0 :     return res;
    9999                 :            : }
   10000                 :            : 
   10001                 :            : PyObject *
   10002                 :          0 : _PyCompile_OptimizeCfg(PyObject *instructions, PyObject *consts)
   10003                 :            : {
   10004                 :          0 :     PyObject *res = NULL;
   10005                 :          0 :     PyObject *const_cache = PyDict_New();
   10006         [ #  # ]:          0 :     if (const_cache == NULL) {
   10007                 :          0 :         return NULL;
   10008                 :            :     }
   10009                 :            : 
   10010                 :            :     cfg_builder g;
   10011                 :          0 :     memset(&g, 0, sizeof(cfg_builder));
   10012         [ #  # ]:          0 :     if (cfg_builder_init(&g) < 0) {
   10013                 :          0 :         goto error;
   10014                 :            :     }
   10015         [ #  # ]:          0 :     if (instructions_to_cfg(instructions, &g) < 0) {
   10016                 :          0 :         goto error;
   10017                 :            :     }
   10018                 :          0 :     int code_flags = 0, nlocals = 0, nparams = 0;
   10019         [ #  # ]:          0 :     if (optimize_code_unit(&g, consts, const_cache, code_flags, nlocals, nparams) < 0) {
   10020                 :          0 :         goto error;
   10021                 :            :     }
   10022                 :          0 :     res = cfg_to_instructions(&g);
   10023                 :          0 : error:
   10024                 :          0 :     Py_DECREF(const_cache);
   10025                 :          0 :     cfg_builder_fini(&g);
   10026                 :          0 :     return res;
   10027                 :            : }
   10028                 :            : 
   10029                 :            : 
   10030                 :            : /* Retained for API compatibility.
   10031                 :            :  * Optimization is now done in optimize_cfg */
   10032                 :            : 
   10033                 :            : PyObject *
   10034                 :          0 : PyCode_Optimize(PyObject *code, PyObject* Py_UNUSED(consts),
   10035                 :            :                 PyObject *Py_UNUSED(names), PyObject *Py_UNUSED(lnotab_obj))
   10036                 :            : {
   10037                 :          0 :     return Py_NewRef(code);
   10038                 :            : }

Generated by: LCOV version 1.14