summaryrefslogtreecommitdiff
path: root/py/runtime.c
diff options
context:
space:
mode:
Diffstat (limited to 'py/runtime.c')
-rw-r--r--py/runtime.c20
1 files changed, 17 insertions, 3 deletions
diff --git a/py/runtime.c b/py/runtime.c
index b53711bbe..2c849fe95 100644
--- a/py/runtime.c
+++ b/py/runtime.c
@@ -1217,6 +1217,7 @@ mp_obj_t mp_getiter(mp_obj_t o_in, mp_obj_iter_buf_t *iter_buf) {
mp_obj_t mp_iternext_allow_raise(mp_obj_t o_in) {
const mp_obj_type_t *type = mp_obj_get_type(o_in);
if (type->iternext != NULL) {
+ MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL;
return type->iternext(o_in);
} else {
// check for __next__ method
@@ -1242,6 +1243,7 @@ mp_obj_t mp_iternext(mp_obj_t o_in) {
MP_STACK_CHECK(); // enumerate, filter, map and zip can recursively call mp_iternext
const mp_obj_type_t *type = mp_obj_get_type(o_in);
if (type->iternext != NULL) {
+ MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL;
return type->iternext(o_in);
} else {
// check for __next__ method
@@ -1256,7 +1258,7 @@ mp_obj_t mp_iternext(mp_obj_t o_in) {
return ret;
} else {
if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(((mp_obj_base_t *)nlr.ret_val)->type), MP_OBJ_FROM_PTR(&mp_type_StopIteration))) {
- return MP_OBJ_STOP_ITERATION;
+ return mp_make_stop_iteration(mp_obj_exception_get_value(MP_OBJ_FROM_PTR(nlr.ret_val)));
} else {
nlr_jump(nlr.ret_val);
}
@@ -1281,14 +1283,18 @@ mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t th
}
if (type->iternext != NULL && send_value == mp_const_none) {
+ MP_STATE_THREAD(stop_iteration_arg) = MP_OBJ_NULL;
mp_obj_t ret = type->iternext(self_in);
*ret_val = ret;
if (ret != MP_OBJ_STOP_ITERATION) {
return MP_VM_RETURN_YIELD;
} else {
// The generator is finished.
- // This is an optimised "raise StopIteration(None)".
- *ret_val = mp_const_none;
+ // This is an optimised "raise StopIteration(*ret_val)".
+ *ret_val = MP_STATE_THREAD(stop_iteration_arg);
+ if (*ret_val == MP_OBJ_NULL) {
+ *ret_val = mp_const_none;
+ }
return MP_VM_RETURN_NORMAL;
}
}
@@ -1559,6 +1565,14 @@ NORETURN void mp_raise_NotImplementedError(mp_rom_error_text_t msg) {
#endif
+NORETURN void mp_raise_StopIteration(mp_obj_t arg) {
+ if (arg == MP_OBJ_NULL) {
+ mp_raise_type(&mp_type_StopIteration);
+ } else {
+ nlr_raise(mp_obj_new_exception_arg1(&mp_type_StopIteration, arg));
+ }
+}
+
NORETURN void mp_raise_OSError(int errno_) {
nlr_raise(mp_obj_new_exception_arg1(&mp_type_OSError, MP_OBJ_NEW_SMALL_INT(errno_)));
}