diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index f45282f6..e9ad94ad 100644 --- a/src/interpreter/ceval.c +++ b/src/interpreter/ceval.c @@ -181,6 +181,10 @@ FrameResult VM__run_top_frame(VM* self) { Function* ud = py_newobject(SP(), tp_function, 0, sizeof(Function)); Function__ctor(ud, decl, frame->module, frame->globals); if(decl->nested) { + if(frame->is_locals_proxy) { + RuntimeError("cannot create closure from locals proxy"); + goto __ERROR; + } ud->closure = FastLocals__to_namedict(frame->locals, frame->co); py_Name name = py_name(decl->code.name->data); // capture itself to allow recursion diff --git a/src/interpreter/frame.c b/src/interpreter/frame.c index 73c4f675..dddc8236 100644 --- a/src/interpreter/frame.c +++ b/src/interpreter/frame.c @@ -78,6 +78,13 @@ void Frame__delete(Frame* self) { FixedMemoryPool__dealloc(&pk_current_vm->pool_frame, self); } +py_StackRef Frame__locals_sp(Frame *self){ + if(!self->is_locals_proxy){ + return self->locals; + } + return self->p0; +} + int Frame__prepare_jump_exception_handler(Frame* self, ValueStack* _s) { // try to find a parent try block int iblock = Frame__iblock(self); diff --git a/src/interpreter/generator.c b/src/interpreter/generator.c index 9c43bd2b..06d73da0 100644 --- a/src/interpreter/generator.c +++ b/src/interpreter/generator.c @@ -28,13 +28,12 @@ static bool generator__next__(int argc, py_Ref argv) { if(ud->state == 2) return StopIteration(); // reset frame->p0 - if(!ud->frame->is_locals_proxy){ - int locals_offset = ud->frame->locals - ud->frame->p0; - ud->frame->p0 = py_peek(0); - ud->frame->locals = ud->frame->p0 + locals_offset; - }else{ - ud->frame->p0 = py_peek(0); + if(ud->frame->is_locals_proxy){ + return RuntimeError("cannot resume generator with locals proxy"); } + int locals_offset = ud->frame->locals - ud->frame->p0; + ud->frame->p0 = py_peek(0); + ud->frame->locals = ud->frame->p0 + locals_offset; // restore the context py_Ref backup = py_getslot(argv, 0);