Numworks Epsilon  1.4.1
Graphing Calculator Operating System
nativeglue.c
Go to the documentation of this file.
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 <stdio.h>
28 #include <string.h>
29 #include <assert.h>
30 
31 #include "py/runtime.h"
32 #include "py/smallint.h"
33 #include "py/emitglue.h"
34 #include "py/bc.h"
35 
36 #if MICROPY_DEBUG_VERBOSE // print debugging info
37 #define DEBUG_printf DEBUG_printf
38 #else // don't print debugging info
39 #define DEBUG_printf(...) (void)0
40 #endif
41 
42 #if MICROPY_EMIT_NATIVE
43 
44 // convert a MicroPython object to a valid native value based on type
46  DEBUG_printf("mp_convert_obj_to_native(%p, " UINT_FMT ")\n", obj, type);
47  switch (type & 0xf) {
48  case MP_NATIVE_TYPE_OBJ: return (mp_uint_t)obj;
50  case MP_NATIVE_TYPE_INT:
52  default: { // cast obj to a pointer
53  mp_buffer_info_t bufinfo;
54  if (mp_get_buffer(obj, &bufinfo, MP_BUFFER_RW)) {
55  return (mp_uint_t)bufinfo.buf;
56  } else {
57  // assume obj is an integer that represents an address
58  return mp_obj_get_int_truncated(obj);
59  }
60  }
61  }
62 }
63 
64 #endif
65 
66 #if MICROPY_EMIT_NATIVE || MICROPY_EMIT_INLINE_ASM
67 
68 // convert a native value to a MicroPython object based on type
70  DEBUG_printf("mp_convert_native_to_obj(" UINT_FMT ", " UINT_FMT ")\n", val, type);
71  switch (type & 0xf) {
72  case MP_NATIVE_TYPE_OBJ: return (mp_obj_t)val;
73  case MP_NATIVE_TYPE_BOOL: return mp_obj_new_bool(val);
74  case MP_NATIVE_TYPE_INT: return mp_obj_new_int(val);
76  default: // a pointer
77  // we return just the value of the pointer as an integer
78  return mp_obj_new_int_from_uint(val);
79  }
80 }
81 
82 #endif
83 
84 #if MICROPY_EMIT_NATIVE
85 
86 // wrapper that accepts n_args and n_kw in one argument
87 // (native emitter can only pass at most 3 arguments to a function)
88 mp_obj_t mp_native_call_function_n_kw(mp_obj_t fun_in, size_t n_args_kw, const mp_obj_t *args) {
89  return mp_call_function_n_kw(fun_in, n_args_kw & 0xff, (n_args_kw >> 8) & 0xff, args);
90 }
91 
92 // wrapper that makes raise obj and raises it
93 // END_FINALLY opcode requires that we don't raise if o==None
94 void mp_native_raise(mp_obj_t o) {
95  if (o != mp_const_none) {
97  }
98 }
99 
100 // wrapper that handles iterator buffer
101 STATIC mp_obj_t mp_native_getiter(mp_obj_t obj, mp_obj_iter_buf_t *iter) {
102  if (iter == NULL) {
103  return mp_getiter(obj, NULL);
104  } else {
105  obj = mp_getiter(obj, iter);
106  if (obj != MP_OBJ_FROM_PTR(iter)) {
107  // Iterator didn't use the stack so indicate that with MP_OBJ_NULL.
108  iter->base.type = MP_OBJ_NULL;
109  iter->buf[0] = obj;
110  }
111  return NULL;
112  }
113 }
114 
115 // wrapper that handles iterator buffer
116 STATIC mp_obj_t mp_native_iternext(mp_obj_iter_buf_t *iter) {
117  mp_obj_t obj;
118  if (iter->base.type == MP_OBJ_NULL) {
119  obj = iter->buf[0];
120  } else {
121  obj = MP_OBJ_FROM_PTR(iter);
122  }
123  return mp_iternext(obj);
124 }
125 
126 // these must correspond to the respective enum in runtime0.h
127 void *const mp_fun_table[MP_F_NUMBER_OF] = {
130  mp_load_name,
133  mp_load_attr,
141  mp_unary_op,
142  mp_binary_op,
148 #if MICROPY_PY_BUILTINS_SET
151 #endif
156  mp_native_getiter,
157  mp_native_iternext,
158  nlr_push,
159  nlr_pop,
164 #if MICROPY_PY_BUILTINS_SLICE
166 #endif
168  mp_unpack_ex,
176 };
177 
178 /*
179 void mp_f_vector(mp_fun_kind_t fun_kind) {
180  (mp_f_table[fun_kind])();
181 }
182 */
183 
184 #endif // MICROPY_EMIT_NATIVE
mp_obj_t mp_obj_new_cell(mp_obj_t obj)
Definition: objcell.c:66
mp_obj_t buf[3]
Definition: obj.h:423
mp_obj_t mp_unary_op(mp_unary_op_t op, mp_obj_t arg)
Definition: runtime.c:216
uintptr_t mp_uint_t
Definition: mpconfigport.h:74
mp_int_t mp_small_int_modulo(mp_int_t dividend, mp_int_t divisor)
Definition: smallint.c:55
mp_obj_t mp_obj_new_slice(mp_obj_t start, mp_obj_t stop, mp_obj_t step)
mp_obj_t mp_obj_new_tuple(size_t n, const mp_obj_t *items)
Definition: objtuple.c:235
#define mp_const_none
Definition: obj.h:614
mp_obj_t mp_import_from(mp_obj_t module, qstr name)
Definition: runtime.c:1336
#define nlr_push(buf)
Definition: nlr.h:73
void mp_load_super_method(qstr attr, mp_obj_t *dest)
Definition: objtype.c:1133
void mp_unpack_sequence(mp_obj_t seq_in, size_t num, mp_obj_t *items)
Definition: runtime.c:827
void mp_delete_global(qstr qst)
Definition: runtime.c:210
bool mp_get_buffer(mp_obj_t obj, mp_buffer_info_t *bufinfo, mp_uint_t flags)
Definition: obj.c:512
#define MP_OBJ_FROM_PTR(p)
Definition: obj.h:233
mp_obj_t mp_load_attr(mp_obj_t base, qstr attr)
Definition: runtime.c:930
#define MP_NATIVE_TYPE_OBJ
Definition: runtime0.h:36
mp_obj_t mp_obj_new_list(size_t n, mp_obj_t *items)
Definition: objlist.c:470
mp_obj_t mp_load_global(qstr qst)
Definition: runtime.c:153
#define STATIC
Definition: mpconfig.h:1178
void mp_native_raise(mp_obj_t o)
mp_obj_t mp_obj_new_dict(size_t n_args)
Definition: objdict.c:584
mp_int_t mp_small_int_floor_divide(mp_int_t num, mp_int_t denom)
Definition: smallint.c:64
void mp_store_name(qstr qst, mp_obj_t obj)
Definition: runtime.c:194
void mp_load_method(mp_obj_t base, qstr attr, mp_obj_t *dest)
Definition: runtime.c:1076
mp_obj_t mp_obj_list_append(mp_obj_t self_in, mp_obj_t arg)
Definition: objlist.c:234
mp_obj_t mp_load_name(qstr qst)
Definition: runtime.c:140
void mp_obj_set_store(mp_obj_t self_in, mp_obj_t item)
mp_uint_t mp_convert_obj_to_native(mp_obj_t obj, mp_uint_t type)
#define NULL
Definition: stddef.h:4
#define MP_OBJ_NULL
Definition: obj.h:73
mp_obj_t mp_make_closure_from_raw_code(const mp_raw_code_t *rc, mp_uint_t n_closed_over, const mp_obj_t *args)
Definition: emitglue.c:157
#define MP_BUFFER_RW
Definition: obj.h:456
#define UINT_FMT
Definition: mpconfigport.h:71
mp_obj_t mp_make_function_from_raw_code(const mp_raw_code_t *rc, mp_obj_t def_args, mp_obj_t def_kw_args)
Definition: emitglue.c:116
mp_obj_t mp_binary_op(mp_binary_op_t op, mp_obj_t lhs, mp_obj_t rhs)
Definition: runtime.c:277
mp_obj_t mp_obj_new_set(size_t n_args, mp_obj_t *items)
#define MP_NATIVE_TYPE_UINT
Definition: runtime0.h:39
mp_obj_t mp_obj_new_int_from_uint(mp_uint_t value)
Definition: objint.c:343
mp_obj_t mp_load_build_class(void)
Definition: runtime.c:180
mp_obj_t mp_native_call_function_n_kw(mp_obj_t fun_in, size_t n_args_kw, const mp_obj_t *args)
args
Definition: i18n.py:175
mp_obj_t mp_call_method_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_obj_t *args)
Definition: runtime.c:816
#define MP_NATIVE_TYPE_BOOL
Definition: runtime0.h:37
mp_obj_t mp_obj_new_int(mp_int_t value)
Definition: objint.c:353
#define nlr_pop()
Definition: nlr.h:74
void mp_setup_code_state(mp_code_state_t *code_state, size_t n_args, size_t n_kw, const mp_obj_t *args)
Definition: bc.c:108
mp_obj_t mp_call_method_n_kw(size_t n_args, size_t n_kw, const mp_obj_t *args)
Definition: runtime.c:639
mp_obj_t mp_obj_dict_store(mp_obj_t self_in, mp_obj_t key, mp_obj_t value)
Definition: objdict.c:595
mp_obj_base_t base
Definition: obj.h:422
mp_obj_t mp_make_raise_obj(mp_obj_t o)
Definition: runtime.c:1304
void mp_unpack_ex(mp_obj_t seq_in, size_t num_in, mp_obj_t *items)
Definition: runtime.c:874
mp_obj_t mp_import_name(qstr name, mp_obj_t fromlist, mp_obj_t level)
Definition: runtime.c:1321
#define DEBUG_printf(...)
Definition: nativeglue.c:39
mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf)
Definition: runtime.c:1120
#define nlr_raise(val)
Definition: nlr.h:89
void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value)
Definition: runtime.c:1100
mp_obj_t mp_convert_native_to_obj(mp_uint_t val, mp_uint_t type)
uint64_t mp_obj_t
Definition: obj.h:39
void *const mp_fun_table[MP_F_NUMBER_OF]
mp_obj_t mp_iternext(mp_obj_t o_in)
Definition: runtime.c:1186
mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, size_t n_args, size_t n_kw, const mp_obj_t *args)
Definition: runtime.c:615
mp_obj_t mp_obj_subscr(mp_obj_t base, mp_obj_t index, mp_obj_t value)
Definition: obj.c:467
void mp_delete_name(qstr qst)
Definition: runtime.c:199
void mp_store_global(qstr qst, mp_obj_t obj)
Definition: runtime.c:205
mp_int_t mp_obj_get_int_truncated(mp_const_obj_t arg)
Definition: obj.c:247
void mp_import_all(mp_obj_t module)
Definition: runtime.c:1380
bool mp_obj_is_true(mp_obj_t arg)
Definition: obj.c:108
#define MP_NATIVE_TYPE_INT
Definition: runtime0.h:38
void * buf
Definition: obj.h:446