diff --git a/include/pocketpy/interpreter/vm.h b/include/pocketpy/interpreter/vm.h index 4d136774..61c30880 100644 --- a/include/pocketpy/interpreter/vm.h +++ b/include/pocketpy/interpreter/vm.h @@ -35,8 +35,8 @@ typedef struct VM { BinTree modules; TypeList types; - py_TValue builtins; // builtins module - py_TValue main; // __main__ module + py_GlobalRef builtins; // builtins module + py_GlobalRef main; // __main__ module py_Callbacks callbacks; @@ -152,7 +152,7 @@ py_Type pk_generator__register(); py_Type pk_namedict__register(); py_Type pk_code__register(); -py_TValue pk_builtins__register(); +py_GlobalRef pk_builtins__register(); /* mappingproxy */ void pk_mappingproxy__namedict(py_Ref out, py_Ref object); \ No newline at end of file diff --git a/include/pocketpy/pocketpy.h b/include/pocketpy/pocketpy.h index fcb3c5da..798985dd 100644 --- a/include/pocketpy/pocketpy.h +++ b/include/pocketpy/pocketpy.h @@ -118,6 +118,8 @@ PK_API void py_setvmctx(void* ctx); PK_API void py_sys_setargv(int argc, char** argv); /// Set the trace function for the current VM. PK_API void py_sys_settrace(py_TraceFunc func, bool reset); +/// Invoke the garbage collector. +PK_API int py_gc_collect(); /// Setup the callbacks for the current VM. PK_API py_Callbacks* py_callbacks(); diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index c2aec98c..cf355cd0 100644 --- a/src/interpreter/ceval.c +++ b/src/interpreter/ceval.c @@ -255,7 +255,7 @@ FrameResult VM__run_top_frame(VM* self) { } if(res == -1) goto __ERROR; // builtins - py_Ref tmp = py_getdict(&self->builtins, name); + py_Ref tmp = py_getdict(self->builtins, name); if(tmp != NULL) { PUSH(tmp); DISPATCH(); @@ -277,7 +277,7 @@ FrameResult VM__run_top_frame(VM* self) { } if(res == -1) goto __ERROR; - tmp = py_getdict(&self->builtins, name); + tmp = py_getdict(self->builtins, name); if(tmp != NULL) { PUSH(tmp); DISPATCH(); @@ -293,7 +293,7 @@ FrameResult VM__run_top_frame(VM* self) { DISPATCH(); } if(res == -1) goto __ERROR; - py_Ref tmp = py_getdict(&self->builtins, name); + py_Ref tmp = py_getdict(self->builtins, name); if(tmp != NULL) { PUSH(tmp); DISPATCH(); @@ -325,7 +325,7 @@ FrameResult VM__run_top_frame(VM* self) { DISPATCH(); } if(res == -1) goto __ERROR; - tmp = py_getdict(&self->builtins, name); + tmp = py_getdict(self->builtins, name); if(tmp) { PUSH(tmp); DISPATCH(); @@ -505,7 +505,7 @@ FrameResult VM__run_top_frame(VM* self) { /*****************************************/ case OP_BUILD_IMAG: { // [x] - py_Ref f = py_getdict(&self->builtins, py_name("complex")); + py_Ref f = py_getdict(self->builtins, py_name("complex")); assert(f != NULL); py_TValue tmp = *TOP(); *TOP() = *f; // [complex] @@ -558,7 +558,7 @@ FrameResult VM__run_top_frame(VM* self) { } case OP_BUILD_SET: { py_TValue* begin = SP() - byte.arg; - py_Ref typeobject_set = py_getdict(&self->builtins, py_name("set")); + py_Ref typeobject_set = py_getdict(self->builtins, py_name("set")); assert(typeobject_set != NULL); py_push(typeobject_set); py_pushnil(); @@ -1079,8 +1079,6 @@ FrameResult VM__run_top_frame(VM* self) { } case OP_STORE_CLASS_ATTR: { assert(self->curr_class); - py_Type type = py_totype(self->curr_class); - py_TypeInfo* ti = TypeList__get(&self->types, type); py_Name name = co_names[byte.arg]; // TOP() can be a function, classmethod or custom decorator py_Ref actual_func = TOP(); diff --git a/src/interpreter/frame.c b/src/interpreter/frame.c index 47853917..2d5ee253 100644 --- a/src/interpreter/frame.c +++ b/src/interpreter/frame.c @@ -194,7 +194,7 @@ const char* py_Frame_sourceloc(py_Frame* self, int* lineno) { void py_Frame_newglobals(py_Frame* frame, py_OutRef out) { if(!frame) { - pk_mappingproxy__namedict(out, &pk_current_vm->main); + pk_mappingproxy__namedict(out, pk_current_vm->main); return; } if(frame->globals->type == tp_module) { diff --git a/src/interpreter/vm.c b/src/interpreter/vm.c index dafac22b..952e873b 100644 --- a/src/interpreter/vm.c +++ b/src/interpreter/vm.c @@ -83,8 +83,8 @@ void VM__ctor(VM* self) { BinTree__ctor(&self->modules, c11_strdup(""), py_NIL(), &modules_config); TypeList__ctor(&self->types); - self->builtins = *py_NIL(); - self->main = *py_NIL(); + self->builtins = NULL; + self->main = NULL; self->callbacks.importfile = pk_default_importfile; self->callbacks.print = pk_default_print; @@ -175,8 +175,8 @@ void VM__ctor(VM* self) { // inject some builtin exceptions #define INJECT_BUILTIN_EXC(name, TBase) \ do { \ - py_Type type = pk_newtype(#name, TBase, &self->builtins, NULL, false, true); \ - py_setdict(&self->builtins, py_name(#name), py_tpobject(type)); \ + py_Type type = pk_newtype(#name, TBase, self->builtins, NULL, false, true); \ + py_setdict(self->builtins, py_name(#name), py_tpobject(type)); \ validate(tp_##name, type); \ } while(0) @@ -184,7 +184,7 @@ void VM__ctor(VM* self) { INJECT_BUILTIN_EXC(KeyboardInterrupt, tp_BaseException); validate(tp_StopIteration, pk_StopIteration__register()); - py_setdict(&self->builtins, py_name("StopIteration"), py_tpobject(tp_StopIteration)); + py_setdict(self->builtins, py_name("StopIteration"), py_tpobject(tp_StopIteration)); INJECT_BUILTIN_EXC(SyntaxError, tp_Exception); INJECT_BUILTIN_EXC(RecursionError, tp_Exception); @@ -230,10 +230,10 @@ void VM__ctor(VM* self) { for(int i = 0; i < c11__count_array(public_types); i++) { py_TypeInfo* ti = pk__type_info(public_types[i]); - py_setdict(&self->builtins, ti->name, &ti->self); + py_setdict(self->builtins, ti->name, &ti->self); } - py_newnotimplemented(py_emplacedict(&self->builtins, py_name("NotImplemented"))); + py_newnotimplemented(py_emplacedict(self->builtins, py_name("NotImplemented"))); pk__add_module_vmath(); pk__add_module_array2d(); @@ -266,7 +266,7 @@ void VM__ctor(VM* self) { // add python builtins do { bool ok; - ok = py_exec(kPythonLibs_builtins, "", EXEC_MODE, &self->builtins); + ok = py_exec(kPythonLibs_builtins, "", EXEC_MODE, self->builtins); if(!ok) goto __ABORT; break; __ABORT: @@ -274,7 +274,7 @@ void VM__ctor(VM* self) { c11__abort("failed to load python builtins!"); } while(0); - self->main = *py_newmodule("__main__"); + self->main = py_newmodule("__main__"); } void VM__dtor(VM* self) { @@ -766,7 +766,7 @@ void ManagedHeap__mark(ManagedHeap* self) { void pk_print_stack(VM* self, py_Frame* frame, Bytecode byte) { return; - if(frame == NULL || py_isnil(&self->main)) return; + if(frame == NULL || py_isnil(self->main)) return; py_TValue* sp = self->stack.sp; c11_sbuf buf; diff --git a/src/modules/gc.c b/src/modules/gc.c index 0116609b..5c5b358f 100644 --- a/src/modules/gc.c +++ b/src/modules/gc.c @@ -1,7 +1,7 @@ #include "pocketpy/pocketpy.h" #include "pocketpy/interpreter/vm.h" -static bool gc_collect(int argc, py_Ref argv){ +static bool gc_collect(int argc, py_Ref argv) { PY_CHECK_ARGC(0); ManagedHeap* heap = &pk_current_vm->heap; int res = ManagedHeap__collect(heap); @@ -9,7 +9,7 @@ static bool gc_collect(int argc, py_Ref argv){ return true; } -static bool gc_enable(int argc, py_Ref argv){ +static bool gc_enable(int argc, py_Ref argv) { PY_CHECK_ARGC(0); ManagedHeap* heap = &pk_current_vm->heap; heap->gc_enabled = true; @@ -17,7 +17,7 @@ static bool gc_enable(int argc, py_Ref argv){ return true; } -static bool gc_disable(int argc, py_Ref argv){ +static bool gc_disable(int argc, py_Ref argv) { PY_CHECK_ARGC(0); ManagedHeap* heap = &pk_current_vm->heap; heap->gc_enabled = false; @@ -25,7 +25,7 @@ static bool gc_disable(int argc, py_Ref argv){ return true; } -static bool gc_isenabled(int argc, py_Ref argv){ +static bool gc_isenabled(int argc, py_Ref argv) { PY_CHECK_ARGC(0); ManagedHeap* heap = &pk_current_vm->heap; py_newbool(py_retval(), heap->gc_enabled); @@ -39,4 +39,9 @@ void pk__add_module_gc() { py_bindfunc(mod, "enable", gc_enable); py_bindfunc(mod, "disable", gc_disable); py_bindfunc(mod, "isenabled", gc_isenabled); +} + +int py_gc_collect() { + ManagedHeap* heap = &pk_current_vm->heap; + return ManagedHeap__collect(heap); } \ No newline at end of file diff --git a/src/modules/os.c b/src/modules/os.c index 38cc3a78..45804407 100644 --- a/src/modules/os.c +++ b/src/modules/os.c @@ -229,7 +229,7 @@ void pk__add_module_io() { py_newint(py_emplacedict(mod, py_name("SEEK_CUR")), SEEK_CUR); py_newint(py_emplacedict(mod, py_name("SEEK_END")), SEEK_END); - py_setdict(&pk_current_vm->builtins, py_name("open"), py_tpobject(FileIO)); + py_setdict(pk_current_vm->builtins, py_name("open"), py_tpobject(FileIO)); } #else diff --git a/src/public/cast.c b/src/public/cast.c index ea5169ca..dd1b44bb 100644 --- a/src/public/cast.c +++ b/src/public/cast.c @@ -85,7 +85,7 @@ py_Type py_gettype(const char* module, py_Name name) { mod = py_getmodule(module); if(!mod) return 0; } else { - mod = &pk_current_vm->builtins; + mod = pk_current_vm->builtins; } py_Ref object = py_getdict(mod, name); if(object && py_istype(object, tp_type)) return py_totype(object); diff --git a/src/public/exec.c b/src/public/exec.c index 0bf1d4e6..d1cf96da 100644 --- a/src/public/exec.c +++ b/src/public/exec.c @@ -49,7 +49,7 @@ bool py_compile(const char* source, bool pk_exec(CodeObject* co, py_Ref module) { VM* vm = pk_current_vm; - if(!module) module = &vm->main; + if(!module) module = vm->main; assert(module->type == tp_module); py_StackRef sp = vm->stack.sp; @@ -63,7 +63,7 @@ bool pk_exec(CodeObject* co, py_Ref module) { bool pk_execdyn(CodeObject* co, py_Ref module, py_Ref globals, py_Ref locals) { VM* vm = pk_current_vm; - if(!module) module = &vm->main; + if(!module) module = vm->main; assert(module->type == tp_module); py_StackRef sp = vm->stack.sp; diff --git a/src/public/modules.c b/src/public/modules.c index e060dd7e..a1d0d98d 100644 --- a/src/public/modules.c +++ b/src/public/modules.c @@ -16,11 +16,11 @@ py_Ref py_getmodule(const char* path) { return BinTree__try_get(&vm->modules, (void*)path); } -py_Ref py_getbuiltin(py_Name name) { return py_getdict(&pk_current_vm->builtins, name); } +py_Ref py_getbuiltin(py_Name name) { return py_getdict(pk_current_vm->builtins, name); } -py_Ref py_getglobal(py_Name name) { return py_getdict(&pk_current_vm->main, name); } +py_Ref py_getglobal(py_Name name) { return py_getdict(pk_current_vm->main, name); } -void py_setglobal(py_Name name, py_Ref val) { py_setdict(&pk_current_vm->main, name, val); } +void py_setglobal(py_Name name, py_Ref val) { py_setdict(pk_current_vm->main, name, val); } py_Ref py_newmodule(const char* path) { ManagedHeap* heap = &pk_current_vm->heap; @@ -608,7 +608,7 @@ static bool builtins_eval(int argc, py_Ref argv) { static bool pk_smartexec(const char* source, py_Ref module, enum py_CompileMode mode, va_list args) { - if(module == NULL) module = &pk_current_vm->main; + if(module == NULL) module = pk_current_vm->main; pk_mappingproxy__namedict(py_pushtmp(), module); // globals py_newdict(py_pushtmp()); // locals bool ok = py_compile(source, "", mode, true); @@ -716,8 +716,8 @@ static bool NotImplementedType__repr__(int argc, py_Ref argv) { return true; } -py_TValue pk_builtins__register() { - py_Ref builtins = py_newmodule("builtins"); +py_GlobalRef pk_builtins__register() { + py_GlobalRef builtins = py_newmodule("builtins"); py_bindfunc(builtins, "exit", builtins_exit); py_bindfunc(builtins, "input", builtins_input); py_bindfunc(builtins, "repr", builtins_repr); @@ -760,7 +760,7 @@ py_TValue pk_builtins__register() { py_setdict(py_tpobject(tp_ellipsis), __hash__, py_None()); py_bindmagic(tp_NotImplementedType, __repr__, NotImplementedType__repr__); py_setdict(py_tpobject(tp_NotImplementedType), __hash__, py_None()); - return *builtins; + return builtins; } void function__gc_mark(void* ud, c11_vector* p_stack) {