// convert a Micro Python object to a sensible value for inline asm machine_uint_t convert_obj_for_inline_asm(mp_obj_t obj) { // TODO for byte_array, pass pointer to the array if (MP_OBJ_IS_SMALL_INT(obj)) { return MP_OBJ_SMALL_INT_VALUE(obj); } else if (obj == mp_const_none) { return 0; } else if (obj == mp_const_false) { return 0; } else if (obj == mp_const_true) { return 1; } else if (MP_OBJ_IS_TYPE(obj, &str_type)) { // pointer to the string (it's probably constant though!) return (machine_uint_t)qstr_str(mp_obj_str_get(obj)); #if MICROPY_ENABLE_FLOAT } else if (MP_OBJ_IS_TYPE(obj, &float_type)) { // convert float to int (could also pass in float registers) return (machine_int_t)mp_obj_float_get(obj); #endif } else if (MP_OBJ_IS_TYPE(obj, &tuple_type)) { // pointer to start of tuple (could pass length, but then could use len(x) for that) uint len; mp_obj_t *items; mp_obj_tuple_get(obj, &len, &items); return (machine_uint_t)items; } else if (MP_OBJ_IS_TYPE(obj, &list_type)) { // pointer to start of list (could pass length, but then could use len(x) for that) uint len; mp_obj_t *items; mp_obj_list_get(obj, &len, &items); return (machine_uint_t)items; } else { // just pass along a pointer to the object return (machine_uint_t)obj; } }
mp_obj_t mp_obj_new_closure(mp_obj_t fun, mp_obj_t closure_tuple) { mp_obj_closure_t *o = m_new_obj(mp_obj_closure_t); o->base.type = &closure_type; o->fun = fun; mp_obj_tuple_get(closure_tuple, &o->n_closed, &o->closed); return o; }
void mp_obj_get_array(mp_obj_t o, uint *len, mp_obj_t **items) { if (MP_OBJ_IS_TYPE(o, &mp_type_tuple)) { mp_obj_tuple_get(o, len, items); } else if (MP_OBJ_IS_TYPE(o, &mp_type_list)) { mp_obj_list_get(o, len, items); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "object '%s' is not a tuple or list", mp_obj_get_type_str(o))); } }
// note: returned value in *items may point to the interior of a GC block void mp_obj_get_array(mp_obj_t o, size_t *len, mp_obj_t **items) { if (MP_OBJ_IS_TYPE(o, &mp_type_tuple)) { mp_obj_tuple_get(o, len, items); } else if (MP_OBJ_IS_TYPE(o, &mp_type_list)) { mp_obj_list_get(o, len, items); } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { mp_raise_TypeError("expected tuple/list"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "object '%s' isn't a tuple or list", mp_obj_get_type_str(o))); } } }
mp_obj_t str_join(mp_obj_t self_in, mp_obj_t arg) { assert(MP_OBJ_IS_STR(self_in)); // get separation string GET_STR_DATA_LEN(self_in, sep_str, sep_len); // process args uint seq_len; mp_obj_t *seq_items; if (MP_OBJ_IS_TYPE(arg, &tuple_type)) { mp_obj_tuple_get(arg, &seq_len, &seq_items); } else if (MP_OBJ_IS_TYPE(arg, &list_type)) { mp_obj_list_get(arg, &seq_len, &seq_items); } else { goto bad_arg; } // count required length int required_len = 0; for (int i = 0; i < seq_len; i++) { if (!MP_OBJ_IS_STR(seq_items[i])) { goto bad_arg; } if (i > 0) { required_len += sep_len; } GET_STR_LEN(seq_items[i], l); required_len += l; } // make joined string byte *data; mp_obj_t joined_str = mp_obj_str_builder_start(required_len, &data); for (int i = 0; i < seq_len; i++) { if (i > 0) { memcpy(data, sep_str, sep_len); data += sep_len; } GET_STR_DATA_LEN(seq_items[i], s, l); memcpy(data, s, l); data += l; } // return joined string return mp_obj_str_builder_end(joined_str); bad_arg: nlr_jump(mp_obj_new_exception_msg(MP_QSTR_TypeError, "?str.join expecting a list of str's")); }
void mp_obj_get_array_fixed_n(mp_obj_t o, uint len, mp_obj_t **items) { if (MP_OBJ_IS_TYPE(o, &mp_type_tuple) || MP_OBJ_IS_TYPE(o, &mp_type_list)) { uint seq_len; if (MP_OBJ_IS_TYPE(o, &mp_type_tuple)) { mp_obj_tuple_get(o, &seq_len, items); } else { mp_obj_list_get(o, &seq_len, items); } if (seq_len != len) { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_IndexError, "requested length %d but object has length %d", len, seq_len)); } } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "object '%s' is not a tuple or list", mp_obj_get_type_str(o))); } }
// convert a Micro Python object to a sensible value for inline asm STATIC machine_uint_t convert_obj_for_inline_asm(mp_obj_t obj) { // TODO for byte_array, pass pointer to the array if (MP_OBJ_IS_SMALL_INT(obj)) { return MP_OBJ_SMALL_INT_VALUE(obj); } else if (obj == mp_const_none) { return 0; } else if (obj == mp_const_false) { return 0; } else if (obj == mp_const_true) { return 1; } else if (MP_OBJ_IS_STR(obj)) { // pointer to the string (it's probably constant though!) uint l; return (machine_uint_t)mp_obj_str_get_data(obj, &l); } else { mp_obj_type_t *type = mp_obj_get_type(obj); if (0) { #if MICROPY_PY_BUILTINS_FLOAT } else if (type == &mp_type_float) { // convert float to int (could also pass in float registers) return (machine_int_t)mp_obj_float_get(obj); #endif } else if (type == &mp_type_tuple) { // pointer to start of tuple (could pass length, but then could use len(x) for that) uint len; mp_obj_t *items; mp_obj_tuple_get(obj, &len, &items); return (machine_uint_t)items; } else if (type == &mp_type_list) { // pointer to start of list (could pass length, but then could use len(x) for that) uint len; mp_obj_t *items; mp_obj_list_get(obj, &len, &items); return (machine_uint_t)items; } else { mp_buffer_info_t bufinfo; if (mp_get_buffer(obj, &bufinfo, MP_BUFFER_WRITE)) { // supports the buffer protocol, return a pointer to the data return (machine_uint_t)bufinfo.buf; } else { // just pass along a pointer to the object return (machine_uint_t)obj; } } } }
STATIC mp_obj_t zip_iternext(mp_obj_t self_in) { assert(MP_OBJ_IS_TYPE(self_in, &mp_type_zip)); mp_obj_zip_t *self = self_in; mp_obj_t *items; if (self->n_iters == 0) { return MP_OBJ_STOP_ITERATION; } mp_obj_t o = mp_obj_new_tuple(self->n_iters, NULL); mp_obj_tuple_get(o, NULL, &items); for (int i = 0; i < self->n_iters; i++) { mp_obj_t next = mp_iternext(self->iters[i]); if (next == MP_OBJ_STOP_ITERATION) { mp_obj_tuple_del(o); return MP_OBJ_STOP_ITERATION; } items[i] = next; } return o; }