LCOV - code coverage report
Current view: top level - py - emitbc.c (source / functions) Hit Total Coverage
Test: unix_coverage_v1.22.0-335-g9c7f0659e.info Lines: 458 458 100.0 %
Date: 2024-04-24 08:31:58 Functions: 71 71 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                 :       3788 : emit_t *emit_bc_new(mp_emit_common_t *emit_common) {
      79                 :       3788 :     emit_t *emit = m_new0(emit_t, 1);
      80                 :       3788 :     emit->emit_common = emit_common;
      81                 :       3788 :     return emit;
      82                 :            : }
      83                 :            : 
      84                 :       3784 : void emit_bc_set_max_num_labels(emit_t *emit, mp_uint_t max_num_labels) {
      85                 :       3784 :     emit->max_num_labels = max_num_labels;
      86                 :       3784 :     emit->label_offsets = m_new(size_t, emit->max_num_labels);
      87                 :       3784 : }
      88                 :            : 
      89                 :       3766 : void emit_bc_free(emit_t *emit) {
      90                 :       3766 :     m_del(size_t, emit->label_offsets, emit->max_num_labels);
      91                 :       3766 :     m_del_obj(emit_t, emit);
      92                 :       3766 : }
      93                 :            : 
      94                 :            : // all functions must go through this one to emit code info
      95                 :     370864 : static uint8_t *emit_get_cur_to_write_code_info(void *emit_in, size_t num_bytes_to_write) {
      96                 :     370864 :     emit_t *emit = emit_in;
      97         [ +  + ]:     370864 :     if (emit->pass < MP_PASS_EMIT) {
      98                 :     192587 :         emit->code_info_offset += num_bytes_to_write;
      99                 :     192587 :         return emit->dummy_data;
     100                 :            :     } else {
     101         [ -  + ]:     178277 :         assert(emit->code_info_offset + num_bytes_to_write <= emit->code_info_size);
     102                 :     178277 :         byte *c = emit->code_base + emit->code_info_offset;
     103                 :     178277 :         emit->code_info_offset += num_bytes_to_write;
     104                 :     178277 :         return c;
     105                 :            :     }
     106                 :            : }
     107                 :            : 
     108                 :      39554 : static void emit_write_code_info_byte(emit_t *emit, byte val) {
     109                 :      39554 :     *emit_get_cur_to_write_code_info(emit, 1) = val;
     110                 :      39552 : }
     111                 :            : 
     112                 :      34130 : static void emit_write_code_info_qstr(emit_t *emit, qstr qst) {
     113                 :      34130 :     mp_encode_uint(emit, emit_get_cur_to_write_code_info, mp_emit_common_use_qstr(emit->emit_common, qst));
     114                 :      34131 : }
     115                 :            : 
     116                 :            : #if MICROPY_ENABLE_SOURCE_LINE
     117                 :     288447 : static void emit_write_code_info_bytes_lines(emit_t *emit, mp_uint_t bytes_to_skip, mp_uint_t lines_to_skip) {
     118         [ +  - ]:     288447 :     assert(bytes_to_skip > 0 || lines_to_skip > 0);
     119         [ +  + ]:     585626 :     while (bytes_to_skip > 0 || lines_to_skip > 0) {
     120                 :     297179 :         mp_uint_t b, l;
     121         [ +  + ]:     297179 :         if (lines_to_skip <= 6 || bytes_to_skip > 0xf) {
     122                 :            :             // use 0b0LLBBBBB encoding
     123                 :     280056 :             b = MIN(bytes_to_skip, 0x1f);
     124         [ +  + ]:     280056 :             if (b < bytes_to_skip) {
     125                 :            :                 // we can't skip any lines until we skip all the bytes
     126                 :            :                 l = 0;
     127                 :            :             } else {
     128                 :     279798 :                 l = MIN(lines_to_skip, 0x3);
     129                 :            :             }
     130                 :     280056 :             *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                 :      17123 :             b = MIN(bytes_to_skip, 0xf);
     134                 :      17123 :             l = MIN(lines_to_skip, 0x7ff);
     135                 :      17123 :             byte *ci = emit_get_cur_to_write_code_info(emit, 2);
     136                 :      17123 :             ci[0] = 0x80 | b | ((l >> 4) & 0x70);
     137                 :      17123 :             ci[1] = l;
     138                 :            :         }
     139                 :     297179 :         bytes_to_skip -= b;
     140                 :     297179 :         lines_to_skip -= l;
     141                 :            :     }
     142                 :     288447 : }
     143                 :            : #endif
     144                 :            : 
     145                 :            : // all functions must go through this one to emit byte code
     146                 :    2312455 : static uint8_t *emit_get_cur_to_write_bytecode(void *emit_in, size_t num_bytes_to_write) {
     147                 :    2312455 :     emit_t *emit = emit_in;
     148         [ +  + ]:    2312455 :     if (emit->suppress) {
     149                 :      10150 :         return emit->dummy_data;
     150                 :            :     }
     151         [ +  + ]:    2302305 :     if (emit->pass < MP_PASS_EMIT) {
     152                 :     996375 :         emit->bytecode_offset += num_bytes_to_write;
     153                 :     996375 :         return emit->dummy_data;
     154                 :            :     } else {
     155         [ -  + ]:    1305930 :         assert(emit->bytecode_offset + num_bytes_to_write <= emit->bytecode_size);
     156                 :    1305930 :         byte *c = emit->code_base + emit->code_info_size + emit->bytecode_offset;
     157                 :    1305930 :         emit->bytecode_offset += num_bytes_to_write;
     158                 :    1305930 :         return c;
     159                 :            :     }
     160                 :            : }
     161                 :            : 
     162                 :       1215 : static void emit_write_bytecode_raw_byte(emit_t *emit, byte b1) {
     163                 :       1215 :     byte *c = emit_get_cur_to_write_bytecode(emit, 1);
     164                 :       1215 :     c[0] = b1;
     165                 :       1215 : }
     166                 :            : 
     167                 :    1346692 : static void emit_write_bytecode_byte(emit_t *emit, int stack_adj, byte b1) {
     168                 :    1346692 :     mp_emit_bc_adjust_stack_size(emit, stack_adj);
     169                 :    1346697 :     byte *c = emit_get_cur_to_write_bytecode(emit, 1);
     170                 :    1346692 :     c[0] = b1;
     171                 :    1346692 : }
     172                 :            : 
     173                 :            : // Similar to mp_encode_uint(), just some extra handling to encode sign
     174                 :       7595 : static void emit_write_bytecode_byte_int(emit_t *emit, int stack_adj, byte b1, mp_int_t num) {
     175                 :       7595 :     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                 :       7595 :     byte buf[MP_ENCODE_UINT_MAX_BYTES];
     179                 :       7595 :     byte *p = buf + sizeof(buf);
     180                 :            :     // We encode in little-ending order, but store in big-endian, to help decoding
     181                 :      15456 :     do {
     182                 :      15456 :         *--p = num & 0x7f;
     183                 :      15456 :         num >>= 7;
     184         [ +  + ]:      15456 :     } 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   [ +  +  +  + ]:       7595 :     if (num == -1 && (*p & 0x40) == 0) {
     188                 :        162 :         *--p = 0x7f;
     189   [ +  +  +  + ]:       7433 :     } else if (num == 0 && (*p & 0x40) != 0) {
     190                 :       2174 :         *--p = 0;
     191                 :            :     }
     192                 :            : 
     193                 :       7595 :     byte *c = emit_get_cur_to_write_bytecode(emit, buf + sizeof(buf) - p);
     194         [ +  + ]:      17792 :     while (p != buf + sizeof(buf) - 1) {
     195                 :      10197 :         *c++ = *p++ | 0x80;
     196                 :            :     }
     197                 :       7595 :     *c = *p;
     198                 :       7595 : }
     199                 :            : 
     200                 :     720435 : static void emit_write_bytecode_byte_uint(emit_t *emit, int stack_adj, byte b, mp_uint_t val) {
     201                 :     720435 :     emit_write_bytecode_byte(emit, stack_adj, b);
     202                 :     720436 :     mp_encode_uint(emit, emit_get_cur_to_write_bytecode, val);
     203                 :     720436 : }
     204                 :            : 
     205                 :      34420 : static void emit_write_bytecode_byte_const(emit_t *emit, int stack_adj, byte b, mp_uint_t n) {
     206                 :      34420 :     emit_write_bytecode_byte_uint(emit, stack_adj, b, n);
     207                 :      34420 : }
     208                 :            : 
     209                 :     348138 : static void emit_write_bytecode_byte_qstr(emit_t *emit, int stack_adj, byte b, qstr qst) {
     210                 :     348138 :     emit_write_bytecode_byte_uint(emit, stack_adj, b, mp_emit_common_use_qstr(emit->emit_common, qst));
     211                 :     348141 : }
     212                 :            : 
     213                 :      19295 : static void emit_write_bytecode_byte_obj(emit_t *emit, int stack_adj, byte b, mp_obj_t obj) {
     214                 :      19295 :     emit_write_bytecode_byte_const(emit, stack_adj, b, mp_emit_common_use_const_obj(emit->emit_common, obj));
     215                 :      19295 : }
     216                 :            : 
     217                 :      15125 : static void emit_write_bytecode_byte_child(emit_t *emit, int stack_adj, byte b, mp_raw_code_t *rc) {
     218         [ +  + ]:      18267 :     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                 :      15125 : }
     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                 :     239870 : static void emit_write_bytecode_byte_label(emit_t *emit, int stack_adj, byte b1, mp_uint_t label) {
     231                 :     239870 :     mp_emit_bc_adjust_stack_size(emit, stack_adj);
     232                 :            : 
     233         [ +  + ]:     239870 :     if (emit->suppress) {
     234                 :            :         return;
     235                 :            :     }
     236                 :            : 
     237                 :            :     // Determine if the jump offset is signed or unsigned, based on the opcode.
     238                 :     236512 :     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                 :     236512 :     unsigned int jump_encoding_size = 1;
     242                 :     236512 :     ssize_t bytecode_offset = 0;
     243                 :            : 
     244                 :            :     // Compute the jump size and offset only when code size is known.
     245         [ +  + ]:     236512 :     if (emit->pass >= MP_PASS_CODE_SIZE) {
     246                 :            :         // The -2 accounts for this jump opcode taking 2 bytes (at least).
     247                 :     188020 :         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   [ +  +  +  + ]:     188020 :         if ((is_signed && -64 <= bytecode_offset && bytecode_offset <= 63)
     251         [ +  + ]:     158980 :             || (!is_signed && (size_t)bytecode_offset <= 127)) {
     252                 :            :             // Use a 1-byte jump offset.
     253                 :     116997 :             jump_encoding_size = 0;
     254                 :            :         }
     255                 :            : 
     256                 :            :         // Adjust the offset depending on the size of the encoding of the offset.
     257                 :     188020 :         bytecode_offset -= jump_encoding_size;
     258                 :            : 
     259         [ -  + ]:     188020 :         assert(is_signed || bytecode_offset >= 0);
     260                 :            :     }
     261                 :            : 
     262                 :            :     // Emit the opcode.
     263                 :     236512 :     byte *c = emit_get_cur_to_write_bytecode(emit, 2 + jump_encoding_size);
     264                 :     236512 :     c[0] = b1;
     265         [ +  + ]:     236512 :     if (jump_encoding_size == 0) {
     266         [ +  + ]:     116997 :         if (is_signed) {
     267                 :      29040 :             bytecode_offset += 0x40;
     268                 :            :         }
     269         [ -  + ]:     116997 :         assert(0 <= bytecode_offset && bytecode_offset <= 0x7f);
     270                 :     116997 :         c[1] = bytecode_offset;
     271                 :            :     } else {
     272         [ +  + ]:     119515 :         if (is_signed) {
     273                 :      34635 :             bytecode_offset += 0x4000;
     274                 :            :         }
     275   [ +  +  +  + ]:     119515 :         if (emit->pass == MP_PASS_EMIT && !(0 <= bytecode_offset && bytecode_offset <= 0x7fff)) {
     276                 :         69 :             emit->overflow = true;
     277                 :            :         }
     278                 :     119515 :         c[1] = 0x80 | (bytecode_offset & 0x7f);
     279                 :     119515 :         c[2] = bytecode_offset >> 7;
     280                 :            :     }
     281                 :            : }
     282                 :            : 
     283                 :      25102 : void mp_emit_bc_start_pass(emit_t *emit, pass_kind_t pass, scope_t *scope) {
     284                 :      25102 :     emit->pass = pass;
     285                 :      25102 :     emit->stack_size = 0;
     286                 :      25102 :     emit->suppress = false;
     287                 :      25102 :     emit->scope = scope;
     288                 :      25102 :     emit->last_source_line_offset = 0;
     289                 :      25102 :     emit->last_source_line = 1;
     290                 :      25102 :     emit->bytecode_offset = 0;
     291                 :      25102 :     emit->code_info_offset = 0;
     292                 :      25102 :     emit->overflow = false;
     293                 :            : 
     294                 :            :     // Write local state size, exception stack size, scope flags and number of arguments
     295                 :            :     {
     296                 :      25102 :         mp_uint_t n_state = scope->num_locals + scope->stack_size;
     297         [ +  + ]:      25102 :         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                 :      12756 :             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                 :      25102 :         size_t n_exc_stack = scope->exc_stack_size;
     309         [ +  + ]:      28686 :         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         [ +  + ]:      25100 :     if (emit->pass >= MP_PASS_CODE_SIZE) {
     314                 :      10376 :         size_t n_info = emit->n_info;
     315                 :      10376 :         size_t n_cell = emit->n_cell;
     316   [ +  +  +  + ]:      10563 :         MP_BC_PRELUDE_SIZE_ENCODE(n_info, n_cell, emit_write_code_info_byte, emit);
     317                 :            :     }
     318                 :            : 
     319                 :      25100 :     emit->n_info = emit->code_info_offset;
     320                 :            : 
     321                 :            :     // Write the name of this function.
     322                 :      25100 :     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         [ +  + ]:      34130 :         for (int i = 0; i < scope->num_pos_args + scope->num_kwonly_args; i++) {
     337                 :      16213 :             qstr qst = MP_QSTR__star_;
     338         [ +  + ]:      16213 :             for (int j = 0; j < scope->id_info_len; ++j) {
     339                 :      15536 :                 id_info_t *id = &scope->id_info[j];
     340   [ +  +  +  + ]:      15536 :                 if ((id->flags & ID_FLAG_IS_PARAM) && id->local_num == i) {
     341                 :       8361 :                     qst = id->qst;
     342                 :       8361 :                     break;
     343                 :            :                 }
     344                 :            :             }
     345                 :       9038 :             emit_write_code_info_qstr(emit, qst);
     346                 :            :         }
     347                 :            :     }
     348                 :      25093 : }
     349                 :            : 
     350                 :      25098 : bool mp_emit_bc_end_pass(emit_t *emit) {
     351         [ +  + ]:      25098 :     if (emit->pass == MP_PASS_SCOPE) {
     352                 :            :         return true;
     353                 :            :     }
     354                 :            : 
     355                 :            :     // check stack is back to zero size
     356         [ -  + ]:      15495 :     assert(emit->stack_size == 0);
     357                 :            : 
     358                 :            :     // Calculate size of source code info section
     359                 :      15495 :     emit->n_info = emit->code_info_offset - emit->n_info;
     360                 :            : 
     361                 :            :     // Emit closure section of prelude
     362                 :      15495 :     emit->n_cell = 0;
     363         [ +  + ]:      78095 :     for (size_t i = 0; i < emit->scope->id_info_len; ++i) {
     364                 :      62600 :         id_info_t *id = &emit->scope->id_info[i];
     365         [ +  + ]:      62600 :         if (id->kind == ID_INFO_KIND_CELL) {
     366         [ -  + ]:        306 :             assert(id->local_num <= 255);
     367                 :        306 :             emit_write_code_info_byte(emit, id->local_num); // write the local which should be converted to a cell
     368                 :        306 :             ++emit->n_cell;
     369                 :            :         }
     370                 :            :     }
     371                 :            : 
     372         [ +  + ]:      15495 :     if (emit->pass == MP_PASS_CODE_SIZE) {
     373                 :            :         // calculate size of total code-info + bytecode, in bytes
     374                 :       5119 :         emit->code_info_size = emit->code_info_offset;
     375                 :       5119 :         emit->bytecode_size = emit->bytecode_offset;
     376                 :       5119 :         emit->code_base = m_new0(byte, emit->code_info_size + emit->bytecode_size);
     377                 :            : 
     378         [ +  + ]:      10376 :     } else if (emit->pass == MP_PASS_EMIT) {
     379                 :            :         // Code info and/or bytecode can shrink during this pass.
     380         [ -  + ]:       5257 :         assert(emit->code_info_offset <= emit->code_info_size);
     381         [ -  + ]:       5257 :         assert(emit->bytecode_offset <= emit->bytecode_size);
     382                 :            : 
     383         [ +  + ]:       5257 :         if (emit->code_info_offset != emit->code_info_size
     384         [ +  + ]:       5256 :             || 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                 :        138 :             emit->code_info_size = emit->code_info_offset;
     388                 :        138 :             emit->bytecode_size = emit->bytecode_offset;
     389                 :        138 :             return false;
     390                 :            :         }
     391                 :            : 
     392         [ +  + ]:       5119 :         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                 :       5117 :         size_t bytecode_len = emit->code_info_size + emit->bytecode_size;
     398                 :            :         #if MICROPY_DEBUG_PRINTERS
     399                 :       5117 :         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                 :       5117 :         mp_emit_glue_assign_bytecode(emit->scope->raw_code, emit->code_base,
     405                 :       5117 :             emit->emit_common->children,
     406                 :            :             #if MICROPY_PERSISTENT_CODE_SAVE
     407                 :            :             bytecode_len,
     408                 :            :             emit->emit_common->ct_cur_child,
     409                 :            :             #endif
     410                 :       5117 :             emit->scope->scope_flags);
     411                 :            :     }
     412                 :            : 
     413                 :            :     return true;
     414                 :            : }
     415                 :            : 
     416                 :    1764978 : void mp_emit_bc_adjust_stack_size(emit_t *emit, mp_int_t delta) {
     417         [ +  + ]:    1764978 :     if (emit->pass == MP_PASS_SCOPE) {
     418                 :            :         return;
     419                 :            :     }
     420         [ -  + ]:    1480228 :     assert((mp_int_t)emit->stack_size + delta >= 0);
     421                 :    1480228 :     emit->stack_size += delta;
     422         [ +  + ]:    1480228 :     if (emit->stack_size > emit->scope->stack_size) {
     423                 :      18873 :         emit->scope->stack_size = emit->stack_size;
     424                 :            :     }
     425                 :            : }
     426                 :            : 
     427                 :     871187 : void mp_emit_bc_set_source_line(emit_t *emit, mp_uint_t source_line) {
     428                 :            :     #if MICROPY_ENABLE_SOURCE_LINE
     429         [ +  + ]:     871187 :     if (MP_STATE_VM(mp_optimise_value) >= 3) {
     430                 :            :         // If we compile with -O3, don't store line numbers.
     431                 :            :         return;
     432                 :            :     }
     433         [ +  + ]:     871139 :     if (source_line > emit->last_source_line) {
     434                 :     288447 :         mp_uint_t bytes_to_skip = emit->bytecode_offset - emit->last_source_line_offset;
     435                 :     288447 :         mp_uint_t lines_to_skip = source_line - emit->last_source_line;
     436                 :     288447 :         emit_write_code_info_bytes_lines(emit, bytes_to_skip, lines_to_skip);
     437                 :     288447 :         emit->last_source_line_offset = emit->bytecode_offset;
     438                 :     288447 :         emit->last_source_line = source_line;
     439                 :            :     }
     440                 :            :     #else
     441                 :            :     (void)emit;
     442                 :            :     (void)source_line;
     443                 :            :     #endif
     444                 :            : }
     445                 :            : 
     446                 :     248524 : 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                 :     248524 :     emit->suppress = false;
     450                 :            : 
     451         [ +  + ]:     248524 :     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         [ -  + ]:     215021 :     assert(l < emit->max_num_labels);
     460   [ +  +  -  + ]:     215021 :     assert(emit->pass == MP_PASS_STACK_SIZE || emit->bytecode_offset <= emit->label_offsets[l]);
     461                 :            : 
     462                 :            :     // Assign label offset.
     463                 :     215021 :     emit->label_offsets[l] = emit->bytecode_offset;
     464                 :            : }
     465                 :            : 
     466                 :       6010 : void mp_emit_bc_import(emit_t *emit, qstr qst, int kind) {
     467                 :       6010 :     MP_STATIC_ASSERT(MP_BC_IMPORT_NAME + MP_EMIT_IMPORT_NAME == MP_BC_IMPORT_NAME);
     468                 :       6010 :     MP_STATIC_ASSERT(MP_BC_IMPORT_NAME + MP_EMIT_IMPORT_FROM == MP_BC_IMPORT_FROM);
     469         [ +  + ]:       6010 :     int stack_adj = kind == MP_EMIT_IMPORT_FROM ? 1 : -1;
     470         [ +  + ]:       4418 :     if (kind == MP_EMIT_IMPORT_STAR) {
     471                 :        201 :         emit_write_bytecode_byte(emit, stack_adj, MP_BC_IMPORT_STAR);
     472                 :            :     } else {
     473                 :       5809 :         emit_write_bytecode_byte_qstr(emit, stack_adj, MP_BC_IMPORT_NAME + kind, qst);
     474                 :            :     }
     475                 :       6010 : }
     476                 :            : 
     477                 :      79861 : void mp_emit_bc_load_const_tok(emit_t *emit, mp_token_kind_t tok) {
     478                 :      79861 :     MP_STATIC_ASSERT(MP_BC_LOAD_CONST_FALSE + (MP_TOKEN_KW_NONE - MP_TOKEN_KW_FALSE) == MP_BC_LOAD_CONST_NONE);
     479                 :      79861 :     MP_STATIC_ASSERT(MP_BC_LOAD_CONST_FALSE + (MP_TOKEN_KW_TRUE - MP_TOKEN_KW_FALSE) == MP_BC_LOAD_CONST_TRUE);
     480         [ +  + ]:      79861 :     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                 :      79849 :         emit_write_bytecode_byte(emit, 1, MP_BC_LOAD_CONST_FALSE + (tok - MP_TOKEN_KW_FALSE));
     484                 :            :     }
     485                 :      79861 : }
     486                 :            : 
     487                 :      64374 : void mp_emit_bc_load_const_small_int(emit_t *emit, mp_int_t arg) {
     488         [ -  + ]:      64374 :     assert(MP_SMALL_INT_FITS(arg));
     489                 :      64374 :     if (-MP_BC_LOAD_CONST_SMALL_INT_MULTI_EXCESS <= arg
     490         [ +  + ]:      64374 :         && arg < MP_BC_LOAD_CONST_SMALL_INT_MULTI_NUM - MP_BC_LOAD_CONST_SMALL_INT_MULTI_EXCESS) {
     491                 :      56779 :         emit_write_bytecode_byte(emit, 1,
     492                 :      56779 :             MP_BC_LOAD_CONST_SMALL_INT_MULTI + MP_BC_LOAD_CONST_SMALL_INT_MULTI_EXCESS + arg);
     493                 :            :     } else {
     494                 :       7595 :         emit_write_bytecode_byte_int(emit, 1, MP_BC_LOAD_CONST_SMALL_INT, arg);
     495                 :            :     }
     496                 :      64374 : }
     497                 :            : 
     498                 :      43178 : void mp_emit_bc_load_const_str(emit_t *emit, qstr qst) {
     499                 :      43178 :     emit_write_bytecode_byte_qstr(emit, 1, MP_BC_LOAD_CONST_STRING, qst);
     500                 :      43180 : }
     501                 :            : 
     502                 :      19283 : void mp_emit_bc_load_const_obj(emit_t *emit, mp_obj_t obj) {
     503                 :      19283 :     emit_write_bytecode_byte_obj(emit, 1, MP_BC_LOAD_CONST_OBJ, obj);
     504                 :      19283 : }
     505                 :            : 
     506                 :       1944 : void mp_emit_bc_load_null(emit_t *emit) {
     507                 :       1944 :     emit_write_bytecode_byte(emit, 1, MP_BC_LOAD_NULL);
     508                 :       1944 : }
     509                 :            : 
     510                 :      27953 : void mp_emit_bc_load_local(emit_t *emit, qstr qst, mp_uint_t local_num, int kind) {
     511                 :      27953 :     MP_STATIC_ASSERT(MP_BC_LOAD_FAST_N + MP_EMIT_IDOP_LOCAL_FAST == MP_BC_LOAD_FAST_N);
     512                 :      27953 :     MP_STATIC_ASSERT(MP_BC_LOAD_FAST_N + MP_EMIT_IDOP_LOCAL_DEREF == MP_BC_LOAD_DEREF);
     513                 :      27953 :     (void)qst;
     514         [ +  + ]:      27953 :     if (kind == MP_EMIT_IDOP_LOCAL_FAST && local_num <= 15) {
     515                 :      27153 :         emit_write_bytecode_byte(emit, 1, MP_BC_LOAD_FAST_MULTI + local_num);
     516                 :            :     } else {
     517                 :        800 :         emit_write_bytecode_byte_uint(emit, 1, MP_BC_LOAD_FAST_N + kind, local_num);
     518                 :            :     }
     519                 :      27953 : }
     520                 :            : 
     521                 :     193127 : void mp_emit_bc_load_global(emit_t *emit, qstr qst, int kind) {
     522                 :     193127 :     MP_STATIC_ASSERT(MP_BC_LOAD_NAME + MP_EMIT_IDOP_GLOBAL_NAME == MP_BC_LOAD_NAME);
     523                 :     193127 :     MP_STATIC_ASSERT(MP_BC_LOAD_NAME + MP_EMIT_IDOP_GLOBAL_GLOBAL == MP_BC_LOAD_GLOBAL);
     524                 :     193127 :     (void)qst;
     525                 :     193127 :     emit_write_bytecode_byte_qstr(emit, 1, MP_BC_LOAD_NAME + kind, qst);
     526                 :     193126 : }
     527                 :            : 
     528                 :      26184 : void mp_emit_bc_load_method(emit_t *emit, qstr qst, bool is_super) {
     529                 :      26184 :     int stack_adj = 1 - 2 * is_super;
     530         [ +  + ]:      52290 :     emit_write_bytecode_byte_qstr(emit, stack_adj, is_super ? MP_BC_LOAD_SUPER_METHOD : MP_BC_LOAD_METHOD, qst);
     531                 :      26184 : }
     532                 :            : 
     533                 :       2469 : void mp_emit_bc_load_build_class(emit_t *emit) {
     534                 :       2469 :     emit_write_bytecode_byte(emit, 1, MP_BC_LOAD_BUILD_CLASS);
     535                 :       2469 : }
     536                 :            : 
     537                 :       9446 : void mp_emit_bc_subscr(emit_t *emit, int kind) {
     538         [ +  + ]:       9446 :     if (kind == MP_EMIT_SUBSCR_LOAD) {
     539                 :       6725 :         emit_write_bytecode_byte(emit, -1, MP_BC_LOAD_SUBSCR);
     540                 :            :     } else {
     541         [ +  + ]:       2721 :         if (kind == MP_EMIT_SUBSCR_DELETE) {
     542                 :        304 :             mp_emit_bc_load_null(emit);
     543                 :        304 :             mp_emit_bc_rot_three(emit);
     544                 :            :         }
     545                 :       2721 :         emit_write_bytecode_byte(emit, -3, MP_BC_STORE_SUBSCR);
     546                 :            :     }
     547                 :       9446 : }
     548                 :            : 
     549                 :      20053 : void mp_emit_bc_attr(emit_t *emit, qstr qst, int kind) {
     550         [ +  + ]:      20053 :     if (kind == MP_EMIT_ATTR_LOAD) {
     551                 :      15985 :         emit_write_bytecode_byte_qstr(emit, 0, MP_BC_LOAD_ATTR, qst);
     552                 :            :     } else {
     553         [ +  + ]:       4068 :         if (kind == MP_EMIT_ATTR_DELETE) {
     554                 :         79 :             mp_emit_bc_load_null(emit);
     555                 :         79 :             mp_emit_bc_rot_two(emit);
     556                 :            :         }
     557                 :       4068 :         emit_write_bytecode_byte_qstr(emit, -2, MP_BC_STORE_ATTR, qst);
     558                 :            :     }
     559                 :      20053 : }
     560                 :            : 
     561                 :       7302 : void mp_emit_bc_store_local(emit_t *emit, qstr qst, mp_uint_t local_num, int kind) {
     562                 :       7302 :     MP_STATIC_ASSERT(MP_BC_STORE_FAST_N + MP_EMIT_IDOP_LOCAL_FAST == MP_BC_STORE_FAST_N);
     563                 :       7302 :     MP_STATIC_ASSERT(MP_BC_STORE_FAST_N + MP_EMIT_IDOP_LOCAL_DEREF == MP_BC_STORE_DEREF);
     564                 :       7302 :     (void)qst;
     565         [ +  + ]:       7302 :     if (kind == MP_EMIT_IDOP_LOCAL_FAST && local_num <= 15) {
     566                 :       6495 :         emit_write_bytecode_byte(emit, -1, MP_BC_STORE_FAST_MULTI + local_num);
     567                 :            :     } else {
     568                 :        807 :         emit_write_bytecode_byte_uint(emit, -1, MP_BC_STORE_FAST_N + kind, local_num);
     569                 :            :     }
     570                 :       7302 : }
     571                 :            : 
     572                 :      59365 : void mp_emit_bc_store_global(emit_t *emit, qstr qst, int kind) {
     573                 :      59365 :     MP_STATIC_ASSERT(MP_BC_STORE_NAME + MP_EMIT_IDOP_GLOBAL_NAME == MP_BC_STORE_NAME);
     574                 :      59365 :     MP_STATIC_ASSERT(MP_BC_STORE_NAME + MP_EMIT_IDOP_GLOBAL_GLOBAL == MP_BC_STORE_GLOBAL);
     575                 :      59365 :     emit_write_bytecode_byte_qstr(emit, -1, MP_BC_STORE_NAME + kind, qst);
     576                 :      59365 : }
     577                 :            : 
     578                 :        356 : void mp_emit_bc_delete_local(emit_t *emit, qstr qst, mp_uint_t local_num, int kind) {
     579                 :        356 :     MP_STATIC_ASSERT(MP_BC_DELETE_FAST + MP_EMIT_IDOP_LOCAL_FAST == MP_BC_DELETE_FAST);
     580                 :        356 :     MP_STATIC_ASSERT(MP_BC_DELETE_FAST + MP_EMIT_IDOP_LOCAL_DEREF == MP_BC_DELETE_DEREF);
     581                 :        356 :     (void)qst;
     582                 :        356 :     emit_write_bytecode_byte_uint(emit, 0, MP_BC_DELETE_FAST + kind, local_num);
     583                 :        356 : }
     584                 :            : 
     585                 :        424 : void mp_emit_bc_delete_global(emit_t *emit, qstr qst, int kind) {
     586                 :        424 :     MP_STATIC_ASSERT(MP_BC_DELETE_NAME + MP_EMIT_IDOP_GLOBAL_NAME == MP_BC_DELETE_NAME);
     587                 :        424 :     MP_STATIC_ASSERT(MP_BC_DELETE_NAME + MP_EMIT_IDOP_GLOBAL_GLOBAL == MP_BC_DELETE_GLOBAL);
     588                 :        424 :     emit_write_bytecode_byte_qstr(emit, 0, MP_BC_DELETE_NAME + kind, qst);
     589                 :        424 : }
     590                 :            : 
     591                 :      47048 : void mp_emit_bc_dup_top(emit_t *emit) {
     592                 :      47048 :     emit_write_bytecode_byte(emit, 1, MP_BC_DUP_TOP);
     593                 :      47048 : }
     594                 :            : 
     595                 :        720 : void mp_emit_bc_dup_top_two(emit_t *emit) {
     596                 :        720 :     emit_write_bytecode_byte(emit, 2, MP_BC_DUP_TOP_TWO);
     597                 :        720 : }
     598                 :            : 
     599                 :     147423 : void mp_emit_bc_pop_top(emit_t *emit) {
     600                 :     147423 :     emit_write_bytecode_byte(emit, -1, MP_BC_POP_TOP);
     601                 :     147422 : }
     602                 :            : 
     603                 :       1211 : void mp_emit_bc_rot_two(emit_t *emit) {
     604                 :       1211 :     emit_write_bytecode_byte(emit, 0, MP_BC_ROT_TWO);
     605                 :       1211 : }
     606                 :            : 
     607                 :        772 : void mp_emit_bc_rot_three(emit_t *emit) {
     608                 :        772 :     emit_write_bytecode_byte(emit, 0, MP_BC_ROT_THREE);
     609                 :        772 : }
     610                 :            : 
     611                 :       8532 : void mp_emit_bc_jump(emit_t *emit, mp_uint_t label) {
     612                 :       8532 :     emit_write_bytecode_byte_label(emit, 0, MP_BC_JUMP, label);
     613                 :       8532 :     emit->suppress = true;
     614                 :       8532 : }
     615                 :            : 
     616                 :      55103 : void mp_emit_bc_pop_jump_if(emit_t *emit, bool cond, mp_uint_t label) {
     617         [ +  + ]:      55103 :     if (cond) {
     618                 :       4778 :         emit_write_bytecode_byte_label(emit, -1, MP_BC_POP_JUMP_IF_TRUE, label);
     619                 :            :     } else {
     620                 :      50325 :         emit_write_bytecode_byte_label(emit, -1, MP_BC_POP_JUMP_IF_FALSE, label);
     621                 :            :     }
     622                 :      55103 : }
     623                 :            : 
     624                 :        475 : void mp_emit_bc_jump_if_or_pop(emit_t *emit, bool cond, mp_uint_t label) {
     625         [ +  + ]:        475 :     if (cond) {
     626                 :        226 :         emit_write_bytecode_byte_label(emit, -1, MP_BC_JUMP_IF_TRUE_OR_POP, label);
     627                 :            :     } else {
     628                 :        249 :         emit_write_bytecode_byte_label(emit, -1, MP_BC_JUMP_IF_FALSE_OR_POP, label);
     629                 :            :     }
     630                 :        475 : }
     631                 :            : 
     632                 :        712 : void mp_emit_bc_unwind_jump(emit_t *emit, mp_uint_t label, mp_uint_t except_depth) {
     633         [ +  + ]:        712 :     if (except_depth == 0) {
     634         [ +  + ]:        497 :         if (label & MP_EMIT_BREAK_FROM_FOR) {
     635                 :            :             // need to pop the iterator if we are breaking out of a for loop
     636                 :        189 :             emit_write_bytecode_raw_byte(emit, MP_BC_POP_TOP);
     637                 :            :             // also pop the iter_buf
     638         [ +  + ]:        756 :             for (size_t i = 0; i < MP_OBJ_ITER_BUF_NSLOTS - 1; ++i) {
     639                 :        567 :                 emit_write_bytecode_raw_byte(emit, MP_BC_POP_TOP);
     640                 :            :             }
     641                 :            :         }
     642                 :        497 :         emit_write_bytecode_byte_label(emit, 0, MP_BC_JUMP, label & ~MP_EMIT_BREAK_FROM_FOR);
     643                 :            :     } else {
     644                 :        215 :         emit_write_bytecode_byte_label(emit, 0, MP_BC_UNWIND_JUMP, label & ~MP_EMIT_BREAK_FROM_FOR);
     645                 :        215 :         emit_write_bytecode_raw_byte(emit, ((label & MP_EMIT_BREAK_FROM_FOR) ? 0x80 : 0) | except_depth);
     646                 :            :     }
     647                 :        712 :     emit->suppress = true;
     648                 :        712 : }
     649                 :            : 
     650                 :      83154 : void mp_emit_bc_setup_block(emit_t *emit, mp_uint_t label, int kind) {
     651                 :      83154 :     MP_STATIC_ASSERT(MP_BC_SETUP_WITH + MP_EMIT_SETUP_BLOCK_WITH == MP_BC_SETUP_WITH);
     652                 :      83154 :     MP_STATIC_ASSERT(MP_BC_SETUP_WITH + MP_EMIT_SETUP_BLOCK_EXCEPT == MP_BC_SETUP_EXCEPT);
     653                 :      83154 :     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         [ +  + ]:      83154 :     int stack_adj = kind == MP_EMIT_SETUP_BLOCK_WITH ? 2 : 0;
     657                 :      83154 :     emit_write_bytecode_byte_label(emit, stack_adj, MP_BC_SETUP_WITH + kind, label);
     658                 :      83154 : }
     659                 :            : 
     660                 :      36693 : void mp_emit_bc_with_cleanup(emit_t *emit, mp_uint_t label) {
     661                 :      36693 :     mp_emit_bc_load_const_tok(emit, MP_TOKEN_KW_NONE);
     662                 :      36693 :     mp_emit_bc_label_assign(emit, label);
     663                 :            :     // The +2 is to ensure we have enough stack space to call the __exit__ method
     664                 :      36693 :     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                 :      36693 :     mp_emit_bc_adjust_stack_size(emit, -4);
     667                 :      36693 : }
     668                 :            : 
     669                 :      83154 : void mp_emit_bc_end_finally(emit_t *emit) {
     670                 :      83154 :     emit_write_bytecode_byte(emit, -1, MP_BC_END_FINALLY);
     671                 :      83154 : }
     672                 :            : 
     673                 :       3834 : void mp_emit_bc_get_iter(emit_t *emit, bool use_stack) {
     674         [ +  + ]:       3834 :     int stack_adj = use_stack ? MP_OBJ_ITER_BUF_NSLOTS - 1 : 0;
     675                 :       3834 :     emit_write_bytecode_byte(emit, stack_adj, use_stack ? MP_BC_GET_ITER_STACK : MP_BC_GET_ITER);
     676                 :       3834 : }
     677                 :            : 
     678                 :       2431 : void mp_emit_bc_for_iter(emit_t *emit, mp_uint_t label) {
     679                 :       2431 :     emit_write_bytecode_byte_label(emit, 1, MP_BC_FOR_ITER, label);
     680                 :       2431 : }
     681                 :            : 
     682                 :       2431 : void mp_emit_bc_for_iter_end(emit_t *emit) {
     683                 :       2431 :     mp_emit_bc_adjust_stack_size(emit, -MP_OBJ_ITER_BUF_NSLOTS);
     684                 :       2431 : }
     685                 :            : 
     686                 :      89463 : void mp_emit_bc_pop_except_jump(emit_t *emit, mp_uint_t label, bool within_exc_handler) {
     687                 :      89463 :     (void)within_exc_handler;
     688                 :      89463 :     emit_write_bytecode_byte_label(emit, 0, MP_BC_POP_EXCEPT_JUMP, label);
     689                 :      89463 :     emit->suppress = true;
     690                 :      89463 : }
     691                 :            : 
     692                 :       2184 : void mp_emit_bc_unary_op(emit_t *emit, mp_unary_op_t op) {
     693                 :       2184 :     emit_write_bytecode_byte(emit, 0, MP_BC_UNARY_OP_MULTI + op);
     694                 :       2184 : }
     695                 :            : 
     696                 :      68350 : void mp_emit_bc_binary_op(emit_t *emit, mp_binary_op_t op) {
     697                 :      68350 :     bool invert = false;
     698         [ +  + ]:      68350 :     if (op == MP_BINARY_OP_NOT_IN) {
     699                 :            :         invert = true;
     700                 :            :         op = MP_BINARY_OP_IN;
     701         [ +  + ]:      68104 :     } else if (op == MP_BINARY_OP_IS_NOT) {
     702                 :        933 :         invert = true;
     703                 :        933 :         op = MP_BINARY_OP_IS;
     704                 :            :     }
     705                 :      68350 :     emit_write_bytecode_byte(emit, -1, MP_BC_BINARY_OP_MULTI + op);
     706         [ +  + ]:      68350 :     if (invert) {
     707                 :       1179 :         emit_write_bytecode_byte(emit, 0, MP_BC_UNARY_OP_MULTI + MP_UNARY_OP_NOT);
     708                 :            :     }
     709                 :      68350 : }
     710                 :            : 
     711                 :      12502 : void mp_emit_bc_build(emit_t *emit, mp_uint_t n_args, int kind) {
     712                 :      12502 :     MP_STATIC_ASSERT(MP_BC_BUILD_TUPLE + MP_EMIT_BUILD_TUPLE == MP_BC_BUILD_TUPLE);
     713                 :      12502 :     MP_STATIC_ASSERT(MP_BC_BUILD_TUPLE + MP_EMIT_BUILD_LIST == MP_BC_BUILD_LIST);
     714                 :      12502 :     MP_STATIC_ASSERT(MP_BC_BUILD_TUPLE + MP_EMIT_BUILD_MAP == MP_BC_BUILD_MAP);
     715                 :      12502 :     MP_STATIC_ASSERT(MP_BC_BUILD_TUPLE + MP_EMIT_BUILD_SET == MP_BC_BUILD_SET);
     716                 :      12502 :     MP_STATIC_ASSERT(MP_BC_BUILD_TUPLE + MP_EMIT_BUILD_SLICE == MP_BC_BUILD_SLICE);
     717         [ +  + ]:      12502 :     int stack_adj = kind == MP_EMIT_BUILD_MAP ? 1 : 1 - n_args;
     718                 :      12502 :     emit_write_bytecode_byte_uint(emit, stack_adj, MP_BC_BUILD_TUPLE + kind, n_args);
     719                 :      12502 : }
     720                 :            : 
     721                 :       3525 : void mp_emit_bc_store_map(emit_t *emit) {
     722                 :       3525 :     emit_write_bytecode_byte(emit, -2, MP_BC_STORE_MAP);
     723                 :       3525 : }
     724                 :            : 
     725                 :        348 : void mp_emit_bc_store_comp(emit_t *emit, scope_kind_t kind, mp_uint_t collection_stack_index) {
     726                 :        348 :     int t;
     727                 :        348 :     int n;
     728         [ +  + ]:        348 :     if (kind == SCOPE_LIST_COMP) {
     729                 :            :         n = 0;
     730                 :            :         t = 0;
     731         [ +  + ]:         53 :     } else if (!MICROPY_PY_BUILTINS_SET || kind == SCOPE_DICT_COMP) {
     732                 :            :         n = 1;
     733                 :            :         t = 1;
     734                 :          5 :     } else if (MICROPY_PY_BUILTINS_SET) {
     735                 :          5 :         n = 0;
     736                 :          5 :         t = 2;
     737                 :            :     }
     738                 :            :     // the lower 2 bits of the opcode argument indicate the collection type
     739                 :        348 :     emit_write_bytecode_byte_uint(emit, -1 - n, MP_BC_STORE_COMP, ((collection_stack_index + n) << 2) | t);
     740                 :        348 : }
     741                 :            : 
     742                 :        686 : void mp_emit_bc_unpack_sequence(emit_t *emit, mp_uint_t n_args) {
     743                 :        686 :     emit_write_bytecode_byte_uint(emit, -1 + n_args, MP_BC_UNPACK_SEQUENCE, n_args);
     744                 :        686 : }
     745                 :            : 
     746                 :        177 : void mp_emit_bc_unpack_ex(emit_t *emit, mp_uint_t n_left, mp_uint_t n_right) {
     747                 :        177 :     emit_write_bytecode_byte_uint(emit, -1 + n_left + n_right + 1, MP_BC_UNPACK_EX, n_left | (n_right << 8));
     748                 :        177 : }
     749                 :            : 
     750                 :      14881 : void mp_emit_bc_make_function(emit_t *emit, scope_t *scope, mp_uint_t n_pos_defaults, mp_uint_t n_kw_defaults) {
     751         [ +  + ]:      14881 :     if (n_pos_defaults == 0 && n_kw_defaults == 0) {
     752                 :      14115 :         emit_write_bytecode_byte_child(emit, 1, MP_BC_MAKE_FUNCTION, scope->raw_code);
     753                 :            :     } else {
     754                 :        766 :         emit_write_bytecode_byte_child(emit, -1, MP_BC_MAKE_FUNCTION_DEFARGS, scope->raw_code);
     755                 :            :     }
     756                 :      14881 : }
     757                 :            : 
     758                 :        244 : 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) {
     759         [ +  + ]:        244 :     if (n_pos_defaults == 0 && n_kw_defaults == 0) {
     760                 :        235 :         int stack_adj = -n_closed_over + 1;
     761                 :        235 :         emit_write_bytecode_byte_child(emit, stack_adj, MP_BC_MAKE_CLOSURE, scope->raw_code);
     762                 :        235 :         emit_write_bytecode_raw_byte(emit, n_closed_over);
     763                 :            :     } else {
     764         [ -  + ]:          9 :         assert(n_closed_over <= 255);
     765                 :          9 :         int stack_adj = -2 - (mp_int_t)n_closed_over + 1;
     766                 :          9 :         emit_write_bytecode_byte_child(emit, stack_adj, MP_BC_MAKE_CLOSURE_DEFARGS, scope->raw_code);
     767                 :          9 :         emit_write_bytecode_raw_byte(emit, n_closed_over);
     768                 :            :     }
     769                 :        244 : }
     770                 :            : 
     771                 :     322200 : 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) {
     772         [ +  + ]:     322200 :     if (star_flags) {
     773                 :            :         // each positional arg is one object, each kwarg is two objects, the key
     774                 :            :         // and the value and one extra object for the star args bitmap.
     775                 :        774 :         stack_adj -= (int)n_positional + 2 * (int)n_keyword + 1;
     776                 :        774 :         emit_write_bytecode_byte_uint(emit, stack_adj, bytecode_base + 1, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints?
     777                 :            :     } else {
     778                 :     321426 :         stack_adj -= (int)n_positional + 2 * (int)n_keyword;
     779                 :     321426 :         emit_write_bytecode_byte_uint(emit, stack_adj, bytecode_base, (n_keyword << 8) | n_positional); // TODO make it 2 separate uints?
     780                 :            :     }
     781                 :     322200 : }
     782                 :            : 
     783                 :     296020 : void mp_emit_bc_call_function(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags) {
     784                 :     296020 :     emit_bc_call_function_method_helper(emit, 0, MP_BC_CALL_FUNCTION, n_positional, n_keyword, star_flags);
     785                 :     296020 : }
     786                 :            : 
     787                 :      26180 : void mp_emit_bc_call_method(emit_t *emit, mp_uint_t n_positional, mp_uint_t n_keyword, mp_uint_t star_flags) {
     788                 :      26180 :     emit_bc_call_function_method_helper(emit, -1, MP_BC_CALL_METHOD, n_positional, n_keyword, star_flags);
     789                 :      26180 : }
     790                 :            : 
     791                 :      30461 : void mp_emit_bc_return_value(emit_t *emit) {
     792                 :      30461 :     emit_write_bytecode_byte(emit, -1, MP_BC_RETURN_VALUE);
     793                 :      30461 :     emit->suppress = true;
     794                 :      30461 : }
     795                 :            : 
     796                 :       5499 : void mp_emit_bc_raise_varargs(emit_t *emit, mp_uint_t n_args) {
     797                 :       5499 :     MP_STATIC_ASSERT(MP_BC_RAISE_LAST + 1 == MP_BC_RAISE_OBJ);
     798                 :       5499 :     MP_STATIC_ASSERT(MP_BC_RAISE_LAST + 2 == MP_BC_RAISE_FROM);
     799         [ -  + ]:       5499 :     assert(n_args <= 2);
     800                 :       5499 :     emit_write_bytecode_byte(emit, -n_args, MP_BC_RAISE_LAST + n_args);
     801                 :       5499 :     emit->suppress = true;
     802                 :       5499 : }
     803                 :            : 
     804                 :       2284 : void mp_emit_bc_yield(emit_t *emit, int kind) {
     805                 :       2284 :     MP_STATIC_ASSERT(MP_BC_YIELD_VALUE + 1 == MP_BC_YIELD_FROM);
     806                 :       2284 :     emit_write_bytecode_byte(emit, -kind, MP_BC_YIELD_VALUE + kind);
     807                 :       2284 :     emit->scope->scope_flags |= MP_SCOPE_FLAG_GENERATOR;
     808                 :       2284 : }
     809                 :            : 
     810                 :      44693 : void mp_emit_bc_start_except_handler(emit_t *emit) {
     811                 :      44693 :     mp_emit_bc_adjust_stack_size(emit, 4); // stack adjust for the exception instance, +3 for possible UNWIND_JUMP state
     812                 :      44693 : }
     813                 :            : 
     814                 :      44689 : void mp_emit_bc_end_except_handler(emit_t *emit) {
     815                 :      44689 :     mp_emit_bc_adjust_stack_size(emit, -3); // stack adjust
     816                 :      44689 : }
     817                 :            : 
     818                 :            : #if MICROPY_EMIT_NATIVE
     819                 :            : const emit_method_table_t emit_bc_method_table = {
     820                 :            :     #if MICROPY_DYNAMIC_COMPILER
     821                 :            :     NULL,
     822                 :            :     NULL,
     823                 :            :     #endif
     824                 :            : 
     825                 :            :     mp_emit_bc_start_pass,
     826                 :            :     mp_emit_bc_end_pass,
     827                 :            :     mp_emit_bc_adjust_stack_size,
     828                 :            :     mp_emit_bc_set_source_line,
     829                 :            : 
     830                 :            :     {
     831                 :            :         mp_emit_bc_load_local,
     832                 :            :         mp_emit_bc_load_global,
     833                 :            :     },
     834                 :            :     {
     835                 :            :         mp_emit_bc_store_local,
     836                 :            :         mp_emit_bc_store_global,
     837                 :            :     },
     838                 :            :     {
     839                 :            :         mp_emit_bc_delete_local,
     840                 :            :         mp_emit_bc_delete_global,
     841                 :            :     },
     842                 :            : 
     843                 :            :     mp_emit_bc_label_assign,
     844                 :            :     mp_emit_bc_import,
     845                 :            :     mp_emit_bc_load_const_tok,
     846                 :            :     mp_emit_bc_load_const_small_int,
     847                 :            :     mp_emit_bc_load_const_str,
     848                 :            :     mp_emit_bc_load_const_obj,
     849                 :            :     mp_emit_bc_load_null,
     850                 :            :     mp_emit_bc_load_method,
     851                 :            :     mp_emit_bc_load_build_class,
     852                 :            :     mp_emit_bc_subscr,
     853                 :            :     mp_emit_bc_attr,
     854                 :            :     mp_emit_bc_dup_top,
     855                 :            :     mp_emit_bc_dup_top_two,
     856                 :            :     mp_emit_bc_pop_top,
     857                 :            :     mp_emit_bc_rot_two,
     858                 :            :     mp_emit_bc_rot_three,
     859                 :            :     mp_emit_bc_jump,
     860                 :            :     mp_emit_bc_pop_jump_if,
     861                 :            :     mp_emit_bc_jump_if_or_pop,
     862                 :            :     mp_emit_bc_unwind_jump,
     863                 :            :     mp_emit_bc_setup_block,
     864                 :            :     mp_emit_bc_with_cleanup,
     865                 :            :     mp_emit_bc_end_finally,
     866                 :            :     mp_emit_bc_get_iter,
     867                 :            :     mp_emit_bc_for_iter,
     868                 :            :     mp_emit_bc_for_iter_end,
     869                 :            :     mp_emit_bc_pop_except_jump,
     870                 :            :     mp_emit_bc_unary_op,
     871                 :            :     mp_emit_bc_binary_op,
     872                 :            :     mp_emit_bc_build,
     873                 :            :     mp_emit_bc_store_map,
     874                 :            :     mp_emit_bc_store_comp,
     875                 :            :     mp_emit_bc_unpack_sequence,
     876                 :            :     mp_emit_bc_unpack_ex,
     877                 :            :     mp_emit_bc_make_function,
     878                 :            :     mp_emit_bc_make_closure,
     879                 :            :     mp_emit_bc_call_function,
     880                 :            :     mp_emit_bc_call_method,
     881                 :            :     mp_emit_bc_return_value,
     882                 :            :     mp_emit_bc_raise_varargs,
     883                 :            :     mp_emit_bc_yield,
     884                 :            : 
     885                 :            :     mp_emit_bc_start_except_handler,
     886                 :            :     mp_emit_bc_end_except_handler,
     887                 :            : };
     888                 :            : #else
     889                 :            : const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_load_id_ops = {
     890                 :            :     mp_emit_bc_load_local,
     891                 :            :     mp_emit_bc_load_global,
     892                 :            : };
     893                 :            : 
     894                 :            : const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_store_id_ops = {
     895                 :            :     mp_emit_bc_store_local,
     896                 :            :     mp_emit_bc_store_global,
     897                 :            : };
     898                 :            : 
     899                 :            : const mp_emit_method_table_id_ops_t mp_emit_bc_method_table_delete_id_ops = {
     900                 :            :     mp_emit_bc_delete_local,
     901                 :            :     mp_emit_bc_delete_global,
     902                 :            : };
     903                 :            : #endif
     904                 :            : 
     905                 :            : #endif // MICROPY_ENABLE_COMPILER

Generated by: LCOV version 1.15-5-g462f71d