mirror of
https://github.com/licsber/micropython.git
synced 2024-09-20 00:50:24 +08:00
py/runtime: mp_resume: Handle exceptions in Python __next__().
This includes StopIteration and thus are important to make Python-coded iterables work with yield from/await. Exceptions in Python send() are still not handled and left for future consideration and optimization.
This commit is contained in:
parent
a392b3aa75
commit
79d996a57b
18
py/runtime.c
18
py/runtime.c
@ -1191,17 +1191,31 @@ mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t th
|
|||||||
|
|
||||||
mp_obj_t dest[3]; // Reserve slot for send() arg
|
mp_obj_t dest[3]; // Reserve slot for send() arg
|
||||||
|
|
||||||
|
// Python instance iterator protocol
|
||||||
if (send_value == mp_const_none) {
|
if (send_value == mp_const_none) {
|
||||||
mp_load_method_maybe(self_in, MP_QSTR___next__, dest);
|
mp_load_method_maybe(self_in, MP_QSTR___next__, dest);
|
||||||
if (dest[0] != MP_OBJ_NULL) {
|
if (dest[0] != MP_OBJ_NULL) {
|
||||||
*ret_val = mp_call_method_n_kw(0, 0, dest);
|
nlr_buf_t nlr;
|
||||||
return MP_VM_RETURN_YIELD;
|
if (nlr_push(&nlr) == 0) {
|
||||||
|
*ret_val = mp_call_method_n_kw(0, 0, dest);
|
||||||
|
nlr_pop();
|
||||||
|
return MP_VM_RETURN_YIELD;
|
||||||
|
} else {
|
||||||
|
*ret_val = nlr.ret_val;
|
||||||
|
return MP_VM_RETURN_EXCEPTION;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Either python instance generator protocol, or native object
|
||||||
|
// generator protocol.
|
||||||
if (send_value != MP_OBJ_NULL) {
|
if (send_value != MP_OBJ_NULL) {
|
||||||
mp_load_method(self_in, MP_QSTR_send, dest);
|
mp_load_method(self_in, MP_QSTR_send, dest);
|
||||||
dest[2] = send_value;
|
dest[2] = send_value;
|
||||||
|
// TODO: This should have exception wrapping like __next__ case
|
||||||
|
// above. Not done right away to think how to optimize native
|
||||||
|
// generators better, see:
|
||||||
|
// https://github.com/micropython/micropython/issues/2628
|
||||||
*ret_val = mp_call_method_n_kw(1, 0, dest);
|
*ret_val = mp_call_method_n_kw(1, 0, dest);
|
||||||
return MP_VM_RETURN_YIELD;
|
return MP_VM_RETURN_YIELD;
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user