LCOV - code coverage report
Current view: top level - py - nativeglue.c (source / functions) Hit Total Coverage
Test: unix_coverage_v1.19.1-724-gfb7d21153.info Lines: 86 91 94.5 %
Date: 2022-12-01 09:37:31 Functions: 9 9 100.0 %
Branches: 48 52 92.3 %

           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) 2014 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 <stdarg.h>
      28                 :            : #include <stdio.h>
      29                 :            : #include <string.h>
      30                 :            : #include <assert.h>
      31                 :            : 
      32                 :            : #include "py/runtime.h"
      33                 :            : #include "py/smallint.h"
      34                 :            : #include "py/nativeglue.h"
      35                 :            : #include "py/gc.h"
      36                 :            : 
      37                 :            : #if MICROPY_DEBUG_VERBOSE // print debugging info
      38                 :            : #define DEBUG_printf DEBUG_printf
      39                 :            : #else // don't print debugging info
      40                 :            : #define DEBUG_printf(...) (void)0
      41                 :            : #endif
      42                 :            : 
      43                 :            : #if MICROPY_EMIT_NATIVE
      44                 :            : 
      45                 :       1154 : int mp_native_type_from_qstr(qstr qst) {
      46   [ +  +  +  +  :       1154 :     switch (qst) {
             +  +  +  +  
                      + ]
      47                 :            :         case MP_QSTR_object:
      48                 :            :             return MP_NATIVE_TYPE_OBJ;
      49                 :         16 :         case MP_QSTR_bool:
      50                 :         16 :             return MP_NATIVE_TYPE_BOOL;
      51                 :        314 :         case MP_QSTR_int:
      52                 :        314 :             return MP_NATIVE_TYPE_INT;
      53                 :         70 :         case MP_QSTR_uint:
      54                 :         70 :             return MP_NATIVE_TYPE_UINT;
      55                 :         20 :         case MP_QSTR_ptr:
      56                 :         20 :             return MP_NATIVE_TYPE_PTR;
      57                 :         42 :         case MP_QSTR_ptr8:
      58                 :         42 :             return MP_NATIVE_TYPE_PTR8;
      59                 :         28 :         case MP_QSTR_ptr16:
      60                 :         28 :             return MP_NATIVE_TYPE_PTR16;
      61                 :         36 :         case MP_QSTR_ptr32:
      62                 :         36 :             return MP_NATIVE_TYPE_PTR32;
      63                 :        620 :         default:
      64                 :        620 :             return -1;
      65                 :            :     }
      66                 :            : }
      67                 :            : 
      68                 :            : // convert a MicroPython object to a valid native value based on type
      69                 :       1524 : mp_uint_t mp_native_from_obj(mp_obj_t obj, mp_uint_t type) {
      70                 :       1524 :     DEBUG_printf("mp_native_from_obj(%p, " UINT_FMT ")\n", obj, type);
      71   [ -  +  +  + ]:       1524 :     switch (type & 0xf) {
      72                 :          0 :         case MP_NATIVE_TYPE_OBJ:
      73                 :          0 :             return (mp_uint_t)obj;
      74                 :         32 :         case MP_NATIVE_TYPE_BOOL:
      75                 :         32 :             return mp_obj_is_true(obj);
      76                 :       1356 :         case MP_NATIVE_TYPE_INT:
      77                 :            :         case MP_NATIVE_TYPE_UINT:
      78                 :       1356 :             return mp_obj_get_int_truncated(obj);
      79                 :        136 :         default: { // cast obj to a pointer
      80                 :        136 :             mp_buffer_info_t bufinfo;
      81         [ +  + ]:        136 :             if (mp_get_buffer(obj, &bufinfo, MP_BUFFER_READ)) {
      82                 :        128 :                 return (mp_uint_t)bufinfo.buf;
      83                 :            :             } else {
      84                 :            :                 // assume obj is an integer that represents an address
      85                 :          8 :                 return mp_obj_get_int_truncated(obj);
      86                 :            :             }
      87                 :            :         }
      88                 :            :     }
      89                 :            : }
      90                 :            : 
      91                 :            : #endif
      92                 :            : 
      93                 :            : #if MICROPY_EMIT_MACHINE_CODE
      94                 :            : 
      95                 :            : // convert a native value to a MicroPython object based on type
      96                 :       1188 : mp_obj_t mp_native_to_obj(mp_uint_t val, mp_uint_t type) {
      97                 :       1188 :     DEBUG_printf("mp_native_to_obj(" UINT_FMT ", " UINT_FMT ")\n", val, type);
      98   [ -  +  +  +  :       1188 :     switch (type & 0xf) {
                      + ]
      99                 :          0 :         case MP_NATIVE_TYPE_OBJ:
     100                 :          0 :             return (mp_obj_t)val;
     101                 :        104 :         case MP_NATIVE_TYPE_BOOL:
     102         [ +  + ]:        104 :             return mp_obj_new_bool(val);
     103                 :        908 :         case MP_NATIVE_TYPE_INT:
     104                 :        908 :             return mp_obj_new_int(val);
     105                 :        172 :         case MP_NATIVE_TYPE_UINT:
     106                 :        172 :             return mp_obj_new_int_from_uint(val);
     107                 :          4 :         default: // a pointer
     108                 :            :             // we return just the value of the pointer as an integer
     109                 :          4 :             return mp_obj_new_int_from_uint(val);
     110                 :            :     }
     111                 :            : }
     112                 :            : 
     113                 :            : #endif
     114                 :            : 
     115                 :            : #if MICROPY_EMIT_NATIVE && !MICROPY_DYNAMIC_COMPILER
     116                 :            : 
     117                 :            : #if !MICROPY_PY_BUILTINS_SET
     118                 :            : mp_obj_t mp_obj_new_set(size_t n_args, mp_obj_t *items) {
     119                 :            :     (void)n_args;
     120                 :            :     (void)items;
     121                 :            :     mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("set unsupported"));
     122                 :            : }
     123                 :            : 
     124                 :            : void mp_obj_set_store(mp_obj_t self_in, mp_obj_t item) {
     125                 :            :     (void)self_in;
     126                 :            :     (void)item;
     127                 :            :     mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("set unsupported"));
     128                 :            : }
     129                 :            : #endif
     130                 :            : 
     131                 :            : #if !MICROPY_PY_BUILTINS_SLICE
     132                 :            : mp_obj_t mp_obj_new_slice(mp_obj_t ostart, mp_obj_t ostop, mp_obj_t ostep) {
     133                 :            :     (void)ostart;
     134                 :            :     (void)ostop;
     135                 :            :     (void)ostep;
     136                 :            :     mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("slice unsupported"));
     137                 :            : }
     138                 :            : #endif
     139                 :            : 
     140                 :     621255 : STATIC mp_obj_dict_t *mp_native_swap_globals(mp_obj_dict_t *new_globals) {
     141         [ +  + ]:     621255 :     if (new_globals == NULL) {
     142                 :            :         // Globals were the originally the same so don't restore them
     143                 :            :         return NULL;
     144                 :            :     }
     145                 :     619733 :     mp_obj_dict_t *old_globals = mp_globals_get();
     146         [ +  + ]:     619733 :     if (old_globals == new_globals) {
     147                 :            :         // Don't set globals if they are the same, and return NULL to indicate this
     148                 :            :         return NULL;
     149                 :            :     }
     150                 :     447378 :     mp_globals_set(new_globals);
     151                 :     447378 :     return old_globals;
     152                 :            : }
     153                 :            : 
     154                 :            : // wrapper that accepts n_args and n_kw in one argument
     155                 :            : // (native emitter can only pass at most 3 arguments to a function)
     156                 :     798508 : STATIC mp_obj_t mp_native_call_function_n_kw(mp_obj_t fun_in, size_t n_args_kw, const mp_obj_t *args) {
     157                 :     798508 :     return mp_call_function_n_kw(fun_in, n_args_kw & 0xff, (n_args_kw >> 8) & 0xff, args);
     158                 :            : }
     159                 :            : 
     160                 :            : // wrapper that makes raise obj and raises it
     161                 :            : // END_FINALLY opcode requires that we don't raise if o==None
     162                 :     163739 : STATIC void mp_native_raise(mp_obj_t o) {
     163         [ +  + ]:     163739 :     if (o != MP_OBJ_NULL && o != mp_const_none) {
     164                 :     149564 :         nlr_raise(mp_make_raise_obj(o));
     165                 :            :     }
     166                 :      14175 : }
     167                 :            : 
     168                 :            : // wrapper that handles iterator buffer
     169                 :     154767 : STATIC mp_obj_t mp_native_getiter(mp_obj_t obj, mp_obj_iter_buf_t *iter) {
     170         [ +  + ]:     154767 :     if (iter == NULL) {
     171                 :      75084 :         return mp_getiter(obj, NULL);
     172                 :            :     } else {
     173                 :      79683 :         obj = mp_getiter(obj, iter);
     174         [ +  + ]:      79679 :         if (obj != MP_OBJ_FROM_PTR(iter)) {
     175                 :            :             // Iterator didn't use the stack so indicate that with MP_OBJ_NULL.
     176                 :      77615 :             iter->base.type = MP_OBJ_NULL;
     177                 :      77615 :             iter->buf[0] = obj;
     178                 :            :         }
     179                 :      79679 :         return NULL;
     180                 :            :     }
     181                 :            : }
     182                 :            : 
     183                 :            : // wrapper that handles iterator buffer
     184                 :     119522 : STATIC mp_obj_t mp_native_iternext(mp_obj_iter_buf_t *iter) {
     185                 :     119522 :     mp_obj_t obj;
     186         [ +  + ]:     119522 :     if (iter->base.type == MP_OBJ_NULL) {
     187                 :     105619 :         obj = iter->buf[0];
     188                 :            :     } else {
     189                 :            :         obj = MP_OBJ_FROM_PTR(iter);
     190                 :            :     }
     191                 :     119522 :     return mp_iternext(obj);
     192                 :            : }
     193                 :            : 
     194                 :     149633 : STATIC bool mp_native_yield_from(mp_obj_t gen, mp_obj_t send_value, mp_obj_t *ret_value) {
     195                 :     149633 :     mp_vm_return_kind_t ret_kind;
     196                 :     149633 :     nlr_buf_t nlr_buf;
     197                 :     149633 :     mp_obj_t throw_value = *ret_value;
     198         [ +  + ]:     149633 :     if (nlr_push(&nlr_buf) == 0) {
     199         [ +  + ]:     149633 :         if (throw_value != MP_OBJ_NULL) {
     200                 :         58 :             send_value = MP_OBJ_NULL;
     201                 :            :         }
     202                 :     149633 :         ret_kind = mp_resume(gen, send_value, throw_value, ret_value);
     203                 :      75123 :         nlr_pop();
     204                 :            :     } else {
     205                 :      74510 :         ret_kind = MP_VM_RETURN_EXCEPTION;
     206                 :      74510 :         *ret_value = nlr_buf.ret_val;
     207                 :            :     }
     208                 :            : 
     209         [ +  + ]:     149633 :     if (ret_kind == MP_VM_RETURN_YIELD) {
     210                 :            :         return true;
     211         [ +  + ]:      74904 :     } else if (ret_kind == MP_VM_RETURN_NORMAL) {
     212         [ -  + ]:        139 :         if (*ret_value == MP_OBJ_STOP_ITERATION) {
     213                 :          0 :             *ret_value = mp_const_none;
     214                 :            :         }
     215                 :            :     } else {
     216         [ -  + ]:      74765 :         assert(ret_kind == MP_VM_RETURN_EXCEPTION);
     217         [ +  + ]:      74765 :         if (!mp_obj_exception_match(*ret_value, MP_OBJ_FROM_PTR(&mp_type_StopIteration))) {
     218                 :        270 :             nlr_raise(*ret_value);
     219                 :            :         }
     220                 :      74495 :         *ret_value = mp_obj_exception_get_value(*ret_value);
     221                 :            :     }
     222                 :            : 
     223   [ +  +  +  + ]:      74634 :     if (throw_value != MP_OBJ_NULL && mp_obj_exception_match(throw_value, MP_OBJ_FROM_PTR(&mp_type_GeneratorExit))) {
     224                 :          4 :         nlr_raise(mp_make_raise_obj(throw_value));
     225                 :            :     }
     226                 :            : 
     227                 :            :     return false;
     228                 :            : }
     229                 :            : 
     230                 :            : #if !MICROPY_PY_BUILTINS_FLOAT
     231                 :            : 
     232                 :            : STATIC mp_obj_t mp_obj_new_float_from_f(float f) {
     233                 :            :     (void)f;
     234                 :            :     mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("float unsupported"));
     235                 :            : }
     236                 :            : 
     237                 :            : STATIC mp_obj_t mp_obj_new_float_from_d(double d) {
     238                 :            :     (void)d;
     239                 :            :     mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("float unsupported"));
     240                 :            : }
     241                 :            : 
     242                 :            : STATIC float mp_obj_get_float_to_f(mp_obj_t o) {
     243                 :            :     (void)o;
     244                 :            :     mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("float unsupported"));
     245                 :            : }
     246                 :            : 
     247                 :            : STATIC double mp_obj_get_float_to_d(mp_obj_t o) {
     248                 :            :     (void)o;
     249                 :            :     mp_raise_msg(&mp_type_RuntimeError, MP_ERROR_TEXT("float unsupported"));
     250                 :            : }
     251                 :            : 
     252                 :            : #endif
     253                 :            : 
     254                 :            : // these must correspond to the respective enum in nativeglue.h
     255                 :            : const mp_fun_table_t mp_fun_table = {
     256                 :            :     mp_const_none,
     257                 :            :     mp_const_false,
     258                 :            :     mp_const_true,
     259                 :            :     mp_native_from_obj,
     260                 :            :     mp_native_to_obj,
     261                 :            :     mp_native_swap_globals,
     262                 :            :     mp_load_name,
     263                 :            :     mp_load_global,
     264                 :            :     mp_load_build_class,
     265                 :            :     mp_load_attr,
     266                 :            :     mp_load_method,
     267                 :            :     mp_load_super_method,
     268                 :            :     mp_store_name,
     269                 :            :     mp_store_global,
     270                 :            :     mp_store_attr,
     271                 :            :     mp_obj_subscr,
     272                 :            :     mp_obj_is_true,
     273                 :            :     mp_unary_op,
     274                 :            :     mp_binary_op,
     275                 :            :     mp_obj_new_tuple,
     276                 :            :     mp_obj_new_list,
     277                 :            :     mp_obj_new_dict,
     278                 :            :     mp_obj_new_set,
     279                 :            :     mp_obj_set_store,
     280                 :            :     mp_obj_list_append,
     281                 :            :     mp_obj_dict_store,
     282                 :            :     mp_make_function_from_raw_code,
     283                 :            :     mp_native_call_function_n_kw,
     284                 :            :     mp_call_method_n_kw,
     285                 :            :     mp_call_method_n_kw_var,
     286                 :            :     mp_native_getiter,
     287                 :            :     mp_native_iternext,
     288                 :            :     #if MICROPY_NLR_SETJMP
     289                 :            :     nlr_push_tail,
     290                 :            :     #else
     291                 :            :     nlr_push,
     292                 :            :     #endif
     293                 :            :     nlr_pop,
     294                 :            :     mp_native_raise,
     295                 :            :     mp_import_name,
     296                 :            :     mp_import_from,
     297                 :            :     mp_import_all,
     298                 :            :     mp_obj_new_slice,
     299                 :            :     mp_unpack_sequence,
     300                 :            :     mp_unpack_ex,
     301                 :            :     mp_delete_name,
     302                 :            :     mp_delete_global,
     303                 :            :     mp_obj_new_closure,
     304                 :            :     mp_arg_check_num_sig,
     305                 :            :     mp_setup_code_state_native,
     306                 :            :     mp_small_int_floor_divide,
     307                 :            :     mp_small_int_modulo,
     308                 :            :     mp_native_yield_from,
     309                 :            :     #if MICROPY_NLR_SETJMP
     310                 :            :     setjmp,
     311                 :            :     #else
     312                 :            :     NULL,
     313                 :            :     #endif
     314                 :            :     // Additional entries for dynamic runtime, starts at index 50
     315                 :            :     memset,
     316                 :            :     memmove,
     317                 :            :     gc_realloc,
     318                 :            :     mp_printf,
     319                 :            :     mp_vprintf,
     320                 :            :     mp_raise_msg,
     321                 :            :     mp_obj_get_type,
     322                 :            :     mp_obj_new_str,
     323                 :            :     mp_obj_new_bytes,
     324                 :            :     mp_obj_new_bytearray_by_ref,
     325                 :            :     mp_obj_new_float_from_f,
     326                 :            :     mp_obj_new_float_from_d,
     327                 :            :     mp_obj_get_float_to_f,
     328                 :            :     mp_obj_get_float_to_d,
     329                 :            :     mp_get_buffer_raise,
     330                 :            :     mp_get_stream_raise,
     331                 :            :     &mp_plat_print,
     332                 :            :     &mp_type_type,
     333                 :            :     &mp_type_str,
     334                 :            :     &mp_type_list,
     335                 :            :     &mp_type_dict,
     336                 :            :     &mp_type_fun_builtin_0,
     337                 :            :     &mp_type_fun_builtin_1,
     338                 :            :     &mp_type_fun_builtin_2,
     339                 :            :     &mp_type_fun_builtin_3,
     340                 :            :     &mp_type_fun_builtin_var,
     341                 :            :     &mp_stream_read_obj,
     342                 :            :     &mp_stream_readinto_obj,
     343                 :            :     &mp_stream_unbuffered_readline_obj,
     344                 :            :     &mp_stream_write_obj,
     345                 :            : };
     346                 :            : 
     347                 :            : #elif MICROPY_EMIT_NATIVE && MICROPY_DYNAMIC_COMPILER
     348                 :            : 
     349                 :            : const int mp_fun_table;
     350                 :            : 
     351                 :            : #endif // MICROPY_EMIT_NATIVE

Generated by: LCOV version 1.15-5-g462f71d