py/runtime: Fix handling of throw() when resuming generator.

If GeneratorExit is injected as a throw-value then that should lead to
the close() method being called, if it exists.  If close() does not exist
then throw() should not be called, and this patch fixes this.
This commit is contained in:
Damien George 2017-01-17 00:10:49 +11:00
parent 40863fce6f
commit aeb2655073
1 changed files with 9 additions and 7 deletions

View File

@ -1245,13 +1245,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