STATIC mp_obj_t gen_resume_and_raise(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value) { mp_obj_t ret; switch (mp_obj_gen_resume(self_in, send_value, throw_value, &ret)) { case MP_VM_RETURN_NORMAL: // Optimize return w/o value in case generator is used in for loop if (ret == mp_const_none || ret == MP_OBJ_STOP_ITERATION) { return MP_OBJ_STOP_ITERATION; } else { nlr_raise(mp_obj_new_exception_args(&mp_type_StopIteration, 1, &ret)); } case MP_VM_RETURN_YIELD: if (throw_value != MP_OBJ_NULL && mp_obj_is_subclass_fast(mp_obj_get_type(throw_value), &mp_type_GeneratorExit)) { nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "generator ignored GeneratorExit")); } return ret; case MP_VM_RETURN_EXCEPTION: // TODO: Optimization of returning MP_OBJ_STOP_ITERATION is really part // of mp_iternext() protocol, but this function is called by other methods // too, which may not handled MP_OBJ_STOP_ITERATION. if (mp_obj_is_subclass_fast(mp_obj_get_type(ret), &mp_type_StopIteration)) { return MP_OBJ_STOP_ITERATION; } else { nlr_raise(ret); } default: assert(0); return mp_const_none; } }
STATIC mp_obj_t gen_resume_and_raise(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value) { mp_obj_t ret; switch (mp_obj_gen_resume(self_in, send_value, throw_value, &ret)) { case MP_VM_RETURN_NORMAL: default: // Optimize return w/o value in case generator is used in for loop if (ret == mp_const_none || ret == MP_OBJ_STOP_ITERATION) { return MP_OBJ_STOP_ITERATION; } else { nlr_raise(mp_obj_new_exception_args(&mp_type_StopIteration, 1, &ret)); } case MP_VM_RETURN_YIELD: return ret; case MP_VM_RETURN_EXCEPTION: // TODO: Optimization of returning MP_OBJ_STOP_ITERATION is really part // of mp_iternext() protocol, but this function is called by other methods // too, which may not handled MP_OBJ_STOP_ITERATION. if (mp_obj_is_subclass_fast(MP_OBJ_FROM_PTR(mp_obj_get_type(ret)), MP_OBJ_FROM_PTR(&mp_type_StopIteration))) { mp_obj_t val = mp_obj_exception_get_value(ret); if (val == mp_const_none) { return MP_OBJ_STOP_ITERATION; } } nlr_raise(ret); } }
STATIC mp_obj_t gen_instance_close(mp_obj_t self_in) { mp_obj_t ret; switch (mp_obj_gen_resume(self_in, mp_const_none, (mp_obj_t)&mp_const_GeneratorExit_obj, &ret)) { case MP_VM_RETURN_YIELD: nlr_raise(mp_obj_new_exception_msg(&mp_type_RuntimeError, "generator ignored GeneratorExit")); // Swallow StopIteration & GeneratorExit (== successful close), and re-raise any other case MP_VM_RETURN_EXCEPTION: // ret should always be an instance of an exception class if (mp_obj_is_subclass_fast(mp_obj_get_type(ret), &mp_type_GeneratorExit) || mp_obj_is_subclass_fast(mp_obj_get_type(ret), &mp_type_StopIteration)) { return mp_const_none; } nlr_raise(ret); default: // The only choice left is MP_VM_RETURN_NORMAL which is successful close return mp_const_none; } }