|
17 | 17 | #include "builtintables.h" |
18 | 18 | #include "bc.h" |
19 | 19 | #include "intdivmod.h" |
| 20 | +#include "objgenerator.h" |
20 | 21 |
|
21 | 22 | #if 0 // print debugging info |
22 | 23 | #define DEBUG_PRINT (1) |
@@ -903,6 +904,62 @@ mp_obj_t mp_iternext(mp_obj_t o_in) { |
903 | 904 | } |
904 | 905 | } |
905 | 906 |
|
| 907 | +// TODO: Unclear what to do with StopIterarion exception here. |
| 908 | +mp_vm_return_kind_t mp_resume(mp_obj_t self_in, mp_obj_t send_value, mp_obj_t throw_value, mp_obj_t *ret_val) { |
| 909 | + mp_obj_type_t *type = mp_obj_get_type(self_in); |
| 910 | + |
| 911 | + if (type == &mp_type_gen_instance) { |
| 912 | + return mp_obj_gen_resume(self_in, send_value, throw_value, ret_val); |
| 913 | + } |
| 914 | + |
| 915 | + if (type->iternext != NULL && send_value == mp_const_none) { |
| 916 | + mp_obj_t ret = type->iternext(self_in); |
| 917 | + if (ret != MP_OBJ_NULL) { |
| 918 | + *ret_val = ret; |
| 919 | + return MP_VM_RETURN_YIELD; |
| 920 | + } else { |
| 921 | + // Emulate raise StopIteration() |
| 922 | + // Special case, handled in vm.c |
| 923 | + *ret_val = MP_OBJ_NULL; |
| 924 | + return MP_VM_RETURN_NORMAL; |
| 925 | + } |
| 926 | + } |
| 927 | + |
| 928 | + mp_obj_t dest[3]; // Reserve slot for send() arg |
| 929 | + |
| 930 | + if (send_value == mp_const_none) { |
| 931 | + mp_load_method_maybe(self_in, MP_QSTR___next__, dest); |
| 932 | + if (dest[0] != MP_OBJ_NULL) { |
| 933 | + *ret_val = mp_call_method_n_kw(0, 0, dest); |
| 934 | + return MP_VM_RETURN_YIELD; |
| 935 | + } |
| 936 | + } |
| 937 | + |
| 938 | + if (send_value != MP_OBJ_NULL) { |
| 939 | + mp_load_method(self_in, MP_QSTR_send, dest); |
| 940 | + dest[2] = send_value; |
| 941 | + *ret_val = mp_call_method_n_kw(1, 0, dest); |
| 942 | + return MP_VM_RETURN_YIELD; |
| 943 | + } |
| 944 | + |
| 945 | + if (throw_value != MP_OBJ_NULL) { |
| 946 | + if (mp_obj_is_subclass_fast(mp_obj_get_type(throw_value), &mp_type_GeneratorExit)) { |
| 947 | + mp_load_method_maybe(self_in, MP_QSTR_close, dest); |
| 948 | + if (dest[0] != MP_OBJ_NULL) { |
| 949 | + *ret_val = mp_call_method_n_kw(0, 0, dest); |
| 950 | + // We assume one can't "yield" from close() |
| 951 | + return MP_VM_RETURN_NORMAL; |
| 952 | + } |
| 953 | + } |
| 954 | + mp_load_method(self_in, MP_QSTR_throw, dest); |
| 955 | + *ret_val = mp_call_method_n_kw(1, 0, &throw_value); |
| 956 | + return MP_VM_RETURN_YIELD; |
| 957 | + } |
| 958 | + |
| 959 | + assert(0); |
| 960 | + return MP_VM_RETURN_NORMAL; // Should be unreachable |
| 961 | +} |
| 962 | + |
906 | 963 | mp_obj_t mp_make_raise_obj(mp_obj_t o) { |
907 | 964 | DEBUG_printf("raise %p\n", o); |
908 | 965 | if (mp_obj_is_exception_type(o)) { |
|
0 commit comments