1
0
blueloveTH 1 жил өмнө
parent
commit
f941d26845

+ 4 - 0
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

+ 7 - 0
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);

+ 5 - 6
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);