diff --git a/include/pocketpy/interpreter/typeinfo.h b/include/pocketpy/interpreter/typeinfo.h index ffd0b060..c3c500bd 100644 --- a/include/pocketpy/interpreter/typeinfo.h +++ b/include/pocketpy/interpreter/typeinfo.h @@ -6,6 +6,7 @@ typedef struct py_TypeInfo { py_Name name; py_Type base; + struct py_TypeInfo* base_ti; py_TValue self; py_TValue module; // the module where the type is defined diff --git a/src/interpreter/ceval.c b/src/interpreter/ceval.c index 98aac846..cf8591b6 100644 --- a/src/interpreter/ceval.c +++ b/src/interpreter/ceval.c @@ -894,7 +894,7 @@ FrameResult VM__run_top_frame(VM* self) { // call on_end_subclass py_TypeInfo* ti = TypeList__get(&self->types, py_totype(TOP())); if(ti->base != tp_object) { - py_TypeInfo* base_ti = TypeList__get(&self->types, ti->base); + py_TypeInfo* base_ti = ti->base_ti; if(base_ti->on_end_subclass) base_ti->on_end_subclass(ti); } } diff --git a/src/interpreter/vm.c b/src/interpreter/vm.c index 22838690..7ae275cb 100644 --- a/src/interpreter/vm.c +++ b/src/interpreter/vm.c @@ -33,11 +33,13 @@ static void py_TypeInfo__ctor(py_TypeInfo* self, py_Name name, py_Type index, py_Type base, + py_TypeInfo* base_ti, py_TValue module) { memset(self, 0, sizeof(py_TypeInfo)); self->name = name; self->base = base; + self->base_ti = base_ti; // create type object with __dict__ ManagedHeap* heap = &pk_current_vm->heap; @@ -323,7 +325,7 @@ py_Type pk_newtype(const char* name, if(base_ti && base_ti->is_sealed) { c11__abort("type '%s' is not an acceptable base type", py_name2str(base_ti->name)); } - py_TypeInfo__ctor(ti, py_name(name), index, base, module ? *module : *py_NIL); + py_TypeInfo__ctor(ti, py_name(name), index, base, base_ti, module ? *module : *py_NIL); if(!dtor && base) dtor = base_ti->dtor; ti->dtor = dtor; ti->is_python = is_python; @@ -697,6 +699,4 @@ bool pk_wrapper__NotImplementedError(int argc, py_Ref argv) { return py_exception(tp_NotImplementedError, ""); } -py_TypeInfo* pk__type_info(py_Type type) { - return TypeList__get(&pk_current_vm->types, type); -} +py_TypeInfo* pk__type_info(py_Type type) { return TypeList__get(&pk_current_vm->types, type); } diff --git a/src/modules/enum.c b/src/modules/enum.c index c2f170a4..11bb57f9 100644 --- a/src/modules/enum.c +++ b/src/modules/enum.c @@ -86,6 +86,5 @@ void pk__add_module_enum() { py_bindproperty(type, "name", Enum__name, NULL); py_bindproperty(type, "value", Enum__value, NULL); - py_TypeInfo* ti = pk__type_info(type); - ti->on_end_subclass = Enum__on_end_subclass; + pk__type_info(type)->on_end_subclass = Enum__on_end_subclass; } \ No newline at end of file diff --git a/src/public/internal.c b/src/public/internal.c index 495b50f2..6b086d99 100644 --- a/src/public/internal.c +++ b/src/public/internal.c @@ -190,24 +190,22 @@ bool pk_loadmethod(py_StackRef self, py_Name name) { py_Ref py_tpfindmagic(py_Type t, py_Name name) { assert(py_ismagicname(name)); - TypeList* types = &pk_current_vm->types; + py_TypeInfo* ti = pk__type_info(t); do { - py_TypeInfo* ti = TypeList__get(types, t); py_Ref f = &ti->magic[name]; if(!py_isnil(f)) return f; - t = ti->base; - } while(t); + ti = ti->base_ti; + } while(ti); return NULL; } py_Ref py_tpfindname(py_Type t, py_Name name) { - TypeList* types = &pk_current_vm->types; + py_TypeInfo* ti = pk__type_info(t); do { - py_TypeInfo* ti = TypeList__get(types, t); py_Ref res = py_getdict(&ti->self, name); if(res) return res; - t = ti->base; - } while(t); + ti = ti->base_ti; + } while(ti); return NULL; } diff --git a/src/public/py_object.c b/src/public/py_object.c index fd577130..3f7c2f02 100644 --- a/src/public/py_object.c +++ b/src/public/py_object.c @@ -74,7 +74,7 @@ static bool type__base__(int argc, py_Ref argv) { PY_CHECK_ARGC(1); py_TypeInfo* ti = pk__type_info(py_totype(argv)); if(ti->base) { - py_assign(py_retval(), py_tpobject(ti->base)); + py_assign(py_retval(), &ti->base_ti->self); } else { py_newnone(py_retval()); } diff --git a/src/public/py_ops.c b/src/public/py_ops.c index da2a1aab..30b2bfa0 100644 --- a/src/public/py_ops.c +++ b/src/public/py_ops.c @@ -45,10 +45,8 @@ int py_bool(py_Ref val) { } bool py_hash(py_Ref val, int64_t* out) { - py_Type t = val->type; - TypeList* types = &pk_current_vm->types; + py_TypeInfo* ti = pk__type_info(val->type); do { - py_TypeInfo* ti = TypeList__get(types, t); py_Ref _hash = &ti->magic[__hash__]; if(py_isnone(_hash)) break; py_Ref _eq = &ti->magic[__eq__]; @@ -59,8 +57,8 @@ bool py_hash(py_Ref val, int64_t* out) { *out = py_toint(py_retval()); return true; } - t = ti->base; - } while(t); + ti = ti->base_ti; + } while(ti); return TypeError("unhashable type: '%t'", val->type); }