LCOV - code coverage report
Current view: top level - py - emitbc.c (source / functions) Hit Total Coverage
Test: unix_coverage_v1.24.0-7-g548babf8a.info Lines: 468 468 100.0 %
Date: 2024-10-30 09:06:48 Functions: 72 72 100.0 %
Branches: 161 176 91.5 %

           Branch data     Line data    Source code
       1                 :            : /*
       2                 :            :  * This file is part of the MicroPython project, http://micropython.org/
       3                 :            :  *
       4                 :            :  * The MIT License (MIT)
       5                 :            :  *
       6                 :            :  * Copyright (c) 2013-2019 Damien P. George
       7                 :            :  *
       8                 :            :  * Permission is hereby granted, free of charge, to any person obtaining a copy
       9                 :            :  * of this software and associated documentation files (the "Software"), to deal
      10                 :            :  * in the Software without restriction, including without limitation the rights
      11                 :            :  * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
      12                 :            :  * copies of the Software, and to permit persons to whom the Software is
      13                 :            :  * furnished to do so, subject to the following conditions:
      14                 :            :  *
      15                 :            :  * The above copyright notice and this permission notice shall be included in
      16                 :            :  * all copies or substantial portions of the Software.
      17                 :            :  *
      18                 :            :  * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
      19                 :            :  * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
      20                 :            :  * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
      21                 :            :  * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
      22                 :            :  * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
      23                 :            :  * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
      24                 :            :  * THE SOFTWARE.
      25                 :            :  */
      26                 :            : 
      27                 :            : #include <stdbool.h>
      28                 :            : #include <stdint.h>
      29                 :            : #include <stdio.h>
      30                 :            : #include <string.h>
      31                 :            : #include <unistd.h>
      32                 :            : #include <assert.h>
      33                 :            : 
      34                 :            : #include "py/mpstate.h"
      35                 :            : #include "py/smallint.h"
      36                 :            : #include "py/emit.h"
      37                 :            : #include "py/bc0.h"
      38                 :            : 
      39                 :            : #if MICROPY_ENABLE_COMPILER
      40                 :            : 
      41                 :            : #define DUMMY_DATA_SIZE (MP_ENCODE_UINT_MAX_BYTES)
      42                 :            : 
      43                 :            : struct _emit_t {
      44                 :            :     // Accessed as mp_obj_t, so must be aligned as such, and we rely on the
      45                 :            :     // memory allocator returning a suitably aligned pointer.
      46                 :            :     // Should work for cases when mp_obj_t is 64-bit on a 32-bit machine.
      47                 :            :     byte dummy_data[DUMMY_DATA_SIZE];
      48                 :            : 
      49                 :            :     pass_kind_t pass : 8;
      50                 :            : 
      51                 :            :     // Set to true if the code generator should suppress emitted code due to it
      52                 :            :     // being dead code.  This can happen when opcodes immediately follow an
      53                 :            :     // unconditional flow control (eg jump or raise).
      54                 :            :     bool suppress;
      55                 :            : 
      56                 :            :     int stack_size;
      57                 :            : 
      58                 :            :     mp_emit_common_t *emit_common;
      59                 :            :     scope_t *scope;
      60                 :            : 
      61                 :            :     mp_uint_t last_source_line_offset;
      62                 :            :     mp_uint_t last_source_line;
      63                 :            : 
      64                 :            :     size_t max_num_labels;
      65                 :            :     size_t *label_offsets;
      66                 :            : 
      67                 :            :     size_t code_info_offset;
      68                 :            :     size_t code_info_size;
      69                 :            :     size_t bytecode_offset;
      70                 :            :     size_t bytecode_size;
      71                 :            :     byte *code_base; // stores both byte code and code info
      72                 :            :     bool overflow;
      73                 :            : 
      74                 :            :     size_t n_info;
      75                 :            :     size_t n_cell;
      76                 :            : };
      77                 :            : 
      78                 :       3891 : emit_t *emit_bc_new(mp_emit_common_t *emit_common) {
      79                 :       3891 :     emit_t *emit = m_new0(emit_t, 1);
      80                 :       3891 :     emit->emit_common = emit_common;
      81                 :       3891 :     return emit;
      82                 :            : }
      83                 :            : 
      84                 :       3887 : void emit_bc_set_max_num_labels(emit_t *emit, mp_uint_t max_num_labels) {
      85                 :       3887 :     emit->max_num_labels = max_num_labels;
      86                 :       3887 :     emit->label_offsets = m_new(size_t, emit->max_num_labels);
      87                 :       3887 : }
      88                 :            : 
      89                 :       3868 : void emit_bc_free(emit_t *emit) {
      90                 :       3868 :     m_del(size_t, emit->label_offsets, emit->max_num_labels);
      91                 :       3869 :     m_del_obj(emit_t, emit);
      92                 :       3869 : }
      93                 :            : 
      94                 :            : // all functions must go through this one to emit code info
      95                 :     385141 : static uint8_t *emit_get_cur_to_write_code_info(void *emit_in, size_t num_bytes_to_write) {
      96                 :     385141 :     emit_t *emit = emit_in;
      97         [ +  + ]:     385141 :     if (emit->pass < MP_PASS_EMIT) {
      98                 :     204005 :         emit->code_info_offset += num_bytes_to_write;
      99                 :     204005 :         return emit->dummy_data;
     100                 :            :     } else {
     101         [ -  + ]:     181136 :         assert(emit->code_info_offset + num_bytes_to_write <= emit->code_info_size);
     102                 :     181136 :         byte *c = emit->code_base + emit->code_info_offset;
     103                 :     181136 :         emit->code_info_offset += num_bytes_to_write;
     104                 :     181136 :         return c;
     105                 :            :     }
     106                 :            : }
     107                 :            : 
     108                 :      41721 : static void emit_write_code_info_byte(emit_t *emit, byte val) {
     109                 :      41721 :     *emit_get_cur_to_write_code_info(emit, 1) = val;
     110                 :      41722 : }
     111                 :            : 
     112                 :      36153 : static void emit_write_code_info_qstr(emit_t *emit, qstr qst) {
     113                 :      36153 :     mp_encode_uint(emit, emit_get_cur_to_write_code_info, mp_emit_common_use_qstr(emit->emit_common, qst));
     114                 :      36153 : }
     115                 :            : 
     116                 :            : #if MICROPY_ENABLE_SOURCE_LINE
     117                 :     297847 : static void emit_write_code_info_bytes_lines(emit_t *emit, mp_uint_t bytes_to_skip, mp_uint_t lines_to_skip) {
     118         [ +  - ]:     297847 :     assert(bytes_to_skip > 0 || lines_to_skip > 0);
     119         [ +  + ]:     605112 :     while (bytes_to_skip > 0 || lines_to_skip > 0) {
     120                 :     307265 :         mp_uint_t b, l;
     121         [ +  + ]:     307265 :         if (lines_to_skip <= 6 || bytes_to_skip > 0xf) {
     122                 :            :             // use 0b0LLBBBBB encoding
     123                 :     288584 :             b = MIN(bytes_to_skip, 0x1f);
     124         [ +  + ]:     288584 :             if (b < bytes_to_skip) {
     125                 :            :                 // we can't skip any lines until we skip all the bytes
     126                 :            :                 l = 0;
     127                 :            :             } else {
     128                 :     288304 :                 l = MIN(lines_to_skip, 0x3);
     129                 :            :             }
     130                 :     288584 :             *emit_get_cur_to_write_code_info(emit, 1) = b | (l << 5);
     131                 :            :         } else {
     132                 :            :             // use 0b1LLLBBBB 0bLLLLLLLL encoding (l's LSB in second byte)
     133                 :      18681 :             b = MIN(bytes_to_skip, 0xf);
     134                 :      18681 :             l = MIN(lines_to_skip, 0x7ff);
     135                 :      18681 :             byte *ci = emit_get_cur_to_write_code_info(emit, 2);
     136                 :      18681 :             ci[0] = 0x80 | b | ((l >> 4) & 0x70);
     137                 :      18681 :             ci[1] = l;
     138                 :            :         }
     139                 :     307265 :         bytes_to_skip -= b;
     140                 :     307265 :         lines_to_skip -= l;
     141                 :            :     }
     142                 :     297847 : }
     143                 :            : #endif
     144                 :            : 
     145                 :            : // all functions must go through this one to emit byte code
     146                 :    2377042 : static uint8_t *emit_get_cur_to_write_bytecode(void *emit_in, size_t num_bytes_to_write) {
     147                 :    2377042 :     emit_t *emit = emit_in;
     148         [ +  + ]:    2377042 :     if (emit->suppress) {
     149                 :      10844 :         return emit->dummy_data;
     150                 :            :     }
     151         [ +  + ]:    2366198 :     if (emit->pass < MP_PASS_EMIT) {
     152                 :    1046343 :         emit->bytecode_offset += num_bytes_to_write;
     153                 :    1046343 :         return emit->dummy_data;
     154                 :            :     } else {
     155         [ -  + ]:    1319855 :         assert(emit->bytecode_offset + num_bytes_to_write <= emit->bytecode_size);
     156                 :    1319855 :         byte *c = emit->code_base + emit->code_info_size + emit->bytecode_offset;
     157                 :    1319855 :         emit->bytecode_offset += num_bytes_to_write;
     158                 :    1319855 :         return c;
     159                 :            :     }
     160                 :            : }
     161                 :            : 
     162                 :       1328 : static void emit_write_bytecode_raw_byte(emit_t *emit, byte b1) {
     163                 :       1328 :     byte *c = emit_get_cur_to_write_bytecode(emit, 1);
     164                 :       1328 :     c[0] = b1;
     165                 :       1328 : }
     166                 :            : 
     167                 :    1386872 : static void emit_write_bytecode_byte(emit_t *emit, int stack_adj, byte b1) {
     168                 :    1386872 :     mp_emit_bc_adjust_stack_size(emit, stack_adj);
     169                 :    1386869 :     byte *c = emit_get_cur_to_write_bytecode(emit, 1);
     170                 :    1386871 :     c[0] = b1;
     171                 :    1386871 : }
     172                 :            : 
     173                 :            : // Similar to mp_encode_uint(), just some extra handling to encode sign
     174                 :       7951 : static void emit_write_bytecode_byte_int(emit_t *emit, int stack_adj, byte b1, mp_int_t num) {
     175                 :       7951 :     emit_write_bytecode_byte(emit, stack_adj, b1);
     176                 :            : 
     177                 :            :     // We store each 7 bits in a separate byte, and that's how many bytes needed
     178                 :       7951 :     byte buf[MP_ENCODE_UINT_MAX_BYTES];
     179                 :       7951 :     byte *p = buf + sizeof(buf);
     180                 :            :     // We encode in little-ending order, but store in big-endian, to help decoding
     181                 :      16214 :     do {
     182                 :      16214 :         *--p = num & 0x7f;
     183                 :      16214 :         num >>= 7;
     184         [ +  + ]:      16214 :     } while (num != 0 && num != -1);
     185                 :            :     // Make sure that highest bit we stored (mask 0x40) matches sign
     186                 :            :     // of the number. If not, store extra byte just to encode sign
     187   [ +  +  +  + ]:       7842 :     if (num == -1 && (*p & 0x40) == 0) {
     188                 :        167 :         *--p = 0x7f;
     189   [ +  +  +  + ]:       7675 :     } else if (num == 0 && (*p & 0x40) != 0) {
     190                 :       2254 :         *--p = 0;
     191                 :            :     }
     192                 :            : 
     193                 :       7842 :     byte *c = emit_get_cur_to_write_bytecode(emit, buf + sizeof(buf) - p);
     194         [ +  + ]:      18635 :     while (p != buf + sizeof(buf) - 1) {
     195                 :      10793 :         *c++ = *p++ | 0x80;
     196                 :            :     }
     197                 :       7950 :     *c = *p;
     198                 :       7950 : }
     199                 :            : 
     200                 :     740604 : static void emit_write_bytecode_byte_uint(emit_t *emit, int stack_adj, byte b, mp_uint_t val) {
     201                 :     740604 :     emit_write_bytecode_byte(emit, stack_adj, b);
     202                 :     740598 :     mp_encode_uint(emit, emit_get_cur_to_write_bytecode, val);
     203                 :     740599 : }
     204                 :            : 
     205                 :      36058 : static void emit_write_bytecode_byte_const(emit_t *emit, int stack_adj, byte b, mp_uint_t n) {
     206                 :      36058 :     emit_write_bytecode_byte_uint(emit, stack_adj, b, n);
     207                 :      36058 : }
     208                 :            : 
     209                 :     360458 : static void emit_write_bytecode_byte_qstr(emit_t *emit, int stack_adj, byte b, qstr qst) {
     210                 :     360458 :     emit_write_bytecode_byte_uint(emit, stack_adj, b, mp_emit_common_use_qstr(emit->emit_common, qst));
     211                 :     360456 : }
     212                 :            : 
     213                 :      19849 : static void emit_write_bytecode_byte_obj(emit_t *emit, int stack_adj, byte b, mp_obj_t obj) {
     214                 :      19849 :     emit_write_bytecode_byte_const(emit, stack_adj, b, mp_emit_common_use_const_obj(emit->emit_common, obj));
     215                 :      19849 : }
     216                 :            : 
     217                 :      16209 : static void emit_write_bytecode_byte_child(emit_t *emit, int stack_adj, byte b, mp_raw_code_t *rc) {
     218         [ +  + ]:      19525 :     emit_write_bytecode_byte_const(emit, stack_adj, b,
     219                 :            :         mp_emit_common_alloc_const_child(emit->emit_common, rc));
     220                 :            :     #if MICROPY_PY_SYS_SETTRACE
     221                 :            :     rc->line_of_definition = emit->last_source_line;
     222                 :            :     #endif
     223                 :      16209 : }
     224                 :            : 
     225                 :            : // Emit a jump opcode to a destination label.
     226                 :            : // The offset to the label is relative to the ip following this instruction.
     227                 :            : // The offset is encoded as either 1 or 2 bytes, depending on how big it is.
     228                 :            : // The encoding of this jump opcode can change size from one pass to the next,
     229                 :            : // but it must only ever decrease in size on successive passes.
     230                 :     243809 : static void emit_write_bytecode_byte_label(emit_t *emit, int stack_adj, byte b1, mp_uint_t label) {
     231                 :     243809 :     mp_emit_bc_adjust_stack_size(emit, stack_adj);
     232                 :            : 
     233         [ +  + ]:     243809 :     if (emit->suppress) {
     234                 :            :         return;
     235                 :            :     }
     236                 :            : 
     237                 :            :     // Determine if the jump offset is signed or unsigned, based on the opcode.
     238                 :     240261 :     const bool is_signed = b1 <= MP_BC_POP_JUMP_IF_FALSE;
     239                 :            : 
     240                 :            :     // Default to a 2-byte encoding (the largest) with an unknown jump offset.
     241                 :     240261 :     unsigned int jump_encoding_size = 1;
     242                 :     240261 :     ssize_t bytecode_offset = 0;
     243                 :            : 
     244                 :            :     // Compute the jump size and offset only when code size is known.
     245         [ +  + ]:     240261 :     if (emit->pass >= MP_PASS_CODE_SIZE) {
     246                 :            :         // The -2 accounts for this jump opcode taking 2 bytes (at least).
     247                 :     189343 :         bytecode_offset = emit->label_offsets[label] - emit->bytecode_offset - 2;
     248                 :            : 
     249                 :            :         // Check if the bytecode_offset is small enough to use a 1-byte encoding.
     250   [ +  +  +  + ]:     189343 :         if ((is_signed && -64 <= bytecode_offset && bytecode_offset <= 63)
     251         [ +  + ]:     159581 :             || (!is_signed && (size_t)bytecode_offset <= 127)) {
     252                 :            :             // Use a 1-byte jump offset.
     253                 :     118224 :             jump_encoding_size = 0;
     254                 :            :         }
     255                 :            : 
     256                 :            :         // Adjust the offset depending on the size of the encoding of the offset.
     257                 :     189343 :         bytecode_offset -= jump_encoding_size;
     258                 :            : 
     259         [ -  + ]:     189343 :         assert(is_signed || bytecode_offset >= 0);
     260                 :            :     }
     261                 :            : 
     262                 :            :     // Emit the opcode.
     263                 :     240261 :     byte *c = emit_get_cur_to_write_bytecode(emit, 2 + jump_encoding_size);
     264                 :     240261 :     c[0] = b1;
     265         [ +  + ]:     240261 :     if (jump_encoding_size == 0) {
     266         [ +  + ]:     118224 :         if (is_signed) {
     267                 :      29762 :             bytecode_offset += 0x40;
     268                 :            :         }
     269         [ -  + ]:     118224 :         assert(0 <= bytecode_offset && bytecode_offset <= 0x7f);
     270                 :     118224 :         c[1] = bytecode_offset;
     271                 :            :     } else {
     272         [ +  + ]:     122037 :         if (is_signed) {
     273                 :      36211 :             bytecode_offset += 0x4000;
     274                 :            :         }
     275   [ +  +  +  + ]:     122037 :         if (emit->pass == MP_PASS_EMIT && !(0 <= bytecode_offset && bytecode_offset <= 0x7fff)) {
     276                 :         69 :             emit->overflow = true;
     277                 :            :         }
     278                 :     122037 :         c[1] = 0x80 | (bytecode_offset & 0x7f);
     279                 :     122037 :         c[2] = bytecode_offset >> 7;
     280                 :            :     }
     281                 :            : }
     282                 :            : 
     283                 :      26427 : void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
     284                 :      26427 :     emit->pass = pass;
     285                 :      26427 :     emit->stack_size = 0;
     286                 :      26427 :     emit->suppress = false;
     287                 :      26427 :     emit->scope = scope;
     288                 :      26427 :     emit->last_source_line_offset = 0;
     289                 :      26427 :     emit->last_source_line = 1;
     290                 :      26427 :     emit->bytecode_offset = 0;
     291                 :      26427 :     emit->code_info_offset = 0;
     292                 :      26427 :     emit->overflow = false;
     293                 :            : 
     294                 :            :     // Write local state size, exception stack size, scope flags and number of arguments
     295                 :            :     {
     296                 :      26427 :         mp_uint_t n_state = scope->num_locals + scope->stack_size;
     297         [ +  + ]:      26427 :         if (n_state == 0) {
     298                 :            :             // Need at least 1 entry in the state, in the case an exception is
     299                 :            :             // propagated through this function, the exception is returned in
     300                 :            :             // the highest slot in the state (fastn[0], see vm.c).
     301                 :      13503 :             n_state = 1;
     302                 :            :         }
     303                 :            :         #if MICROPY_DEBUG_VM_STACK_OVERFLOW
     304                 :            :         // An extra slot in the stack is needed to detect VM stack overflow
     305                 :            :         n_state += 1;
     306                 :            :         #endif
     307                 :            : 
     308                 :      26427 :         size_t n_exc_stack = scope->exc_stack_size;
     309         [ +  + ]:      30379 :         MP_BC_PRELUDE_SIG_ENCODE(n_state, n_exc_stack, scope, emit_write_code_info_byte, emit);
     310                 :            :     }
     311                 :            : 
     312                 :            :     // Write number of cells and size of the source code info
     313         [ +  + ]:      26426 :     if (emit->pass >= MP_PASS_CODE_SIZE) {
     314                 :      10817 :         size_t n_info = emit->n_info;
     315                 :      10817 :         size_t n_cell = emit->n_cell;
     316   [ +  +  +  + ]:      11008 :         MP_BC_PRELUDE_SIZE_ENCODE(n_info, n_cell, emit_write_code_info_byte, emit);
     317                 :            :     }
     318                 :            : 
     319                 :      26426 :     emit->n_info = emit->code_info_offset;
     320                 :            : 
     321                 :            :     // Write the name of this function.
     322                 :      26426 :     emit_write_code_info_qstr(emit, scope->simple_name);
     323                 :            : 
     324                 :            :     // Write argument names, needed to resolve positional args passed as keywords.
     325                 :            :     {
     326                 :            :         // For a given argument position (indexed by i) we need to find the
     327                 :            :         // corresponding id_info which is a parameter, as it has the correct
     328                 :            :         // qstr name to use as the argument name.  Note that it's not a simple
     329                 :            :         // 1-1 mapping (ie i!=j in general) because of possible closed-over
     330                 :            :         // variables.  In the case that the argument i has no corresponding
     331                 :            :         // parameter we use "*" as its name (since no argument can ever be named
     332                 :            :         // "*").  We could use a blank qstr but "*" is better for debugging.
     333                 :            :         // Note: there is some wasted RAM here for the case of storing a qstr
     334                 :            :         // for each closed-over variable, and maybe there is a better way to do
     335                 :            :         // it, but that would require changes to mp_setup_code_state.
     336         [ +  + ]:      36153 :         for (int i = 0; i < scope->num_pos_args + scope->num_kwonly_args; i++) {
     337                 :      17553 :             qstr qst = MP_QSTR__star_;
     338         [ +  + ]:      17553 :             for (int j = 0; j < scope->id_info_len; ++j) {
     339                 :      16842 :                 id_info_t *id = &scope->id_info[j];
     340   [ +  +  +  + ]:      16842 :                 if ((id->flags & ID_FLAG_IS_PARAM) && id->local_num == i) {
     341                 :       9016 :                     qst = id->qst;
     342                 :       9016 :                     break;
     343                 :            :                 }
     344                 :            :             }
     345                 :       9727 :             emit_write_code_info_qstr(emit, qst);
     346                 :            :         }
     347                 :            :     }
     348                 :      26425 : }
     349                 :            : 
     350                 :      26422 : bool mp_emit_bc_end_pass(emit_t *emit) {
     351         [ +  + ]:      26422 :     if (emit->pass == MP_PASS_SCOPE) {
     352                 :            :         return true;
     353                 :            :     }
     354                 :            : 
     355                 :            :     // check stack is back to zero size
     356         [ -  + ]:      16154 :     assert(emit->stack_size == 0);
     357                 :            : 
     358                 :            :     // Calculate size of source code info section
     359                 :      16154 :     emit->n_info = emit->code_info_offset - emit->n_info;
     360                 :            : 
     361                 :            :     // Emit closure section of prelude
     362                 :      16154 :     emit->n_cell = 0;
     363         [ +  + ]:      82548 :     for (size_t i = 0; i < emit->scope->id_info_len; ++i) {
     364                 :      66392 :         id_info_t *id = &emit->scope->id_info[i];
     365         [ +  + ]:      66392 :         if (id->kind == ID_INFO_KIND_CELL) {
     366         [ -  + ]:        336 :             assert(id->local_num <= 255);
     367                 :        336 :             emit_write_code_info_byte(emit, id->local_num); // write the local which should be converted to a cell
     368                 :        338 :             ++emit->n_cell;
     369                 :            :         }
     370                 :            :     }
     371                 :            : 
     372         [ +  + ]:      16156 :     if (emit->pass == MP_PASS_CODE_SIZE) {
     373                 :            :         // calculate size of total code-info + bytecode, in bytes
     374                 :       5337 :         emit->code_info_size = emit->code_info_offset;
     375                 :       5337 :         emit->bytecode_size = emit->bytecode_offset;
     376                 :       5337 :         emit->code_base = m_new0(byte, emit->code_info_size + emit->bytecode_size);
     377                 :            : 
     378         [ +  + ]:      10819 :     } else if (emit->pass == MP_PASS_EMIT) {
     379                 :            :         // Code info and/or bytecode can shrink during this pass.
     380         [ -  + ]:       5481 :         assert(emit->code_info_offset <= emit->code_info_size);
     381         [ -  + ]:       5481 :         assert(emit->bytecode_offset <= emit->bytecode_size);
     382                 :            : 
     383         [ +  + ]:       5481 :         if (emit->code_info_offset != emit->code_info_size
     384         [ +  + ]:       5480 :             || emit->bytecode_offset != emit->bytecode_size) {
     385                 :            :             // Code info and/or bytecode changed size in this pass, so request the
     386                 :            :             // compiler to do another pass with these updated sizes.
     387                 :        143 :             emit->code_info_size = emit->code_info_offset;
     388                 :        143 :             emit->bytecode_size = emit->bytecode_offset;
     389                 :        143 :             return false;
     390                 :            :         }
     391                 :            : 
     392         [ +  + ]:       5338 :         if (emit->overflow) {
     393                 :          2 :             mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("bytecode overflow"));
     394                 :            :         }
     395                 :            : 
     396                 :            :         #if MICROPY_PERSISTENT_CODE_SAVE || MICROPY_DEBUG_PRINTERS
     397                 :       5336 :         size_t bytecode_len = emit->code_info_size + emit->bytecode_size;
     398                 :            :         #if MICROPY_DEBUG_PRINTERS
     399                 :       5336 :         emit->scope->raw_code_data_len = bytecode_len;
     400                 :            :         #endif
     401                 :            :         #endif
     402                 :            : 
     403                 :            :         // Bytecode is finalised, assign it to the raw code object.
     404                 :       5336 :         mp_emit_glue_assign_bytecode(emit->scope->raw_code, emit->code_base,
     405                 :       5336 :             emit->emit_common->children,
     406                 :            :             #if MICROPY_PERSISTENT_CODE_SAVE
     407                 :            :             bytecode_len,
     408                 :            :             emit->emit_common->ct_cur_child,
     409                 :            :             #endif
     410                 :       5336 :             emit->scope->scope_flags);
     411                 :            :     }
     412                 :            : 
     413                 :            :     return true;
     414                 :            : }
     415                 :            : 
     416                 :    1810917 : void mp_emit_bc_adjust_stack_size(emit_t *emit, mp_int_t delta) {
     417         [ +  + ]:    1810917 :     if (emit->pass == MP_PASS_SCOPE) {
     418                 :            :         return;
     419                 :            :     }
     420         [ -  + ]:    1507918 :     assert((mp_int_t)emit->stack_size + delta >= 0);
     421                 :    1507918 :     emit->stack_size += delta;
     422         [ +  + ]:    1507918 :     if (emit->stack_size > emit->scope->stack_size) {
     423                 :      19763 :         emit->scope->stack_size = emit->stack_size;
     424                 :            :     }
     425                 :            : }
     426                 :            : 
     427                 :     896555 : void mp_emit_bc_set_source_line(emit_t *emit, mp_uint_t source_line) {
     428                 :            :     #if MICROPY_ENABLE_SOURCE_LINE
     429         [ +  + ]:     896555 :     if (MP_STATE_VM(mp_optimise_value) >= 3) {
     430                 :            :         // If we compile with -O3, don't store line numbers.
     431                 :            :         return;
     432                 :            :     }
     433         [ +  + ]:     896507 :     if (source_line > emit->last_source_line) {
     434                 :     297847 :         mp_uint_t bytes_to_skip = emit->bytecode_offset - emit->last_source_line_offset;
     435                 :     297847 :         mp_uint_t lines_to_skip = source_line - emit->last_source_line;
     436                 :     297847 :         emit_write_code_info_bytes_lines(emit, bytes_to_skip, lines_to_skip);
     437                 :     297847 :         emit->last_source_line_offset = emit->bytecode_offset;
     438                 :     297847 :         emit->last_source_line = source_line;
     439                 :            :     }
     440                 :            :     #else
     441                 :            :     (void)emit;
     442                 :            :     (void)source_line;
     443                 :            :     #endif
     444                 :            : }
     445                 :            : 
     446                 :     253116 : void mp_emit_bc_label_assign(emit_t *emit, mp_uint_t l) {
     447                 :            :     // Assigning a label ends any dead-code region, and all following opcodes
     448                 :            :     // should be emitted (until another unconditional flow control).
     449                 :     253116 :     emit->suppress = false;
     450                 :            : 
     451         [ +  + ]:     253116 :     if (emit->pass == MP_PASS_SCOPE) {
     452                 :            :         return;
     453                 :            :     }
     454                 :            : 
     455                 :            :     // Label offsets can change from one pass to the next, but they must only
     456                 :            :     // decrease (ie code can only shrink).  There will be multiple MP_PASS_EMIT
     457                 :            :     // stages until the labels no longer change, which is when the code size
     458                 :            :     // stays constant after a MP_PASS_EMIT.
     459         [ -  + ]:     217422 :     assert(l < emit->max_num_labels);
     460   [ +  +  -  + ]:     217422 :     assert(emit->pass == MP_PASS_STACK_SIZE || emit->bytecode_offset <= emit->label_offsets[l]);
     461                 :            : 
     462                 :            :     // Assign label offset.
     463                 :     217422 :     emit->label_offsets[l] = emit->bytecode_offset;
     464                 :            : }
     465                 :            : 
     466                 :       6603 : void mp_emit_bc_import(emit_t *emit, qstr qst, int kind) {
     467                 :       6603 :     MP_STATIC_ASSERT(MP_BC_IMPORT_NAME + MP_EMIT_IMPORT_NAME == MP_BC_IMPORT_NAME);
     468                 :       6603 :     MP_STATIC_ASSERT(MP_BC_IMPORT_NAME + MP_EMIT_IMPORT_FROM == MP_BC_IMPORT_FROM);
     469         [ +  + ]:       6603 :     int stack_adj = kind == MP_EMIT_IMPORT_FROM ? 1 : -1;
     470         [ +  + ]:       4831 :     if (kind == MP_EMIT_IMPORT_STAR) {
     471                 :        215 :         emit_write_bytecode_byte(emit, stack_adj, MP_BC_IMPORT_STAR);
     472                 :            :     } else {
     473                 :       6388 :         emit_write_bytecode_byte_qstr(emit, stack_adj, MP_BC_IMPORT_NAME + kind, qst);
     474                 :            :     }
     475                 :       6603 : }
     476                 :            : 
     477                 :      83044 : void mp_emit_bc_load_const_tok(emit_t *emit, mp_token_kind_t tok) {
     478                 :      83044 :     MP_STATIC_ASSERT(MP_BC_LOAD_CONST_FALSE + (MP_TOKEN_KW_NONE - MP_TOKEN_KW_FALSE) == MP_BC_LOAD_CONST_NONE);
     479                 :      83044 :     MP_STATIC_ASSERT(MP_BC_LOAD_CONST_FALSE + (MP_TOKEN_KW_TRUE - MP_TOKEN_KW_FALSE) == MP_BC_LOAD_CONST_TRUE);
     480         [ +  + ]:      83044 :     if (tok == MP_TOKEN_ELLIPSIS) {
     481                 :         12 :         emit_write_bytecode_byte_obj(emit, 1, MP_BC_LOAD_CONST_OBJ, MP_OBJ_FROM_PTR(&mp_const_ellipsis_obj));
     482                 :            :     } else {
     483                 :      83032 :         emit_write_bytecode_byte(emit, 1, MP_BC_LOAD_CONST_FALSE + (tok - MP_TOKEN_KW_FALSE));
     484                 :            :     }
     485                 :      83046 : }
     486                 :            : 
     487                 :      67438 : void mp_emit_bc_load_const_small_int(emit_t *emit, mp_int_t arg) {
     488         [ -  + ]:      67438 :     assert(MP_SMALL_INT_FITS(arg));
     489                 :      67438 :     if (-MP_BC_LOAD_CONST_SMALL_INT_MULTI_EXCESS <= arg
     490         [ +  + ]:      67438 :         && arg < MP_BC_LOAD_CONST_SMALL_INT_MULTI_NUM - MP_BC_LOAD_CONST_SMALL_INT_MULTI_EXCESS) {
     491                 :      59487 :         emit_write_bytecode_byte(emit, 1,
     492                 :      59487 :             MP_BC_LOAD_CONST_SMALL_INT_MULTI + MP_BC_LOAD_CONST_SMALL_INT_MULTI_EXCESS + arg);
     493                 :            :     } else {
     494                 :       7951 :         emit_write_bytecode_byte_int(emit, 1, MP_BC_LOAD_CONST_SMALL_INT, arg);
     495                 :            :     }
     496                 :      67437 : }
     497                 :            : 
     498                 :      45518 : void mp_emit_bc_load_const_str(emit_t *emit, qstr qst) {
     499                 :      45518 :     emit_write_bytecode_byte_qstr(emit, 1, MP_BC_LOAD_CONST_STRING, qst);
     500                 :      45517 : }
     501                 :            : 
     502                 :      19837 : void mp_emit_bc_load_const_obj(emit_t *emit, mp_obj_t obj) {
     503                 :      19837 :     emit_write_bytecode_byte_obj(emit, 1, MP_BC_LOAD_CONST_OBJ, obj);
     504                 :      19837 : }
     505                 :            : 
     506                 :       2082 : void mp_emit_bc_load_null(emit_t *emit) {
     507                 :       2082 :     emit_write_bytecode_byte(emit, 1, MP_BC_LOAD_NULL);
     508                 :       2082 : }
     509                 :            : 
     510                 :      30524 : void mp_emit_bc_load_local(emit_t *emit, qstr qst, mp_uint_t local_num, int kind) {
     511                 :      30524 :     MP_STATIC_ASSERT(MP_BC_LOAD_FAST_N + MP_EMIT_IDOP_LOCAL_FAST == MP_BC_LOAD_FAST_N);
     512                 :      30524 :     MP_STATIC_ASSERT(MP_BC_LOAD_FAST_N + MP_EMIT_IDOP_LOCAL_DEREF == MP_BC_LOAD_DEREF);
     513                 :      30524 :     (void)qst;
     514         [ +  + ]:      30524 :     if (kind == MP_EMIT_IDOP_LOCAL_FAST && local_num <= 15) {
     515                 :      29631 :         emit_write_bytecode_byte(emit, 1, MP_BC_LOAD_FAST_MULTI + local_num);
     516                 :            :     } else {
     517                 :        893 :         emit_write_bytecode_byte_uint(emit, 1, MP_BC_LOAD_FAST_N + kind, local_num);
     518                 :            :     }
     519                 :      30524 : }
     520                 :            : 
     521                 :     196930 : void mp_emit_bc_load_global(emit_t *emit, qstr qst, int kind) {
     522                 :     196930 :     MP_STATIC_ASSERT(MP_BC_LOAD_NAME + MP_EMIT_IDOP_GLOBAL_NAME == MP_BC_LOAD_NAME);
     523                 :     196930 :     MP_STATIC_ASSERT(MP_BC_LOAD_NAME + MP_EMIT_IDOP_GLOBAL_GLOBAL == MP_BC_LOAD_GLOBAL);
     524                 :     196930 :     (void)qst;
     525                 :     196930 :     emit_write_bytecode_byte_qstr(emit, 1, MP_BC_LOAD_NAME + kind, qst);
     526                 :     196931 : }
     527                 :            : 
     528                 :      28158 : void mp_emit_bc_load_method(emit_t *emit, qstr qst, bool is_super) {
     529                 :      28158 :     int stack_adj = 1 - 2 * is_super;
     530         [ +  + ]:      56203 :     emit_write_bytecode_byte_qstr(emit, stack_adj, is_super ? MP_BC_LOAD_SUPER_METHOD : MP_BC_LOAD_METHOD, qst);
     531                 :      28158 : }
     532                 :            : 
     533                 :       2628 : void mp_emit_bc_load_build_class(emit_t *emit) {
     534                 :       2628 :     emit_write_bytecode_byte(emit, 1, MP_BC_LOAD_BUILD_CLASS);
     535                 :       2628 : }
     536                 :            : 
     537                 :      10079 : void mp_emit_bc_subscr(emit_t *emit, int kind) {
     538         [ +  + ]:      10079 :     if (kind == MP_EMIT_SUBSCR_LOAD) {
     539                 :       7201 :         emit_write_bytecode_byte(emit, -1, MP_BC_LOAD_SUBSCR);
     540                 :            :     } else {
     541         [ +  + ]:       2878 :         if (kind == MP_EMIT_SUBSCR_DELETE) {
     542                 :        318 :             mp_emit_bc_load_null(emit);
     543                 :        318 :             mp_emit_bc_rot_three(emit);
     544                 :            :         }
     545                 :       2878 :         emit_write_bytecode_byte(emit, -3, MP_BC_STORE_SUBSCR);
     546                 :            :     }
     547                 :      10079 : }
     548                 :            : 
     549                 :      22300 : void mp_emit_bc_attr(emit_t *emit, qstr qst, int kind) {
     550         [ +  + ]:      22300 :     if (kind == MP_EMIT_ATTR_LOAD) {
     551                 :      17797 :         emit_write_bytecode_byte_qstr(emit, 0, MP_BC_LOAD_ATTR, qst);
     552                 :            :     } else {
     553         [ +  + ]:       4503 :         if (kind == MP_EMIT_ATTR_DELETE) {
     554                 :         84 :             mp_emit_bc_load_null(emit);
     555                 :         84 :             mp_emit_bc_rot_two(emit);
     556                 :            :         }
     557                 :       4503 :         emit_write_bytecode_byte_qstr(emit, -2, MP_BC_STORE_ATTR, qst);
     558                 :            :     }
     559                 :      22300 : }
     560                 :            : 
     561                 :       8016 : void mp_emit_bc_store_local(emit_t *emit, qstr qst, mp_uint_t local_num, int kind) {
     562                 :       8016 :     MP_STATIC_ASSERT(MP_BC_STORE_FAST_N + MP_EMIT_IDOP_LOCAL_FAST == MP_BC_STORE_FAST_N);
     563                 :       8016 :     MP_STATIC_ASSERT(MP_BC_STORE_FAST_N + MP_EMIT_IDOP_LOCAL_DEREF == MP_BC_STORE_DEREF);
     564                 :       8016 :     (void)qst;
     565         [ +  + ]:       8016 :     if (kind == MP_EMIT_IDOP_LOCAL_FAST && local_num <= 15) {
     566                 :       7185 :         emit_write_bytecode_byte(emit, -1, MP_BC_STORE_FAST_MULTI + local_num);
     567                 :            :     } else {
     568                 :        831 :         emit_write_bytecode_byte_uint(emit, -1, MP_BC_STORE_FAST_N + kind, local_num);
     569                 :            :     }
     570                 :       8016 : }
     571                 :            : 
     572                 :      60733 : void mp_emit_bc_store_global(emit_t *emit, qstr qst, int kind) {
     573                 :      60733 :     MP_STATIC_ASSERT(MP_BC_STORE_NAME + MP_EMIT_IDOP_GLOBAL_NAME == MP_BC_STORE_NAME);
     574                 :      60733 :     MP_STATIC_ASSERT(MP_BC_STORE_NAME + MP_EMIT_IDOP_GLOBAL_GLOBAL == MP_BC_STORE_GLOBAL);
     575                 :      60733 :     emit_write_bytecode_byte_qstr(emit, -1, MP_BC_STORE_NAME + kind, qst);
     576                 :      60733 : }
     577                 :            : 
     578                 :        410 : void mp_emit_bc_delete_local(emit_t *emit, qstr qst, mp_uint_t local_num, int kind) {
     579                 :        410 :     MP_STATIC_ASSERT(MP_BC_DELETE_FAST + MP_EMIT_IDOP_LOCAL_FAST == MP_BC_DELETE_FAST);
     580                 :        410 :     MP_STATIC_ASSERT(MP_BC_DELETE_FAST + MP_EMIT_IDOP_LOCAL_DEREF == MP_BC_DELETE_DEREF);
     581                 :        410 :     (void)qst;
     582                 :        410 :     emit_write_bytecode_byte_uint(emit, 0, MP_BC_DELETE_FAST + kind, local_num);
     583                 :        410 : }
     584                 :            : 
     585                 :        433 : void mp_emit_bc_delete_global(emit_t *emit, qstr qst, int kind) {
     586                 :        433 :     MP_STATIC_ASSERT(MP_BC_DELETE_NAME + MP_EMIT_IDOP_GLOBAL_NAME == MP_BC_DELETE_NAME);
     587                 :        433 :     MP_STATIC_ASSERT(MP_BC_DELETE_NAME + MP_EMIT_IDOP_GLOBAL_GLOBAL == MP_BC_DELETE_GLOBAL);
     588                 :        433 :     emit_write_bytecode_byte_qstr(emit, 0, MP_BC_DELETE_NAME + kind, qst);
     589                 :        433 : }
     590                 :            : 
     591                 :      47641 : void mp_emit_bc_dup_top(emit_t *emit) {
     592                 :      47641 :     emit_write_bytecode_byte(emit, 1, MP_BC_DUP_TOP);
     593                 :      47641 : }
     594                 :            : 
     595                 :        745 : void mp_emit_bc_dup_top_two(emit_t *emit) {
     596                 :        745 :     emit_write_bytecode_byte(emit, 2, MP_BC_DUP_TOP_TWO);
     597                 :        745 : }
     598                 :            : 
     599                 :     150762 : void mp_emit_bc_pop_top(emit_t *emit) {
     600                 :     150762 :     emit_write_bytecode_byte(emit, -1, MP_BC_POP_TOP);
     601                 :     150761 : }
     602                 :            : 
     603                 :       1300 : void mp_emit_bc_rot_two(emit_t *emit) {
     604                 :       1300 :     emit_write_bytecode_byte(emit, 0, MP_BC_ROT_TWO);
     605                 :       1300 : }
     606                 :            : 
     607                 :        857 : void mp_emit_bc_rot_three(emit_t *emit) {
     608                 :        857 :     emit_write_bytecode_byte(emit, 0, MP_BC_ROT_THREE);
     609                 :        857 : }
     610                 :            : 
     611                 :       9236 : void mp_emit_bc_jump(emit_t *emit, mp_uint_t label) {
     612                 :       9236 :     emit_write_bytecode_byte_label(emit, 0, MP_BC_JUMP, label);
     613                 :       9236 :     emit->suppress = true;
     614                 :       9236 : }
     615                 :            : 
     616                 :      56691 : void mp_emit_bc_pop_jump_if(emit_t *emit, bool cond, mp_uint_t label) {
     617         [ +  + ]:      56691 :     if (cond) {
     618                 :       5163 :         emit_write_bytecode_byte_label(emit, -1, MP_BC_POP_JUMP_IF_TRUE, label);
     619                 :            :     } else {
     620                 :      51528 :         emit_write_bytecode_byte_label(emit, -1, MP_BC_POP_JUMP_IF_FALSE, label);
     621                 :            :     }
     622                 :      56691 : }
     623                 :            : 
     624                 :        505 : void mp_emit_bc_jump_if_or_pop(emit_t *emit, bool cond, mp_uint_t label) {
     625         [ +  + ]:        505 :     if (cond) {
     626                 :        255 :         emit_write_bytecode_byte_label(emit, -1, MP_BC_JUMP_IF_TRUE_OR_POP, label);
     627                 :            :     } else {
     628                 :        250 :         emit_write_bytecode_byte_label(emit, -1, MP_BC_JUMP_IF_FALSE_OR_POP, label);
     629                 :            :     }
     630                 :        505 : }
     631                 :            : 
     632                 :        777 : void mp_emit_bc_unwind_jump(emit_t *emit, mp_uint_t label, mp_uint_t except_depth) {
     633         [ +  + ]:        777 :     if (except_depth == 0) {
     634         [ +  + ]:        535 :         if (label & MP_EMIT_BREAK_FROM_FOR) {
     635                 :            :             // need to pop the iterator if we are breaking out of a for loop
     636                 :        203 :             emit_write_bytecode_raw_byte(emit, MP_BC_POP_TOP);
     637                 :            :             // also pop the iter_buf
     638         [ +  + ]:        812 :             for (size_t i = 0; i < MP_OBJ_ITER_BUF_NSLOTS - 1; ++i) {
     639                 :        609 :                 emit_write_bytecode_raw_byte(emit, MP_BC_POP_TOP);
     640                 :            :             }
     641                 :            :         }
     642                 :        535 :         emit_write_bytecode_byte_label(emit, 0, MP_BC_JUMP, label & ~MP_EMIT_BREAK_FROM_FOR);
     643                 :            :     } else {
     644                 :        242 :         emit_write_bytecode_byte_label(emit, 0, MP_BC_UNWIND_JUMP, label & ~MP_EMIT_BREAK_FROM_FOR);
     645                 :        242 :         emit_write_bytecode_raw_byte(emit, ((label & MP_EMIT_BREAK_FROM_FOR) ? 0x80 : 0) | except_depth);
     646                 :            :     }
     647                 :        777 :     emit->suppress = true;
     648                 :        777 : }
     649                 :            : 
     650                 :      83744 : void mp_emit_bc_setup_block(emit_t *emit, mp_uint_t label, int kind) {
     651                 :      83744 :     MP_STATIC_ASSERT(MP_BC_SETUP_WITH + MP_EMIT_SETUP_BLOCK_WITH == MP_BC_SETUP_WITH);
     652                 :      83744 :     MP_STATIC_ASSERT(MP_BC_SETUP_WITH + MP_EMIT_SETUP_BLOCK_EXCEPT == MP_BC_SETUP_EXCEPT);
     653                 :      83744 :     MP_STATIC_ASSERT(MP_BC_SETUP_WITH + MP_EMIT_SETUP_BLOCK_FINALLY == MP_BC_SETUP_FINALLY);
     654                 :            :     // The SETUP_WITH opcode pops ctx_mgr from the top of the stack
     655                 :            :     // and then pushes 3 entries: __exit__, ctx_mgr, as_value.
     656         [ +  + ]:      83744 :     int stack_adj = kind == MP_EMIT_SETUP_BLOCK_WITH ? 2 : 0;
     657                 :      83744 :     emit_write_bytecode_byte_label(emit, stack_adj, MP_BC_SETUP_WITH + kind, label);
     658                 :      83744 : }
     659                 :            : 
     660                 :      36708 : void mp_emit_bc_with_cleanup(emit_t *emit, mp_uint_t label) {
     661                 :      36708 :     mp_emit_bc_load_const_tok(emit, MP_TOKEN_KW_NONE);
     662                 :      36708 :     mp_emit_bc_label_assign(emit, label);
     663                 :            :     // The +2 is to ensure we have enough stack space to call the __exit__ method
     664                 :      36708 :     emit_write_bytecode_byte(emit, 2, MP_BC_WITH_CLEANUP);
     665                 :            :     // Cancel the +2 above, plus the +2 from mp_emit_bc_setup_block(MP_EMIT_SETUP_BLOCK_WITH)
     666                 :      36708 :     mp_emit_bc_adjust_stack_size(emit, -4);
     667                 :      36708 : }
     668                 :            : 
     669                 :            : #if MICROPY_PY_ASYNC_AWAIT
     670                 :         70 : void mp_emit_bc_async_with_setup_finally(emit_t *emit, mp_uint_t label_aexit_no_exc, mp_uint_t label_finally_block, mp_uint_t label_ret_unwind_jump) {
     671                 :            :     // The async-with body has executed and no exception was raised, the execution fell through to this point.
     672                 :            :     // Stack: (..., ctx_mgr)
     673                 :            : 
     674                 :            :     // Finish async-with body and prepare to enter "finally" block.
     675                 :         70 :     mp_emit_bc_load_const_tok(emit, MP_TOKEN_KW_NONE); // to tell end_finally there's no exception
     676                 :         70 :     mp_emit_bc_rot_two(emit);
     677                 :         70 :     mp_emit_bc_jump(emit, label_aexit_no_exc); // jump to code to call __aexit__
     678                 :            : 
     679                 :            :     // Start of "finally" block which is entered via one of: an exception propagating out, a return, an unwind jump.
     680                 :         70 :     mp_emit_bc_label_assign(emit, label_finally_block);
     681                 :            : 
     682                 :            :     // Detect which case we have by the TOS being an exception or not.
     683                 :         70 :     mp_emit_bc_dup_top(emit);
     684                 :         70 :     mp_emit_bc_load_global(emit, MP_QSTR_BaseException, MP_EMIT_IDOP_GLOBAL_GLOBAL);
     685                 :         70 :     mp_emit_bc_binary_op(emit, MP_BINARY_OP_EXCEPTION_MATCH);
     686                 :         70 :     mp_emit_bc_pop_jump_if(emit, false, label_ret_unwind_jump); // if not an exception then we have return or unwind jump.
     687                 :         70 : }
     688                 :            : #endif
     689                 :            : 
     690                 :      83744 : void mp_emit_bc_end_finally(emit_t *emit) {
     691                 :      83744 :     emit_write_bytecode_byte(emit, -1, MP_BC_END_FINALLY);
     692                 :      83744 : }
     693                 :            : 
     694                 :       4125 : void mp_emit_bc_get_iter(emit_t *emit, bool use_stack) {
     695         [ +  + ]:       4125 :     int stack_adj = use_stack ? MP_OBJ_ITER_BUF_NSLOTS - 1 : 0;
     696                 :       4125 :     emit_write_bytecode_byte(emit, stack_adj, use_stack ? MP_BC_GET_ITER_STACK : MP_BC_GET_ITER);
     697                 :       4125 : }
     698                 :            : 
     699                 :       2537 : void mp_emit_bc_for_iter(emit_t *emit, mp_uint_t label) {
     700                 :       2537 :     emit_write_bytecode_byte_label(emit, 1, MP_BC_FOR_ITER, label);
     701                 :       2537 : }
     702                 :            : 
     703                 :       2537 : void mp_emit_bc_for_iter_end(emit_t *emit) {
     704                 :       2537 :     mp_emit_bc_adjust_stack_size(emit, -MP_OBJ_ITER_BUF_NSLOTS);
     705                 :       2537 : }
     706                 :            : 
     707                 :      90319 : void mp_emit_bc_pop_except_jump(emit_t *emit, mp_uint_t label, bool within_exc_handler) {
     708                 :      90319 :     (void)within_exc_handler;
     709                 :      90319 :     emit_write_bytecode_byte_label(emit, 0, MP_BC_POP_EXCEPT_JUMP, label);
     710                 :      90319 :     emit->suppress = true;
     711                 :      90319 : }
     712                 :            : 
     713                 :       2240 : void mp_emit_bc_unary_op(emit_t *emit, mp_unary_op_t op) {
     714                 :       2240 :     emit_write_bytecode_byte(emit, 0, MP_BC_UNARY_OP_MULTI + op);
     715                 :       2240 : }
     716                 :            : 
     717                 :      70139 : void mp_emit_bc_binary_op(emit_t *emit, mp_binary_op_t op) {
     718                 :      70139 :     bool invert = false;
     719         [ +  + ]:      70139 :     if (op == MP_BINARY_OP_NOT_IN) {
     720                 :            :         invert = true;
     721                 :            :         op = MP_BINARY_OP_IN;
     722         [ +  + ]:      69879 :     } else if (op == MP_BINARY_OP_IS_NOT) {
     723                 :       1060 :         invert = true;
     724                 :       1060 :         op = MP_BINARY_OP_IS;
     725                 :            :     }
     726                 :      70139 :     emit_write_bytecode_byte(emit, -1, MP_BC_BINARY_OP_MULTI + op);
     727         [ +  + ]:      70139 :     if (invert) {
     728                 :       1320 :         emit_write_bytecode_byte(emit, 0, MP_BC_UNARY_OP_MULTI + MP_UNARY_OP_NOT);
     729                 :            :     }
     730                 :      70139 : }
     731                 :            : 
     732                 :      13091 : void mp_emit_bc_build(emit_t *emit, mp_uint_t n_args, int kind) {
     733                 :      13091 :     MP_STATIC_ASSERT(MP_BC_BUILD_TUPLE + MP_EMIT_BUILD_TUPLE == MP_BC_BUILD_TUPLE);
     734                 :      13091 :     MP_STATIC_ASSERT(MP_BC_BUILD_TUPLE + MP_EMIT_BUILD_LIST == MP_BC_BUILD_LIST);
     735                 :      13091 :     MP_STATIC_ASSERT(MP_BC_BUILD_TUPLE + MP_EMIT_BUILD_MAP == MP_BC_BUILD_MAP);
     736                 :      13091 :     MP_STATIC_ASSERT(MP_BC_BUILD_TUPLE + MP_EMIT_BUILD_SET == MP_BC_BUILD_SET);
     737                 :      13091 :     MP_STATIC_ASSERT(MP_BC_BUILD_TUPLE + MP_EMIT_BUILD_SLICE == MP_BC_BUILD_SLICE);
     738         [ +  + ]:      13091 :     int stack_adj = kind == MP_EMIT_BUILD_MAP ? 1 : 1 - n_args;
     739                 :      13091 :     emit_write_bytecode_byte_uint(emit, stack_adj, MP_BC_BUILD_TUPLE + kind, n_args);
     740                 :      13091 : }
     741                 :            : 
     742                 :       3747 : void mp_emit_bc_store_map(emit_t *emit) {
     743                 :       3747 :     emit_write_bytecode_byte(emit, -2, MP_BC_STORE_MAP);
     744                 :       3747 : }
     745                 :            : 
     746                 :        351 : void mp_emit_bc_store_comp(emit_t *emit, scope_kind_t kind, mp_uint_t collection_stack_index) {
     747                 :        351 :     int t;
     748                 :        351 :     int n;
     749         [ +  + ]:        351 :     if (kind == SCOPE_LIST_COMP) {
     750                 :            :         n = 0;
     751                 :            :         t = 0;
     752         [ +  + ]:         53 :     } else if (!MICROPY_PY_BUILTINS_SET || kind == SCOPE_DICT_COMP) {
     753                 :            :         n = 1;
     754                 :            :         t = 1;
     755                 :          5 :     } else if (MICROPY_PY_BUILTINS_SET) {
     756                 :          5 :         n = 0;
     757                 :          5 :         t = 2;
     758                 :            :     }
     759                 :            :     // the lower 2 bits of the opcode argument indicate the collection type
     760                 :        351 :     emit_write_bytecode_byte_uint(emit, -1 - n, MP_BC_STORE_COMP, ((collection_stack_index + n) << 2) | t);
     761                 :        351 : }
     762                 :            : 
     763                 :        766 : void mp_emit_bc_unpack_sequence(emit_t *emit, mp_uint_t n_args) {
     764                 :        766 :     emit_write_bytecode_byte_uint(emit, -1 + n_args, MP_BC_UNPACK_SEQUENCE, n_args);
     765                 :        766 : }
     766                 :            : 
     767                 :        177 : void mp_emit_bc_unpack_ex(emit_t *emit, mp_uint_t n_left, mp_uint_t n_right) {
     768                 :        177 :     emit_write_bytecode_byte_uint(emit, -1 + n_left + n_right + 1, MP_BC_UNPACK_EX, n_left | (n_right << 8));
     769                 :        177 : }
     770                 :            : 
     771                 :      15935 : void mp_emit_bc_make_function(emit_t *emit, scope_t *scope, mp_uint_t n_pos_defaults, mp_uint_t n_kw_defaults) {
     772         [ +  + ]:      15935 :     if (n_pos_defaults == 0 && n_kw_defaults == 0) {
     773                 :      15060 :         emit_write_bytecode_byte_child(emit, 1, MP_BC_MAKE_FUNCTION, scope->raw_code);
     774                 :            :     } else {
     775                 :        875 :         emit_write_bytecode_byte_child(emit, -1, MP_BC_MAKE_FUNCTION_DEFARGS, scope->raw_code);
     776                 :            :     }
     777                 :      15935 : }
     778                 :            : 
     779                 :        274 : void mp_emit_bc_make_closure(emit_t *emit, scope_t *scope, mp_uint_t n_closed_over, mp_uint_t n_pos_defaults, mp_uint_t n_kw_defaults) {
     780         [ +  + ]:        274 :     if (n_pos_defaults == 0 && n_kw_defaults == 0) {
     781                 :        265 :         int stack_adj = -n_closed_over + 1;
     782                 :        265 :         emit_write_bytecode_byte_child(emit, stack_adj, MP_BC_MAKE_CLOSURE, scope->raw_code);
     783                 :        265 :         emit_write_bytecode_raw_byte(emit, n_closed_over);
     784                 :            :     } else {
     785         [ -  + ]:          9 :         assert(n_closed_over <= 255);
     786                 :          9 :         int stack_adj = -2 - (mp_int_t)n_closed_over + 1;
     787                 :          9 :         emit_write_bytecode_byte_child(emit, stack_adj, MP_BC_MAKE_CLOSURE_DEFARGS, scope->raw_code);
     788                 :          9 :         emit_write_bytecode_raw_byte(emit, n_closed_over);
     789                 :            :     }
     790                 :        274 : }
     791                 :            : 
     792                 :     327576 : static void emit_bc_call_function_method_helper(emit_t *emit, int stack_adj, mp_uint_t bytecode_base, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags) {
     793         [ +  + ]:     327576 :     if (star_flags) {
     794                 :            :         // each positional arg is one object, each kwarg is two objects, the key
     795                 :            :         // and the value and one extra object for the star args bitmap.
     796                 :        789 :         stack_adj -= (int)n_positional + 2 * (int)n_keyword + 1;
     797                 :        789 :         emit_write_bytecode_byte_uint(emit, stack_adj, bytecode_base + 1, (n_keyword << 8) | n_positional);
     798                 :            :     } else {
     799                 :     326787 :         stack_adj -= (int)n_positional + 2 * (int)n_keyword;
     800                 :     326787 :         emit_write_bytecode_byte_uint(emit, stack_adj, bytecode_base, (n_keyword << 8) | n_positional);
     801                 :            :     }
     802                 :     327576 : }
     803                 :            : 
     804                 :     299422 : void mp_emit_bc_call_function(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags) {
     805                 :     299422 :     emit_bc_call_function_method_helper(emit, 0, MP_BC_CALL_FUNCTION, n_positional, n_keyword, star_flags);
     806                 :     299422 : }
     807                 :            : 
     808                 :      28154 : void mp_emit_bc_call_method(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags) {
     809                 :      28154 :     emit_bc_call_function_method_helper(emit, -1, MP_BC_CALL_METHOD, n_positional, n_keyword, star_flags);
     810                 :      28154 : }
     811                 :            : 
     812                 :      32249 : void mp_emit_bc_return_value(emit_t *emit) {
     813                 :      32249 :     emit_write_bytecode_byte(emit, -1, MP_BC_RETURN_VALUE);
     814                 :      32248 :     emit->suppress = true;
     815                 :      32248 : }
     816                 :            : 
     817                 :       5877 : void mp_emit_bc_raise_varargs(emit_t *emit, mp_uint_t n_args) {
     818                 :       5877 :     MP_STATIC_ASSERT(MP_BC_RAISE_LAST + 1 == MP_BC_RAISE_OBJ);
     819                 :       5877 :     MP_STATIC_ASSERT(MP_BC_RAISE_LAST + 2 == MP_BC_RAISE_FROM);
     820         [ -  + ]:       5877 :     assert(n_args <= 2);
     821                 :       5877 :     emit_write_bytecode_byte(emit, -n_args, MP_BC_RAISE_LAST + n_args);
     822                 :       5877 :     emit->suppress = true;
     823                 :       5877 : }
     824                 :            : 
     825                 :       2584 : void mp_emit_bc_yield(emit_t *emit, int kind) {
     826                 :       2584 :     MP_STATIC_ASSERT(MP_BC_YIELD_VALUE + 1 == MP_BC_YIELD_FROM);
     827                 :       2584 :     emit_write_bytecode_byte(emit, -kind, MP_BC_YIELD_VALUE + kind);
     828                 :       2584 :     emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
     829                 :       2584 : }
     830                 :            : 
     831                 :      45121 : void mp_emit_bc_start_except_handler(emit_t *emit) {
     832                 :      45121 :     mp_emit_bc_adjust_stack_size(emit, 4); // stack adjust for the exception instance, +3 for possible UNWIND_JUMP state
     833                 :      45121 : }
     834                 :            : 
     835                 :      45117 : void mp_emit_bc_end_except_handler(emit_t *emit) {
     836                 :      45117 :     mp_emit_bc_adjust_stack_size(emit, -3); // stack adjust
     837                 :      45117 : }
     838                 :            : 
     839                 :            : #if MICROPY_EMIT_NATIVE
     840                 :            : const emit_method_table_t emit_bc_method_table = {
     841                 :            :     #if MICROPY_DYNAMIC_COMPILER
     842                 :            :     NULL,
     843                 :            :     NULL,
     844                 :            :     #endif
     845                 :            : 
     846                 :            :     mp_emit_bc_start_pass,
     847                 :            :     mp_emit_bc_end_pass,
     848                 :            :     mp_emit_bc_adjust_stack_size,
     849                 :            :     mp_emit_bc_set_source_line,
     850                 :            : 
     851                 :            :     {
     852                 :            :         mp_emit_bc_load_local,
     853                 :            :         mp_emit_bc_load_global,
     854                 :            :     },
     855                 :            :     {
     856                 :            :         mp_emit_bc_store_local,
     857                 :            :         mp_emit_bc_store_global,
     858                 :            :     },
     859                 :            :     {
     860                 :            :         mp_emit_bc_delete_local,
     861                 :            :         mp_emit_bc_delete_global,
     862                 :            :     },
     863                 :            : 
     864                 :            :     mp_emit_bc_label_assign,
     865                 :            :     mp_emit_bc_import,
     866                 :            :     mp_emit_bc_load_const_tok,
     867                 :            :     mp_emit_bc_load_const_small_int,
     868                 :            :     mp_emit_bc_load_const_str,
     869                 :            :     mp_emit_bc_load_const_obj,
     870                 :            :     mp_emit_bc_load_null,
     871                 :            :     mp_emit_bc_load_method,
     872                 :            :     mp_emit_bc_load_build_class,
     873                 :            :     mp_emit_bc_subscr,
     874                 :            :     mp_emit_bc_attr,
     875                 :            :     mp_emit_bc_dup_top,
     876                 :            :     mp_emit_bc_dup_top_two,
     877                 :            :     mp_emit_bc_pop_top,
     878                 :            :     mp_emit_bc_rot_two,
     879                 :            :     mp_emit_bc_rot_three,
     880                 :            :     mp_emit_bc_jump,
     881                 :            :     mp_emit_bc_pop_jump_if,
     882                 :            :     mp_emit_bc_jump_if_or_pop,
     883                 :            :     mp_emit_bc_unwind_jump,
     884                 :            :     mp_emit_bc_setup_block,
     885                 :            :     mp_emit_bc_with_cleanup,
     886                 :            :     #if MICROPY_PY_ASYNC_AWAIT
     887                 :            :     mp_emit_bc_async_with_setup_finally,
     888                 :            :     #endif
     889                 :            :     mp_emit_bc_end_finally,
     890                 :            :     mp_emit_bc_get_iter,
     891                 :            :     mp_emit_bc_for_iter,
     892                 :            :     mp_emit_bc_for_iter_end,
     893                 :            :     mp_emit_bc_pop_except_jump,
     894                 :            :     mp_emit_bc_unary_op,
     895                 :            :     mp_emit_bc_binary_op,
     896                 :            :     mp_emit_bc_build,
     897                 :            :     mp_emit_bc_store_map,
     898                 :            :     mp_emit_bc_store_comp,
     899                 :            :     mp_emit_bc_unpack_sequence,
     900                 :            :     mp_emit_bc_unpack_ex,
     901                 :            :     mp_emit_bc_make_function,
     902                 :            :     mp_emit_bc_make_closure,
     903                 :            :     mp_emit_bc_call_function,
     904                 :            :     mp_emit_bc_call_method,
     905                 :            :     mp_emit_bc_return_value,
     906                 :            :     mp_emit_bc_raise_varargs,
     907                 :            :     mp_emit_bc_yield,
     908                 :            : 
     909                 :            :     mp_emit_bc_start_except_handler,
     910                 :            :     mp_emit_bc_end_except_handler,
     911                 :            : };
     912                 :            : #else
     913                 :            : const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_load_id_ops = {
     914                 :            :     mp_emit_bc_load_local,
     915                 :            :     mp_emit_bc_load_global,
     916                 :            : };
     917                 :            : 
     918                 :            : const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_store_id_ops = {
     919                 :            :     mp_emit_bc_store_local,
     920                 :            :     mp_emit_bc_store_global,
     921                 :            : };
     922                 :            : 
     923                 :            : const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_delete_id_ops = {
     924                 :            :     mp_emit_bc_delete_local,
     925                 :            :     mp_emit_bc_delete_global,
     926                 :            : };
     927                 :            : #endif
     928                 :            : 
     929                 :            : #endif // MICROPY_ENABLE_COMPILER

Generated by: LCOV version 1.15-5-g462f71d