From 749435e516f3592ca8535df48957eeb541d626b7 Mon Sep 17 00:00:00 2001 From: blueloveTH Date: Tue, 6 Aug 2024 13:47:41 +0800 Subject: [PATCH] ... --- include/pocketpy/interpreter/frame.h | 5 ++-- include/pocketpy/interpreter/generator.h | 8 +++++ include/pocketpy/pocketpy.h | 5 ++-- src/interpreter/ceval.c | 28 +++++++++--------- src/interpreter/frame.c | 5 ++-- src/interpreter/generator.c | 9 +++++- src/interpreter/vm.c | 37 ++++++++++++++++++------ src/public/modules.c | 10 +++---- 8 files changed, 71 insertions(+), 36 deletions(-) diff --git a/include/pocketpy/interpreter/frame.h b/include/pocketpy/interpreter/frame.h index 6720d2d8..ff39c622 100644 --- a/include/pocketpy/interpreter/frame.h +++ b/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); diff --git a/include/pocketpy/interpreter/generator.h b/include/pocketpy/interpreter/generator.h index 3f59c932..6a47d871 100644 --- a/include/pocketpy/interpreter/generator.h +++ b/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); \ No newline at end of file diff --git a/include/pocketpy/pocketpy.h b/include/pocketpy/pocketpy.h index 0872390d..479d0023 100644 --- a/include/pocketpy/pocketpy.h +++ b/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, diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index ad571ad1..0a32a600 100644 --- a/src/interpreter/ceval.c +++ b/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_MODE, &frame->module)) goto __ERROR; + if(!py_exec(string, "", EVAL_MODE, frame->module)) goto __ERROR; PUSH(py_retval()); DISPATCH(); } diff --git a/src/interpreter/frame.c b/src/interpreter/frame.c index 33284633..401b98f8 100644 --- a/src/interpreter/frame.c +++ b/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; diff --git a/src/interpreter/generator.c b/src/interpreter/generator.c index 9ae75b07..ce1aea10 100644 --- a/src/interpreter/generator.c +++ b/src/interpreter/generator.c @@ -1 +1,8 @@ -#include "pocketpy/interpreter/generator.h" \ No newline at end of file +#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; +} \ No newline at end of file diff --git a/src/interpreter/vm.c b/src/interpreter/vm.c index fc893cbc..c346324e 100644 --- a/src/interpreter/vm.c +++ b/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); diff --git a/src/public/modules.c b/src/public/modules.c index 7e917e18..8f6db6c8 100644 --- a/src/public/modules.c +++ b/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_MODE, &frame->module); + return py_exec(py_tostr(argv), "", 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_MODE, &frame->module); + return py_exec(py_tostr(argv), "", 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; }