1515
1616typedef struct _mp_obj_gen_wrap_t {
1717 mp_obj_base_t base ;
18- int n_state ;
18+ uint n_state ;
1919 mp_obj_t * fun ;
2020} mp_obj_gen_wrap_t ;
2121
@@ -31,22 +31,8 @@ mp_obj_t gen_wrap_call_n(mp_obj_t self_in, int n_args, const mp_obj_t *args) {
3131 if (n_args != bc_n_args ) {
3232 nlr_jump (mp_obj_new_exception_msg_2_args (rt_q_TypeError , "function takes %d positional arguments but %d were given" , (const char * )(machine_int_t )bc_n_args , (const char * )(machine_int_t )n_args ));
3333 }
34- mp_obj_t * state = m_new (mp_obj_t , 1 + self -> n_state );
35- // put function object at first slot in state (to keep u_gen_instance small)
36- state [0 ] = self_fun ;
37- // init args
38- for (int i = 0 ; i < n_args ; i ++ ) {
39- state [1 + i ] = args [n_args - 1 - i ];
40- }
4134
42- // TODO
43- // prelude for making cells (closed over variables)
44- // for now we just make sure there are no cells variables
45- // need to work out how to implement closed over variables in generators
46- assert (bc_code [0 ] == 0 );
47- bc_code += 1 ;
48-
49- return mp_obj_new_gen_instance (state , bc_code , state + self -> n_state );
35+ return mp_obj_new_gen_instance (bc_code , self -> n_state , n_args , args );
5036}
5137
5238const mp_obj_type_t gen_wrap_type = {
@@ -75,9 +61,9 @@ mp_obj_t mp_obj_new_gen_wrap(uint n_locals, uint n_stack, mp_obj_t fun) {
7561
7662typedef struct _mp_obj_gen_instance_t {
7763 mp_obj_base_t base ;
78- mp_obj_t * state ;
7964 const byte * ip ;
8065 mp_obj_t * sp ;
66+ mp_obj_t state [];
8167} mp_obj_gen_instance_t ;
8268
8369void gen_instance_print (void (* print )(void * env , const char * fmt , ...), void * env , mp_obj_t self_in ) {
@@ -90,9 +76,7 @@ mp_obj_t gen_instance_getiter(mp_obj_t self_in) {
9076
9177mp_obj_t gen_instance_iternext (mp_obj_t self_in ) {
9278 mp_obj_gen_instance_t * self = self_in ;
93- //mp_obj_base_t *fun = self->u_gen_instance.state[0];
94- //assert(fun->kind == O_FUN_BC);
95- bool yield = mp_execute_byte_code_2 (& self -> ip , & self -> state [1 ], & self -> sp );
79+ bool yield = mp_execute_byte_code_2 (& self -> ip , & self -> state [0 ], & self -> sp );
9680 if (yield ) {
9781 return * self -> sp ;
9882 } else {
@@ -117,11 +101,24 @@ const mp_obj_type_t gen_instance_type = {
117101 {{NULL , NULL },}, // method list
118102};
119103
120- mp_obj_t mp_obj_new_gen_instance (mp_obj_t state , const byte * ip , mp_obj_t * sp ) {
121- mp_obj_gen_instance_t * o = m_new_obj (mp_obj_gen_instance_t );
104+ // args are in reverse order in the array
105+ mp_obj_t mp_obj_new_gen_instance (const byte * bytecode , uint n_state , int n_args , const mp_obj_t * args ) {
106+ mp_obj_gen_instance_t * o = m_new_obj_var (mp_obj_gen_instance_t , mp_obj_t , n_state );
122107 o -> base .type = & gen_instance_type ;
123- o -> state = state ;
124- o -> ip = ip ;
125- o -> sp = sp ;
108+ o -> ip = bytecode ;
109+ o -> sp = o -> state + n_state ;
110+
111+ // copy args (which are in reverse order) to start of state array
112+ for (int i = 0 ; i < n_args ; i ++ ) {
113+ o -> state [i ] = args [n_args - 1 - i ];
114+ }
115+
116+ // TODO
117+ // prelude for making cells (closed over variables)
118+ // for now we just make sure there are no cells variables
119+ // need to work out how to implement closed over variables in generators
120+ assert (o -> ip [0 ] == 0 );
121+ o -> ip += 1 ;
122+
126123 return o ;
127124}
0 commit comments