diff --git a/include/pocketpy/interpreter/types.h b/include/pocketpy/interpreter/types.h new file mode 100644 index 00000000..eecd9497 --- /dev/null +++ b/include/pocketpy/interpreter/types.h @@ -0,0 +1,25 @@ +#pragma once + +#include "pocketpy/common/vector.h" +#include "pocketpy/objects/base.h" + +#define PK_DICT_MAX_COLLISION 4 + +typedef struct { + uint64_t hash; + py_TValue key; + py_TValue val; +} DictEntry; + +typedef struct { + int _[PK_DICT_MAX_COLLISION]; +} DictIndex; + +typedef struct { + int length; + uint32_t capacity; + DictIndex* indices; + c11_vector /*T=DictEntry*/ entries; +} Dict; + +typedef c11_vector List; diff --git a/include/pocketpy/interpreter/vm.h b/include/pocketpy/interpreter/vm.h index 92f47cec..47b69dfe 100644 --- a/include/pocketpy/interpreter/vm.h +++ b/include/pocketpy/interpreter/vm.h @@ -8,6 +8,7 @@ #include "pocketpy/interpreter/modules.h" #include "pocketpy/interpreter/typeinfo.h" #include "pocketpy/interpreter/name.h" +#include "pocketpy/interpreter/types.h" // TODO: // 1. __eq__ and __ne__ fallbacks @@ -58,7 +59,6 @@ bool pk__parse_int_slice(py_Ref slice, int length, int* restrict start, int* res bool pk__normalize_index(int* index, int length); #define pk__mark_value(val) if((val)->is_ptr && !(val)->_obj->gc_marked) PyObject__mark((val)->_obj) -void pk__mark_namedict(NameDict*); void pk__tp_set_marker(py_Type type, void (*gc_mark)(void*)); bool pk__object_new(int argc, py_Ref argv); py_TypeInfo* pk__type_info(py_Type type); diff --git a/src/interpreter/generator.c b/src/interpreter/generator.c index bccfe13a..82eb4d48 100644 --- a/src/interpreter/generator.c +++ b/src/interpreter/generator.c @@ -76,16 +76,8 @@ static bool generator__next__(int argc, py_Ref argv) { } } -static void generator__gc_mark(void* ud){ - Generator* gen = ud; - if(gen->frame) Frame__gc_mark(gen->frame); -} - py_Type pk_generator__register() { py_Type type = pk_newtype("generator", tp_object, NULL, (py_Dtor)Generator__dtor, false, true); - - pk__tp_set_marker(type, generator__gc_mark); - py_bindmagic(type, __iter__, pk_wrapper__self); py_bindmagic(type, __next__, generator__next__); return type; diff --git a/src/interpreter/vm.c b/src/interpreter/vm.c index 9e7e38df..99f934d9 100644 --- a/src/interpreter/vm.c +++ b/src/interpreter/vm.c @@ -604,13 +604,6 @@ void PyObject__dtor(PyObject* self) { if(self->slots == -1) NameDict__dtor(PyObject__dict(self)); } -void pk__mark_namedict(NameDict* dict) { - for(int i = 0; i < dict->length; i++) { - NameDict_KV* kv = c11__at(NameDict_KV, dict, i); - pk__mark_value(&kv->value); - } -} - void pk__tp_set_marker(py_Type type, void (*gc_mark)(void*)) { py_TypeInfo* ti = pk__type_info(type); assert(ti->gc_mark == NULL); @@ -627,12 +620,42 @@ void PyObject__mark(PyObject* obj) { for(int i = 0; i < obj->slots; i++) pk__mark_value(p + i); } else if(obj->slots == -1) { - NameDict* dict = PyObject__dict(obj); - pk__mark_namedict(dict); + NameDict* namedict = PyObject__dict(obj); + for(int i = 0; i < namedict->length; i++) { + NameDict_KV* kv = c11__at(NameDict_KV, namedict, i); + pk__mark_value(&kv->value); + } } - py_TypeInfo* ti = pk__type_info(obj->type); - if(ti->gc_mark) ti->gc_mark(PyObject__userdata(obj)); + void* ud = PyObject__userdata(obj); + switch(obj->type) { + case tp_list: { + List* self = ud; + for(int i = 0; i < self->length; i++) { + pk__mark_value(c11__at(py_TValue, self, i)); + } + break; + } + case tp_dict: { + Dict* self = ud; + for(int i = 0; i < self->entries.length; i++) { + DictEntry* entry = c11__at(DictEntry, &self->entries, i); + if(py_isnil(&entry->key)) continue; + pk__mark_value(&entry->key); + pk__mark_value(&entry->val); + } + break; + } + case tp_generator: { + Generator* self = ud; + if(self->frame) Frame__gc_mark(self->frame); + break; + } + default: { + py_TypeInfo* ti = pk__type_info(obj->type); + if(ti->gc_mark) ti->gc_mark(ud); + } + } } void FuncDecl__gc_mark(const FuncDecl* self) { diff --git a/src/public/modules.c b/src/public/modules.c index b165dd16..98953daa 100644 --- a/src/public/modules.c +++ b/src/public/modules.c @@ -776,7 +776,13 @@ py_TValue pk_builtins__register() { static void function__gc_mark(void* ud) { Function* func = ud; if(func->globals) pk__mark_value(func->globals); - if(func->closure) pk__mark_namedict(func->closure); + if(func->closure) { + NameDict* namedict = func->closure; + for(int i = 0; i < namedict->length; i++) { + NameDict_KV* kv = c11__at(NameDict_KV, namedict, i); + pk__mark_value(&kv->value); + } + } FuncDecl__gc_mark(func->decl); } diff --git a/src/public/py_dict.c b/src/public/py_dict.c index 8f12f476..4ab786c8 100644 --- a/src/public/py_dict.c +++ b/src/public/py_dict.c @@ -5,8 +5,6 @@ #include "pocketpy/objects/object.h" #include "pocketpy/interpreter/vm.h" -#define PK_DICT_MAX_COLLISION 4 - static uint32_t Dict__next_cap(uint32_t cap) { switch(cap) { case 7: return 17; @@ -53,22 +51,7 @@ static uint32_t Dict__next_cap(uint32_t cap) { } } -typedef struct { - uint64_t hash; - py_TValue key; - py_TValue val; -} DictEntry; -typedef struct { - int _[PK_DICT_MAX_COLLISION]; -} DictIndex; - -typedef struct { - int length; - uint32_t capacity; - DictIndex* indices; - c11_vector /*T=DictEntry*/ entries; -} Dict; typedef struct { DictEntry* curr; @@ -525,21 +508,9 @@ static bool dict_values(int argc, py_Ref argv) { return true; } -static void dict__gc_mark(void* ud) { - Dict* self = ud; - for(int i = 0; i < self->entries.length; i++) { - DictEntry* entry = c11__at(DictEntry, &self->entries, i); - if(py_isnil(&entry->key)) continue; - pk__mark_value(&entry->key); - pk__mark_value(&entry->val); - } -} - py_Type pk_dict__register() { py_Type type = pk_newtype("dict", tp_object, NULL, (void (*)(void*))Dict__dtor, false, false); - pk__tp_set_marker(type, dict__gc_mark); - py_bindmagic(type, __new__, dict__new__); py_bindmagic(type, __init__, dict__init__); py_bindmagic(type, __getitem__, dict__getitem__); diff --git a/src/public/py_list.c b/src/public/py_list.c index 904653f1..d33585cf 100644 --- a/src/public/py_list.c +++ b/src/public/py_list.c @@ -5,8 +5,6 @@ #include "pocketpy/interpreter/vm.h" #include "pocketpy/common/sstream.h" -typedef c11_vector List; - void py_newlist(py_Ref out) { List* ud = py_newobject(out, tp_list, 0, sizeof(List)); c11_vector__ctor(ud, sizeof(py_TValue)); @@ -404,19 +402,10 @@ static bool list__contains__(int argc, py_Ref argv) { return pk_arraycontains(py_arg(0), py_arg(1)); } -static void list__gc_mark(void* ud) { - List* self = ud; - for(int i = 0; i < self->length; i++) { - pk__mark_value(c11__at(py_TValue, self, i)); - } -} - py_Type pk_list__register() { py_Type type = pk_newtype("list", tp_object, NULL, (void (*)(void*))c11_vector__dtor, false, true); - pk__tp_set_marker(type, list__gc_mark); - py_bindmagic(type, __len__, list__len__); py_bindmagic(type, __eq__, list__eq__); py_bindmagic(type, __ne__, list__ne__);