diff options
Diffstat (limited to 'py/runtime.c')
-rw-r--r-- | py/runtime.c | 184 |
1 files changed, 99 insertions, 85 deletions
diff --git a/py/runtime.c b/py/runtime.c index 8b4420926c..bf2bfb8eae 100644 --- a/py/runtime.c +++ b/py/runtime.c @@ -63,6 +63,10 @@ void mp_init(void) { // no pending exceptions to start with MP_STATE_VM(mp_pending_exception) = MP_OBJ_NULL; + #if MICROPY_ENABLE_SCHEDULER + MP_STATE_VM(sched_state) = MP_SCHED_IDLE; + MP_STATE_VM(sched_sp) = 0; + #endif #if MICROPY_ENABLE_EMERGENCY_EXCEPTION_BUF mp_init_emergency_exception_buf(); @@ -74,7 +78,7 @@ void mp_init(void) { MP_STATE_VM(mp_kbd_exception).traceback_alloc = 0; MP_STATE_VM(mp_kbd_exception).traceback_len = 0; MP_STATE_VM(mp_kbd_exception).traceback_data = NULL; - MP_STATE_VM(mp_kbd_exception).args = mp_const_empty_tuple; + MP_STATE_VM(mp_kbd_exception).args = (mp_obj_tuple_t*)&mp_const_empty_tuple_obj; #endif // call port specific initialization if any @@ -85,15 +89,16 @@ void mp_init(void) { // optimization disabled by default MP_STATE_VM(mp_optimise_value) = 0; - // init global module stuff - mp_module_init(); + // init global module dict + mp_obj_dict_init(&MP_STATE_VM(mp_loaded_modules_dict), 3); // initialise the __main__ module mp_obj_dict_init(&MP_STATE_VM(dict_main), 1); mp_obj_dict_store(MP_OBJ_FROM_PTR(&MP_STATE_VM(dict_main)), MP_OBJ_NEW_QSTR(MP_QSTR___name__), MP_OBJ_NEW_QSTR(MP_QSTR___main__)); // locals = globals for outer module (see Objects/frameobject.c/PyFrame_New()) - MP_STATE_CTX(dict_locals) = MP_STATE_CTX(dict_globals) = &MP_STATE_VM(dict_main); + mp_locals_set(&MP_STATE_VM(dict_main)); + mp_globals_set(&MP_STATE_VM(dict_main)); #if MICROPY_CAN_OVERRIDE_BUILTINS // start with no extensions to builtins @@ -105,6 +110,12 @@ void mp_init(void) { memset(MP_STATE_VM(fs_user_mount), 0, sizeof(MP_STATE_VM(fs_user_mount))); #endif + #if MICROPY_VFS + // initialise the VFS sub-system + MP_STATE_VM(vfs_cur) = NULL; + MP_STATE_VM(vfs_mount_table) = NULL; + #endif + #if MICROPY_PY_THREAD_GIL mp_thread_mutex_init(&MP_STATE_VM(gil_mutex)); #endif @@ -114,7 +125,7 @@ void mp_init(void) { void mp_deinit(void) { //mp_obj_dict_free(&dict_main); - mp_module_deinit(); + //mp_map_deinit(&MP_STATE_VM(mp_loaded_modules_map)); // call port specific deinitialization if any #ifdef MICROPY_PORT_INIT_FUNC @@ -126,8 +137,8 @@ mp_obj_t mp_load_name(qstr qst) { // logic: search locals, globals, builtins DEBUG_OP_printf("load name %s\n", qstr_str(qst)); // If we're at the outer scope (locals == globals), dispatch to load_global right away - if (MP_STATE_CTX(dict_locals) != MP_STATE_CTX(dict_globals)) { - mp_map_elem_t *elem = mp_map_lookup(&MP_STATE_CTX(dict_locals)->map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP); + if (mp_locals_get() != mp_globals_get()) { + mp_map_elem_t *elem = mp_map_lookup(&mp_locals_get()->map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP); if (elem != NULL) { return elem->value; } @@ -138,7 +149,7 @@ mp_obj_t mp_load_name(qstr qst) { mp_obj_t mp_load_global(qstr qst) { // logic: search globals, builtins DEBUG_OP_printf("load global %s\n", qstr_str(qst)); - mp_map_elem_t *elem = mp_map_lookup(&MP_STATE_CTX(dict_globals)->map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP); + mp_map_elem_t *elem = mp_map_lookup(&mp_globals_get()->map, MP_OBJ_NEW_QSTR(qst), MP_MAP_LOOKUP); if (elem == NULL) { #if MICROPY_CAN_OVERRIDE_BUILTINS if (MP_STATE_VM(mp_module_builtins_override_dict) != NULL) { @@ -178,24 +189,24 @@ mp_obj_t mp_load_build_class(void) { void mp_store_name(qstr qst, mp_obj_t obj) { DEBUG_OP_printf("store name %s <- %p\n", qstr_str(qst), obj); - mp_obj_dict_store(MP_OBJ_FROM_PTR(MP_STATE_CTX(dict_locals)), MP_OBJ_NEW_QSTR(qst), obj); + mp_obj_dict_store(MP_OBJ_FROM_PTR(mp_locals_get()), MP_OBJ_NEW_QSTR(qst), obj); } void mp_delete_name(qstr qst) { DEBUG_OP_printf("delete name %s\n", qstr_str(qst)); // TODO convert KeyError to NameError if qst not found - mp_obj_dict_delete(MP_OBJ_FROM_PTR(MP_STATE_CTX(dict_locals)), MP_OBJ_NEW_QSTR(qst)); + mp_obj_dict_delete(MP_OBJ_FROM_PTR(mp_locals_get()), MP_OBJ_NEW_QSTR(qst)); } void mp_store_global(qstr qst, mp_obj_t obj) { DEBUG_OP_printf("store global %s <- %p\n", qstr_str(qst), obj); - mp_obj_dict_store(MP_OBJ_FROM_PTR(MP_STATE_CTX(dict_globals)), MP_OBJ_NEW_QSTR(qst), obj); + mp_obj_dict_store(MP_OBJ_FROM_PTR(mp_globals_get()), MP_OBJ_NEW_QSTR(qst), obj); } void mp_delete_global(qstr qst) { DEBUG_OP_printf("delete global %s\n", qstr_str(qst)); // TODO convert KeyError to NameError if qst not found - mp_obj_dict_delete(MP_OBJ_FROM_PTR(MP_STATE_CTX(dict_globals)), MP_OBJ_NEW_QSTR(qst)); + mp_obj_dict_delete(MP_OBJ_FROM_PTR(mp_globals_get()), MP_OBJ_NEW_QSTR(qst)); } mp_obj_t mp_unary_op(mp_uint_t op, mp_obj_t arg) { @@ -220,11 +231,9 @@ mp_obj_t mp_unary_op(mp_uint_t op, mp_obj_t arg) { } else { return MP_OBJ_NEW_SMALL_INT(-val); } - case MP_UNARY_OP_INVERT: - return MP_OBJ_NEW_SMALL_INT(~val); default: - assert(0); - return arg; + assert(op == MP_UNARY_OP_INVERT); + return MP_OBJ_NEW_SMALL_INT(~val); } } else if (op == MP_UNARY_OP_HASH && MP_OBJ_IS_STR_OR_BYTES(arg)) { // fast path for hashing str/bytes @@ -243,7 +252,7 @@ mp_obj_t mp_unary_op(mp_uint_t op, mp_obj_t arg) { } } if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "unsupported type for operator"); + mp_raise_TypeError("unsupported type for operator"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "unsupported type for %q: '%s'", @@ -297,7 +306,7 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) { } } else if (MP_OBJ_IS_TYPE(rhs, &mp_type_tuple)) { mp_obj_tuple_t *tuple = MP_OBJ_TO_PTR(rhs); - for (mp_uint_t i = 0; i < tuple->len; i++) { + for (size_t i = 0; i < tuple->len; i++) { rhs = tuple->items[i]; if (!mp_obj_is_exception_type(rhs)) { goto unsupported_op; @@ -335,7 +344,7 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) { case MP_BINARY_OP_INPLACE_LSHIFT: { if (rhs_val < 0) { // negative shift not allowed - mp_raise_msg(&mp_type_ValueError, "negative shift count"); + mp_raise_ValueError("negative shift count"); } else if (rhs_val >= (mp_int_t)BITS_PER_WORD || lhs_val > (MP_SMALL_INT_MAX >> rhs_val) || lhs_val < (MP_SMALL_INT_MIN >> rhs_val)) { // left-shift will overflow, so use higher precision integer lhs = mp_obj_new_int_from_ll(lhs_val); @@ -350,7 +359,7 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) { case MP_BINARY_OP_INPLACE_RSHIFT: if (rhs_val < 0) { // negative shift not allowed - mp_raise_msg(&mp_type_ValueError, "negative shift count"); + mp_raise_ValueError("negative shift count"); } else { // standard precision is enough for right-shift if (rhs_val >= (mp_int_t)BITS_PER_WORD) { @@ -426,7 +435,7 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) { lhs = mp_obj_new_float(lhs_val); goto generic_binary_op; #else - mp_raise_msg(&mp_type_ValueError, "negative power with no float support"); + mp_raise_ValueError("negative power with no float support"); #endif } else { mp_int_t ans = 1; @@ -516,7 +525,8 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) { } if (type->getiter != NULL) { /* second attempt, walk the iterator */ - mp_obj_t iter = mp_getiter(rhs); + mp_obj_iter_buf_t iter_buf; + mp_obj_t iter = mp_getiter(rhs, &iter_buf); mp_obj_t next; while ((next = mp_iternext(iter)) != MP_OBJ_STOP_ITERATION) { if (mp_obj_equal(next, lhs)) { @@ -527,7 +537,7 @@ mp_obj_t mp_binary_op(mp_uint_t op, mp_obj_t lhs, mp_obj_t rhs) { } if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "object not iterable"); + mp_raise_TypeError("object not iterable"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not iterable", mp_obj_get_type_str(rhs))); @@ -549,7 +559,7 @@ generic_binary_op: unsupported_op: if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "unsupported type for operator"); + mp_raise_TypeError("unsupported type for operator"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "unsupported types for %q: '%s', '%s'", @@ -576,7 +586,7 @@ mp_obj_t mp_call_function_2(mp_obj_t fun, mp_obj_t arg1, mp_obj_t arg2) { } // args contains, eg: arg0 arg1 key0 value0 key1 value1 -mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { +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) { // TODO improve this: fun object can specify its type and we parse here the arguments, // passing to the function arrays of fixed and keyword arguments @@ -591,7 +601,7 @@ mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, mp_uint_t n_args, mp_uint_t n_kw } if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "object not callable"); + mp_raise_TypeError("object not callable"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not callable", mp_obj_get_type_str(fun_in))); @@ -600,7 +610,7 @@ mp_obj_t mp_call_function_n_kw(mp_obj_t fun_in, mp_uint_t n_args, mp_uint_t n_kw // args contains: fun self/NULL arg(0) ... arg(n_args-2) arg(n_args-1) kw_key(0) kw_val(0) ... kw_key(n_kw-1) kw_val(n_kw-1) // if n_args==0 and n_kw==0 then there are only fun and self/NULL -mp_obj_t mp_call_method_n_kw(mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *args) { +mp_obj_t mp_call_method_n_kw(size_t n_args, size_t n_kw, const mp_obj_t *args) { DEBUG_OP_printf("call method (fun=%p, self=%p, n_args=" UINT_FMT ", n_kw=" UINT_FMT ", args=%p)\n", args[0], args[1], n_args, n_kw, args); int adjust = (args[1] == MP_OBJ_NULL) ? 0 : 1; return mp_call_function_n_kw(args[0], n_args + adjust, n_kw, args + 2 - adjust); @@ -610,7 +620,7 @@ mp_obj_t mp_call_method_n_kw(mp_uint_t n_args, mp_uint_t n_kw, const mp_obj_t *a #if !MICROPY_STACKLESS STATIC #endif -void mp_call_prepare_args_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const mp_obj_t *args, mp_call_args_t *out_args) { +void mp_call_prepare_args_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_obj_t *args, mp_call_args_t *out_args) { mp_obj_t fun = *args++; mp_obj_t self = MP_OBJ_NULL; if (have_self) { @@ -660,7 +670,7 @@ void mp_call_prepare_args_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const // optimise the case of a tuple and list // get the items - mp_uint_t len; + size_t len; mp_obj_t *items; mp_obj_get_array(pos_seq, &len, &items); @@ -694,7 +704,8 @@ void mp_call_prepare_args_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const args2_len += n_args; // extract the variable position args from the iterator - mp_obj_t iterable = mp_getiter(pos_seq); + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable = mp_getiter(pos_seq, &iter_buf); mp_obj_t item; while ((item = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { if (args2_len >= args2_alloc) { @@ -720,7 +731,7 @@ void mp_call_prepare_args_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const // dictionary mp_map_t *map = mp_obj_dict_get_map(kw_dict); assert(args2_len + 2 * map->used <= args2_alloc); // should have enough, since kw_dict_len is in this case hinted correctly above - for (mp_uint_t i = 0; i < map->alloc; i++) { + for (size_t i = 0; i < map->alloc; i++) { if (MP_MAP_SLOT_IS_FILLED(map, i)) { // the key must be a qstr, so intern it if it's a string mp_obj_t key = map->table[i].key; @@ -739,7 +750,7 @@ void mp_call_prepare_args_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const // get the keys iterable mp_obj_t dest[3]; mp_load_method(kw_dict, MP_QSTR_keys, dest); - mp_obj_t iterable = mp_getiter(mp_call_method_n_kw(0, 0, dest)); + mp_obj_t iterable = mp_getiter(mp_call_method_n_kw(0, 0, dest), NULL); mp_obj_t key; while ((key = mp_iternext(iterable)) != MP_OBJ_STOP_ITERATION) { @@ -776,7 +787,7 @@ void mp_call_prepare_args_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const out_args->n_alloc = args2_alloc; } -mp_obj_t mp_call_method_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const mp_obj_t *args) { +mp_obj_t mp_call_method_n_kw_var(bool have_self, size_t n_args_n_kw, const mp_obj_t *args) { mp_call_args_t out_args; mp_call_prepare_args_n_kw_var(have_self, n_args_n_kw, args, &out_args); @@ -787,25 +798,22 @@ mp_obj_t mp_call_method_n_kw_var(bool have_self, mp_uint_t n_args_n_kw, const mp } // unpacked items are stored in reverse order into the array pointed to by items -void mp_unpack_sequence(mp_obj_t seq_in, mp_uint_t num, mp_obj_t *items) { - mp_uint_t seq_len; +void mp_unpack_sequence(mp_obj_t seq_in, size_t num, mp_obj_t *items) { + size_t seq_len; if (MP_OBJ_IS_TYPE(seq_in, &mp_type_tuple) || MP_OBJ_IS_TYPE(seq_in, &mp_type_list)) { mp_obj_t *seq_items; - if (MP_OBJ_IS_TYPE(seq_in, &mp_type_tuple)) { - mp_obj_tuple_get(seq_in, &seq_len, &seq_items); - } else { - mp_obj_list_get(seq_in, &seq_len, &seq_items); - } + mp_obj_get_array(seq_in, &seq_len, &seq_items); if (seq_len < num) { goto too_short; } else if (seq_len > num) { goto too_long; } - for (mp_uint_t i = 0; i < num; i++) { + for (size_t i = 0; i < num; i++) { items[i] = seq_items[num - 1 - i]; } } else { - mp_obj_t iterable = mp_getiter(seq_in); + mp_obj_iter_buf_t iter_buf; + mp_obj_t iterable = mp_getiter(seq_in, &iter_buf); for (seq_len = 0; seq_len < num; seq_len++) { mp_obj_t el = mp_iternext(iterable); @@ -822,14 +830,14 @@ void mp_unpack_sequence(mp_obj_t seq_in, mp_uint_t num, mp_obj_t *items) { too_short: if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_ValueError, "wrong number of values to unpack"); + mp_raise_ValueError("wrong number of values to unpack"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "need more than %d values to unpack", (int)seq_len)); } too_long: if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_ValueError, "wrong number of values to unpack"); + mp_raise_ValueError("wrong number of values to unpack"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "too many values to unpack (expected %d)", (int)num)); @@ -837,31 +845,22 @@ too_long: } // unpacked items are stored in reverse order into the array pointed to by items -void mp_unpack_ex(mp_obj_t seq_in, mp_uint_t num_in, mp_obj_t *items) { - mp_uint_t num_left = num_in & 0xff; - mp_uint_t num_right = (num_in >> 8) & 0xff; +void mp_unpack_ex(mp_obj_t seq_in, size_t num_in, mp_obj_t *items) { + size_t num_left = num_in & 0xff; + size_t num_right = (num_in >> 8) & 0xff; DEBUG_OP_printf("unpack ex " UINT_FMT " " UINT_FMT "\n", num_left, num_right); - mp_uint_t seq_len; + size_t seq_len; if (MP_OBJ_IS_TYPE(seq_in, &mp_type_tuple) || MP_OBJ_IS_TYPE(seq_in, &mp_type_list)) { mp_obj_t *seq_items; - if (MP_OBJ_IS_TYPE(seq_in, &mp_type_tuple)) { - mp_obj_tuple_get(seq_in, &seq_len, &seq_items); - } else { - if (num_left == 0 && num_right == 0) { - // *a, = b # sets a to b if b is a list - items[0] = seq_in; - return; - } - mp_obj_list_get(seq_in, &seq_len, &seq_items); - } + mp_obj_get_array(seq_in, &seq_len, &seq_items); if (seq_len < num_left + num_right) { goto too_short; } - for (mp_uint_t i = 0; i < num_right; i++) { + for (size_t i = 0; i < num_right; i++) { items[i] = seq_items[seq_len - 1 - i]; } items[num_right] = mp_obj_new_list(seq_len - num_left - num_right, seq_items + num_left); - for (mp_uint_t i = 0; i < num_left; i++) { + for (size_t i = 0; i < num_left; i++) { items[num_right + 1 + i] = seq_items[num_left - 1 - i]; } } else { @@ -869,7 +868,7 @@ void mp_unpack_ex(mp_obj_t seq_in, mp_uint_t num_in, mp_obj_t *items) { // items destination array, then the rest to a dynamically created list. Once the // iterable is exhausted, we take from this list for the right part of the items. // TODO Improve to waste less memory in the dynamically created list. - mp_obj_t iterable = mp_getiter(seq_in); + mp_obj_t iterable = mp_getiter(seq_in, NULL); mp_obj_t item; for (seq_len = 0; seq_len < num_left; seq_len++) { item = mp_iternext(iterable); @@ -886,7 +885,7 @@ void mp_unpack_ex(mp_obj_t seq_in, mp_uint_t num_in, mp_obj_t *items) { goto too_short; } items[num_right] = MP_OBJ_FROM_PTR(rest); - for (mp_uint_t i = 0; i < num_right; i++) { + for (size_t i = 0; i < num_right; i++) { items[num_right - 1 - i] = rest->items[rest->len - num_right + i]; } mp_obj_list_set_len(MP_OBJ_FROM_PTR(rest), rest->len - num_right); @@ -895,7 +894,7 @@ void mp_unpack_ex(mp_obj_t seq_in, mp_uint_t num_in, mp_obj_t *items) { too_short: if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_ValueError, "wrong number of values to unpack"); + mp_raise_ValueError("wrong number of values to unpack"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_ValueError, "need more than %d values to unpack", (int)seq_len)); @@ -934,7 +933,7 @@ STATIC mp_obj_t checked_fun_call(mp_obj_t self_in, size_t n_args, size_t n_kw, c const mp_obj_type_t *arg0_type = mp_obj_get_type(args[0]); if (arg0_type != self->type) { if (MICROPY_ERROR_REPORTING != MICROPY_ERROR_REPORTING_DETAILED) { - mp_raise_msg(&mp_type_TypeError, "argument has wrong type"); + mp_raise_TypeError("argument has wrong type"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "argument should be a '%q' not a '%q'", self->type->name, arg0_type->name)); @@ -1092,13 +1091,24 @@ void mp_store_attr(mp_obj_t base, qstr attr, mp_obj_t value) { } } -mp_obj_t mp_getiter(mp_obj_t o_in) { +mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) { assert(o_in); + mp_obj_type_t *type = mp_obj_get_type(o_in); + + // Check for native getiter which is the identity. We handle this case explicitly + // so we don't unnecessarily allocate any RAM for the iter_buf, which won't be used. + if (type->getiter == mp_identity_getiter) { + return o_in; + } + + // if caller did not provide a buffer then allocate one on the heap + if (iter_buf == NULL) { + iter_buf = m_new_obj(mp_obj_iter_buf_t); + } // check for native getiter (corresponds to __iter__) - mp_obj_type_t *type = mp_obj_get_type(o_in); if (type->getiter != NULL) { - mp_obj_t iter = type->getiter(o_in); + mp_obj_t iter = type->getiter(o_in, iter_buf); if (iter != MP_OBJ_NULL) { return iter; } @@ -1109,12 +1119,12 @@ mp_obj_t mp_getiter(mp_obj_t o_in) { mp_load_method_maybe(o_in, MP_QSTR___getitem__, dest); if (dest[0] != MP_OBJ_NULL) { // __getitem__ exists, create and return an iterator - return mp_obj_new_getitem_iter(dest); + return mp_obj_new_getitem_iter(dest, iter_buf); } // object not iterable if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "object not iterable"); + mp_raise_TypeError("object not iterable"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not iterable", mp_obj_get_type_str(o_in))); @@ -1136,7 +1146,7 @@ mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) { return mp_call_method_n_kw(0, 0, dest); } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "object not an iterator"); + mp_raise_TypeError("object not an iterator"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not an iterator", mp_obj_get_type_str(o_in))); @@ -1172,7 +1182,7 @@ mp_obj_t mp_iternext(mp_obj_t o_in) { } } else { if (MICROPY_ERROR_REPORTING == MICROPY_ERROR_REPORTING_TERSE) { - mp_raise_msg(&mp_type_TypeError, "object not an iterator"); + mp_raise_TypeError("object not an iterator"); } else { nlr_raise(mp_obj_new_exception_msg_varg(&mp_type_TypeError, "'%s' object is not an iterator", mp_obj_get_type_str(o_in))); @@ -1234,7 +1244,8 @@ mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t th return MP_VM_RETURN_YIELD; } - if (throw_value != MP_OBJ_NULL) { + assert(throw_value != MP_OBJ_NULL); + { if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(mp_obj_get_type(throw_value)), MP_OBJ_FROM_PTR(&mp_type_GeneratorExit))) { mp_load_method_maybe(self_in, MP_QSTR_close, dest); if (dest[0] != MP_OBJ_NULL) { @@ -1244,13 +1255,15 @@ mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t th // We assume one can't "yield" from close() return MP_VM_RETURN_NORMAL; } - } - mp_load_method_maybe(self_in, MP_QSTR_throw, dest); - if (dest[0] != MP_OBJ_NULL) { - *ret_val = mp_call_method_n_kw(1, 0, &throw_value); - // If .throw() method returned, we assume it's value to yield - // - any exception would be thrown with nlr_raise(). - return MP_VM_RETURN_YIELD; + } else { + mp_load_method_maybe(self_in, MP_QSTR_throw, dest); + if (dest[0] != MP_OBJ_NULL) { + dest[2] = throw_value; + *ret_val = mp_call_method_n_kw(1, 0, dest); + // If .throw() method returned, we assume it's value to yield + // - any exception would be thrown with nlr_raise(). + return MP_VM_RETURN_YIELD; + } } // If there's nowhere to throw exception into, then we assume that object // is just incapable to handle it, so any exception thrown into it @@ -1260,9 +1273,6 @@ mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t th *ret_val = throw_value; return MP_VM_RETURN_EXCEPTION; } - - assert(0); - return MP_VM_RETURN_NORMAL; // Should be unreachable } mp_obj_t mp_make_raise_obj(mp_obj_t o) { @@ -1320,7 +1330,7 @@ import_error: } mp_load_method_maybe(module, MP_QSTR___name__, dest); - mp_uint_t pkg_name_len; + size_t pkg_name_len; const char *pkg_name = mp_obj_str_get_data(dest[0], &pkg_name_len); const uint dot_name_len = pkg_name_len + 1 + qstr_len(name); @@ -1346,7 +1356,7 @@ void mp_import_all(mp_obj_t module) { // TODO: Support __all__ mp_map_t *map = mp_obj_dict_get_map(MP_OBJ_FROM_PTR(mp_obj_module_get_globals(module))); - for (mp_uint_t i = 0; i < map->alloc; i++) { + for (size_t i = 0; i < map->alloc; i++) { if (MP_MAP_SLOT_IS_FILLED(map, i)) { qstr name = MP_OBJ_QSTR_VALUE(map->table[i].key); if (*qstr_str(name) != '_') { @@ -1413,7 +1423,11 @@ void *m_malloc_fail(size_t num_bytes) { } NORETURN void mp_raise_msg(const mp_obj_type_t *exc_type, const char *msg) { - nlr_raise(mp_obj_new_exception_msg(exc_type, msg)); + if (msg == NULL) { + nlr_raise(mp_obj_new_exception(exc_type)); + } else { + nlr_raise(mp_obj_new_exception_msg(exc_type, msg)); + } } NORETURN void mp_raise_ValueError(const char *msg) { |