Просмотр исходного кода

add MICROPY_PY_GENERATOR_PEND_THROW ,pend throw attribute.

SummerGift 8 лет назад
Родитель
Сommit
fc04f11ff5
2 измененных файлов с 24 добавлено и 0 удалено
  1. 10 0
      py/mpconfig.h
  2. 14 0
      py/objgenerator.c

+ 10 - 0
py/mpconfig.h

@@ -1153,6 +1153,16 @@ typedef double mp_float_t;
 #define MICROPY_PORT_ROOT_POINTERS
 #endif
 
+// Non-standard .pend_throw() method for generators, allowing for
+// Future-like behavior with respect to exception handling: an
+// exception set with .pend_throw() will activate on the next call
+// to generator's .send() or .__next__(). (This is useful to implement
+// async schedulers.)
+#ifndef MICROPY_PY_GENERATOR_PEND_THROW
+#define MICROPY_PY_GENERATOR_PEND_THROW (1)
+#endif
+
+
 /*****************************************************************************/
 /* Miscellaneous settings                                                    */
 

+ 14 - 0
py/objgenerator.c

@@ -222,10 +222,24 @@ STATIC mp_obj_t gen_instance_close(mp_obj_t self_in) {
 
 STATIC MP_DEFINE_CONST_FUN_OBJ_1(gen_instance_close_obj, gen_instance_close);
 
+STATIC mp_obj_t gen_instance_pend_throw(mp_obj_t self_in, mp_obj_t exc_in) {
+    mp_obj_gen_instance_t *self = MP_OBJ_TO_PTR(self_in);
+    if (self->code_state.sp == self->code_state.state - 1) {
+        mp_raise_TypeError("can't pend throw to just-started generator");
+    }
+    mp_obj_t prev = *self->code_state.sp;
+    *self->code_state.sp = exc_in;
+    return prev;
+}
+STATIC MP_DEFINE_CONST_FUN_OBJ_2(gen_instance_pend_throw_obj, gen_instance_pend_throw);
+
 STATIC const mp_rom_map_elem_t gen_instance_locals_dict_table[] = {
     { MP_ROM_QSTR(MP_QSTR_close), MP_ROM_PTR(&gen_instance_close_obj) },
     { MP_ROM_QSTR(MP_QSTR_send), MP_ROM_PTR(&gen_instance_send_obj) },
     { MP_ROM_QSTR(MP_QSTR_throw), MP_ROM_PTR(&gen_instance_throw_obj) },
+    #if MICROPY_PY_GENERATOR_PEND_THROW
+    { MP_ROM_QSTR(MP_QSTR_pend_throw), MP_ROM_PTR(&gen_instance_pend_throw_obj) },
+    #endif
 };
 
 STATIC MP_DEFINE_CONST_DICT(gen_instance_locals_dict, gen_instance_locals_dict_table);