blueloveTH 1 год назад
Родитель
Сommit
749435e516

+ 3 - 2
include/pocketpy/interpreter/frame.h

@@ -6,6 +6,7 @@
 #include "pocketpy/objects/object.h"
 #include "pocketpy/common/config.h"
 #include "pocketpy/common/strname.h"
+#include "pocketpy/pocketpy.h"
 
 py_TValue* FastLocals__try_get_by_name(py_TValue* locals, const CodeObject* co, py_Name name);
 NameDict* FastLocals__to_namedict(py_TValue* locals, const CodeObject* co);
@@ -34,7 +35,7 @@ typedef struct Frame {
     struct Frame* f_back;
     const Bytecode* ip;
     const CodeObject* co;
-    py_TValue module;      // weak ref
+    py_GlobalRef module;
     py_StackRef function;  // a function object or NULL (global scope)
     py_StackRef p0;        // unwinding base
     py_StackRef locals;    // locals base
@@ -42,7 +43,7 @@ typedef struct Frame {
 } Frame;
 
 Frame* Frame__new(const CodeObject* co,
-                  py_TValue* module,
+                  py_GlobalRef module,
                   py_StackRef function,
                   py_StackRef p0,
                   py_StackRef locals);

+ 8 - 0
include/pocketpy/interpreter/generator.h

@@ -1,2 +1,10 @@
 #pragma once
 
+#include "pocketpy/interpreter/frame.h"
+
+typedef struct Generator{
+    Frame* frame;
+    int state;
+} Generator;
+
+void pk_newgenerator(py_Ref out, Frame* frame, int slots);

+ 3 - 2
include/pocketpy/pocketpy.h

@@ -518,9 +518,10 @@ enum py_PredefinedTypes {
     tp_NoneType,
     tp_NotImplementedType,
     tp_ellipsis,
-    tp_SyntaxError,
-    tp_StopIteration,
+    tp_generator,
     /* builtin exceptions */
+    tp_StopIteration,
+    tp_SyntaxError,
     tp_StackOverflowError,
     tp_IOError,
     tp_OSError,

+ 14 - 14
src/interpreter/ceval.c

@@ -134,7 +134,7 @@ FrameResult VM__run_top_frame(VM* self) {
             case OP_LOAD_FUNCTION: {
                 FuncDecl_ decl = c11__getitem(FuncDecl_, &frame->co->func_decls, byte.arg);
                 Function* ud = py_newobject(SP(), tp_function, 0, sizeof(Function));
-                Function__ctor(ud, decl, &frame->module);
+                Function__ctor(ud, decl, frame->module);
                 if(decl->nested) {
                     ud->closure = FastLocals__to_namedict(frame->locals, frame->co);
                     py_Name name = py_name(decl->code.name->data);
@@ -173,7 +173,7 @@ FrameResult VM__run_top_frame(VM* self) {
                     PUSH(tmp);
                     DISPATCH();
                 }
-                tmp = py_getdict(&frame->module, name);
+                tmp = py_getdict(frame->module, name);
                 if(tmp != NULL) {
                     PUSH(tmp);
                     DISPATCH();
@@ -193,7 +193,7 @@ FrameResult VM__run_top_frame(VM* self) {
                     PUSH(tmp);
                     DISPATCH();
                 }
-                tmp = py_getdict(&frame->module, name);
+                tmp = py_getdict(frame->module, name);
                 if(tmp != NULL) {
                     PUSH(tmp);
                     DISPATCH();
@@ -208,7 +208,7 @@ FrameResult VM__run_top_frame(VM* self) {
             }
             case OP_LOAD_GLOBAL: {
                 py_Name name = byte.arg;
-                py_Ref tmp = py_getdict(&frame->module, name);
+                py_Ref tmp = py_getdict(frame->module, name);
                 if(tmp != NULL) {
                     PUSH(tmp);
                     DISPATCH();
@@ -237,7 +237,7 @@ FrameResult VM__run_top_frame(VM* self) {
                     DISPATCH();
                 }
                 // load global if attribute not found
-                tmp = py_getdict(&frame->module, name);
+                tmp = py_getdict(frame->module, name);
                 if(tmp) {
                     PUSH(tmp);
                     DISPATCH();
@@ -300,13 +300,13 @@ FrameResult VM__run_top_frame(VM* self) {
                         // }
                     }
                 } else {
-                    py_setdict(&frame->module, name, TOP());
+                    py_setdict(frame->module, name, TOP());
                 }
                 POP();
                 DISPATCH();
             }
             case OP_STORE_GLOBAL: {
-                py_setdict(&frame->module, byte.arg, TOP());
+                py_setdict(frame->module, byte.arg, TOP());
                 POP();
                 DISPATCH();
             }
@@ -361,7 +361,7 @@ FrameResult VM__run_top_frame(VM* self) {
                         // }
                     }
                 } else {
-                    bool ok = py_deldict(&frame->module, name);
+                    bool ok = py_deldict(frame->module, name);
                     if(!ok) {
                         NameError(name);
                         goto __ERROR;
@@ -371,7 +371,7 @@ FrameResult VM__run_top_frame(VM* self) {
             }
             case OP_DELETE_GLOBAL: {
                 py_Name name = byte.arg;
-                bool ok = py_deldict(&frame->module, name);
+                bool ok = py_deldict(frame->module, name);
                 if(!ok) {
                     NameError(name);
                     goto __ERROR;
@@ -802,7 +802,7 @@ FrameResult VM__run_top_frame(VM* self) {
                             ImportError("cannot import name '%n'", name);
                             goto __ERROR;
                         } else {
-                            py_setdict(&frame->module, name, value);
+                            py_setdict(frame->module, name, value);
                         }
                     }
                 } else {
@@ -811,7 +811,7 @@ FrameResult VM__run_top_frame(VM* self) {
                         if(!kv->key) continue;
                         c11_sv name = py_name2sv(kv->key);
                         if(name.size == 0 || name.data[0] == '_') continue;
-                        py_setdict(&frame->module, kv->key, &kv->value);
+                        py_setdict(frame->module, kv->key, &kv->value);
                     }
                 }
                 POP();
@@ -857,7 +857,7 @@ FrameResult VM__run_top_frame(VM* self) {
                 }
                 POP();
                 py_Type type =
-                    pk_newtype(py_name2str(name), base, &frame->module, NULL, true, false);
+                    pk_newtype(py_name2str(name), base, frame->module, NULL, true, false);
                 PUSH(py_tpobject(type));
                 self->__curr_class = TOP();
                 DISPATCH();
@@ -866,7 +866,7 @@ FrameResult VM__run_top_frame(VM* self) {
                 // [cls or decorated]
                 py_Name name = byte.arg;
                 // set into f_globals
-                py_setdict(&frame->module, name, TOP());
+                py_setdict(frame->module, name, TOP());
 
                 if(py_istype(TOP(), tp_type)) {
                     // call on_end_subclass
@@ -950,7 +950,7 @@ FrameResult VM__run_top_frame(VM* self) {
                 py_TValue* tmp = c11__at(py_TValue, &frame->co->consts, byte.arg);
                 const char* string = py_tostr(tmp);
                 // TODO: optimize this
-                if(!py_exec(string, "<eval>", EVAL_MODE, &frame->module)) goto __ERROR;
+                if(!py_exec(string, "<eval>", EVAL_MODE, frame->module)) goto __ERROR;
                 PUSH(py_retval());
                 DISPATCH();
             }

+ 3 - 2
src/interpreter/frame.c

@@ -1,6 +1,7 @@
 #include "pocketpy/interpreter/frame.h"
 #include "pocketpy/objects/codeobject.h"
 #include "pocketpy/objects/object.h"
+#include "pocketpy/pocketpy.h"
 
 void ValueStack__ctor(ValueStack* self) {
     self->sp = self->begin;
@@ -35,7 +36,7 @@ UnwindTarget* UnwindTarget__new(UnwindTarget* next, int iblock, int offset) {
 void UnwindTarget__delete(UnwindTarget* self) { free(self); }
 
 Frame* Frame__new(const CodeObject* co,
-                  py_TValue* module,
+                  py_GlobalRef module,
                   py_StackRef function,
                   py_StackRef p0,
                   py_StackRef locals) {
@@ -44,7 +45,7 @@ Frame* Frame__new(const CodeObject* co,
     self->f_back = NULL;
     self->ip = (Bytecode*)co->codes.data - 1;
     self->co = co;
-    self->module = *module;
+    self->module = module;
     self->function = function;
     self->p0 = p0;
     self->locals = locals;

+ 8 - 1
src/interpreter/generator.c

@@ -1 +1,8 @@
-#include "pocketpy/interpreter/generator.h"
+#include "pocketpy/interpreter/generator.h"
+#include "pocketpy/interpreter/frame.h"
+
+void pk_newgenerator(py_Ref out, Frame* frame, int slots) {
+    Generator* ud = py_newobject(out, tp_generator, slots, sizeof(Generator));
+    ud->frame = frame;
+    ud->state = 0;
+}

+ 28 - 9
src/interpreter/vm.c

@@ -2,6 +2,7 @@
 #include "pocketpy/common/memorypool.h"
 #include "pocketpy/common/sstream.h"
 #include "pocketpy/common/utils.h"
+#include "pocketpy/interpreter/generator.h"
 #include "pocketpy/objects/base.h"
 #include "pocketpy/common/_generated.h"
 #include "pocketpy/pocketpy.h"
@@ -126,9 +127,7 @@ void VM__ctor(VM* self) {
     validate(tp_NotImplementedType,
              pk_newtype("NotImplementedType", tp_object, NULL, NULL, false, true));
     validate(tp_ellipsis, pk_newtype("ellipsis", tp_object, NULL, NULL, false, true));
-
-    validate(tp_SyntaxError, pk_newtype("SyntaxError", tp_Exception, NULL, NULL, false, true));
-    validate(tp_StopIteration, pk_newtype("StopIteration", tp_Exception, NULL, NULL, false, true));
+    validate(tp_generator, pk_newtype("generator", tp_object, NULL, NULL, false, true));
 
     self->builtins = pk_builtins__register();
 
@@ -140,6 +139,8 @@ void VM__ctor(VM* self) {
         validate(tp_##name, type);                                                                 \
     } while(0)
 
+    INJECT_BUILTIN_EXC(StopIteration);
+    INJECT_BUILTIN_EXC(SyntaxError);
     INJECT_BUILTIN_EXC(StackOverflowError);
     INJECT_BUILTIN_EXC(IOError);
     INJECT_BUILTIN_EXC(OSError);
@@ -160,11 +161,26 @@ void VM__ctor(VM* self) {
 #undef validate
 
     /* Setup Public Builtin Types */
-    py_Type public_types[] = {tp_object,        tp_type,         tp_int,           tp_float,
-                              tp_bool,          tp_str,          tp_list,          tp_tuple,
-                              tp_slice,         tp_range,        tp_bytes,         tp_dict,
-                              tp_property,      tp_staticmethod, tp_classmethod,   tp_super,
-                              tp_BaseException, tp_Exception,    tp_StopIteration, tp_SyntaxError};
+    py_Type public_types[] = {
+        tp_object,
+        tp_type,
+        tp_int,
+        tp_float,
+        tp_bool,
+        tp_str,
+        tp_list,
+        tp_tuple,
+        tp_slice,
+        tp_range,
+        tp_bytes,
+        tp_dict,
+        tp_property,
+        tp_staticmethod,
+        tp_classmethod,
+        tp_super,
+        tp_BaseException,
+        tp_Exception,
+    };
 
     for(int i = 0; i < c11__count_array(public_types); i++) {
         py_TypeInfo* ti = c11__at(py_TypeInfo, &self->types, public_types[i]);
@@ -438,6 +454,9 @@ FrameResult VM__vectorcall(VM* self, uint16_t argc, uint16_t kwargc, bool opcall
             case FuncType_GENERATOR: {
                 bool ok = prepare_py_call(self->__vectorcall_buffer, argv, p1, kwargc, fn->decl);
                 if(!ok) return RES_ERROR;
+                Frame* frame = Frame__new(co, &fn->module, p0, p0, argv);
+                pk_newgenerator(py_retval(), frame, 0);
+                self->stack.sp = p0;
                 return RES_RETURN;
             }
                 // prepare_py_call(__vectorcall_buffer, args, kwargs, fn.decl);
@@ -560,7 +579,7 @@ void ManagedHeap__mark(ManagedHeap* self) {
     }
     // mark frame
     for(Frame* frame = vm->top_frame; frame; frame = frame->f_back) {
-        mark_value(&frame->module);
+        mark_value(frame->module);
     }
     // mark vm's registers
     mark_value(&vm->last_retval);

+ 4 - 6
src/public/modules.c

@@ -68,7 +68,7 @@ int py_import(const char* path_cstr) {
         c11_sv top_filename = c11_string__sv(vm->top_frame->co->src->filename);
         int is_init = c11_sv__endswith(top_filename, (c11_sv){"__init__.py", 11});
 
-        py_Ref package = py_getdict(&vm->top_frame->module, __path__);
+        py_Ref package = py_getdict(vm->top_frame->module, __path__);
         c11_sv package_sv = py_tosv(package);
         if(package_sv.size == 0) {
             return ImportError("attempted relative import with no known parent package");
@@ -323,14 +323,14 @@ static bool builtins_exec(int argc, py_Ref argv) {
     PY_CHECK_ARGC(1);
     PY_CHECK_ARG_TYPE(0, tp_str);
     Frame* frame = pk_current_vm->top_frame;
-    return py_exec(py_tostr(argv), "<exec>", EXEC_MODE, &frame->module);
+    return py_exec(py_tostr(argv), "<exec>", EXEC_MODE, frame->module);
 }
 
 static bool builtins_eval(int argc, py_Ref argv) {
     PY_CHECK_ARGC(1);
     PY_CHECK_ARG_TYPE(0, tp_str);
     Frame* frame = pk_current_vm->top_frame;
-    return py_exec(py_tostr(argv), "<eval>", EVAL_MODE, &frame->module);
+    return py_exec(py_tostr(argv), "<eval>", EVAL_MODE, frame->module);
 }
 
 static bool builtins_isinstance(int argc, py_Ref argv) {
@@ -418,9 +418,7 @@ static bool builtins_chr(int argc, py_Ref argv) {
     PY_CHECK_ARGC(1);
     PY_CHECK_ARG_TYPE(0, tp_int);
     py_i64 val = py_toint(py_arg(0));
-    if(val < 0 || val > 128) {
-        return ValueError("chr() arg not in range(128)");
-    }
+    if(val < 0 || val > 128) { return ValueError("chr() arg not in range(128)"); }
     py_newstrn(py_retval(), (const char*)&val, 1);
     return true;
 }