Browse Source

py/objgenerator: Remove globals from mp_obj_gen_instance_t.

This wasn't necessary as the wrapped function already has a reference to
its globals.  But it had a dual purpose of tracking whether the function
was currently running, so replace it with a bool.
pull/5279/head
Jim Mussared 5 years ago
committed by Damien George
parent
commit
576ed89224
  1. 18
      py/objgenerator.c

18
py/objgenerator.c

@ -43,7 +43,7 @@ const mp_obj_exception_t mp_const_GeneratorExit_obj = {{&mp_type_GeneratorExit},
typedef struct _mp_obj_gen_instance_t { typedef struct _mp_obj_gen_instance_t {
mp_obj_base_t base; mp_obj_base_t base;
mp_obj_dict_t *globals; bool is_running;
mp_code_state_t code_state; mp_code_state_t code_state;
} mp_obj_gen_instance_t; } mp_obj_gen_instance_t;
@ -60,7 +60,7 @@ STATIC mp_obj_t gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_kw, cons
n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t)); n_state * sizeof(mp_obj_t) + n_exc_stack * sizeof(mp_exc_stack_t));
o->base.type = &mp_type_gen_instance; o->base.type = &mp_type_gen_instance;
o->globals = self_fun->globals; o->is_running = false;
o->code_state.fun_bc = self_fun; o->code_state.fun_bc = self_fun;
o->code_state.ip = 0; o->code_state.ip = 0;
o->code_state.n_state = n_state; o->code_state.n_state = n_state;
@ -105,7 +105,7 @@ STATIC mp_obj_t native_gen_wrap_call(mp_obj_t self_in, size_t n_args, size_t n_k
o->base.type = &mp_type_gen_instance; o->base.type = &mp_type_gen_instance;
// Parse the input arguments and set up the code state // Parse the input arguments and set up the code state
o->globals = self_fun->globals; o->is_running = false;
o->code_state.fun_bc = self_fun; o->code_state.fun_bc = self_fun;
o->code_state.ip = (const byte*)prelude_offset; o->code_state.ip = (const byte*)prelude_offset;
o->code_state.n_state = n_state; o->code_state.n_state = n_state;
@ -168,16 +168,15 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_
} }
} }
// We set self->globals=NULL while executing, for a sentinel to ensure the generator // Ensure the generator cannot be reentered during execution
// cannot be reentered during execution if (self->is_running) {
if (self->globals == NULL) {
mp_raise_ValueError("generator already executing"); mp_raise_ValueError("generator already executing");
} }
self->is_running = true;
// Set up the correct globals context for the generator and execute it // Set up the correct globals context for the generator and execute it
self->code_state.old_globals = mp_globals_get(); self->code_state.old_globals = mp_globals_get();
mp_globals_set(self->globals); mp_globals_set(self->code_state.fun_bc->globals);
self->globals = NULL;
mp_vm_return_kind_t ret_kind; mp_vm_return_kind_t ret_kind;
@ -194,9 +193,10 @@ mp_vm_return_kind_t mp_obj_gen_resume(mp_obj_t self_in, mp_obj_t send_value, mp_
ret_kind = mp_execute_bytecode(&self->code_state, throw_value); ret_kind = mp_execute_bytecode(&self->code_state, throw_value);
} }
self->globals = mp_globals_get();
mp_globals_set(self->code_state.old_globals); mp_globals_set(self->code_state.old_globals);
self->is_running = false;
switch (ret_kind) { switch (ret_kind) {
case MP_VM_RETURN_NORMAL: case MP_VM_RETURN_NORMAL:
default: default:

Loading…
Cancel
Save