@@ -236,17 +236,10 @@ mp_obj_t mp_obj_new_gen_instance(const byte *bytecode, uint n_args, const mp_obj
236236 machine_uint_t n_exc_stack = bytecode [2 ] | (bytecode [3 ] << 8 );
237237 bytecode += 4 ;
238238
239- // bytecode prelude: initialise closed over variables
240- // TODO
241- // for now we just make sure there are no cells variables
242- // need to work out how to implement closed over variables in generators
243- assert (bytecode [0 ] == 0 );
244- bytecode += 1 ;
245-
239+ // allocate the generator object, with room for local stack and exception stack
246240 mp_obj_gen_instance_t * o = m_new_obj_var (mp_obj_gen_instance_t , byte , n_state * sizeof (mp_obj_t ) + n_exc_stack * sizeof (mp_exc_stack_t ));
247241 o -> base .type = & mp_type_gen_instance ;
248242 o -> code_info = code_info ;
249- o -> ip = bytecode ;
250243 o -> sp = & o -> state [0 ] - 1 ; // sp points to top of stack, which starts off 1 below the state
251244 o -> exc_sp = (mp_exc_stack_t * )(o -> state + n_state ) - 1 ;
252245 o -> n_state = n_state ;
@@ -259,5 +252,18 @@ mp_obj_t mp_obj_new_gen_instance(const byte *bytecode, uint n_args, const mp_obj
259252 o -> state [n_state - 1 - n_args - i ] = args2 [i ];
260253 }
261254
255+ // bytecode prelude: initialise closed over variables
256+ for (uint n_local = * bytecode ++ ; n_local > 0 ; n_local -- ) {
257+ uint local_num = * bytecode ++ ;
258+ if (local_num < n_args + n_args2 ) {
259+ o -> state [n_state - 1 - local_num ] = mp_obj_new_cell (o -> state [n_state - 1 - local_num ]);
260+ } else {
261+ o -> state [n_state - 1 - local_num ] = mp_obj_new_cell (MP_OBJ_NULL );
262+ }
263+ }
264+
265+ // set ip to start of actual byte code
266+ o -> ip = bytecode ;
267+
262268 return o ;
263269}
0 commit comments