add py_tpclassattrs and py_tpbase

This commit is contained in:
blueloveTH 2025-06-10 23:07:53 +08:00
parent 70e824a6b6
commit 141f187705
6 changed files with 25 additions and 7 deletions

View File

@ -18,12 +18,10 @@ typedef struct py_TypeInfo {
void (*dtor)(void*); void (*dtor)(void*);
py_TValue annotations; // type annotations py_TValue annotations;
c11_vector /*T=py_Name*/ ordered_attrs;
void (*on_end_subclass)(struct py_TypeInfo*); // backdoor for enum module void (*on_end_subclass)(struct py_TypeInfo*); // backdoor for enum module
/* Magic Slots */
// (deleted)
} py_TypeInfo; } py_TypeInfo;
typedef struct TypeList { typedef struct TypeList {
@ -36,4 +34,3 @@ void TypeList__dtor(TypeList* self);
py_TypeInfo* TypeList__get(TypeList* self, py_Type index); py_TypeInfo* TypeList__get(TypeList* self, py_Type index);
py_TypeInfo* TypeList__emplace(TypeList* self); py_TypeInfo* TypeList__emplace(TypeList* self);
void TypeList__apply(TypeList* self, void (*f)(py_TypeInfo*, void*), void* ctx); void TypeList__apply(TypeList* self, void (*f)(py_TypeInfo*, void*), void* ctx);

View File

@ -325,7 +325,7 @@ PK_API bool py_isinstance(py_Ref obj, py_Type type);
PK_API bool py_issubclass(py_Type derived, py_Type base); PK_API bool py_issubclass(py_Type derived, py_Type base);
/// Get the magic method from the given type only. /// Get the magic method from the given type only.
/// The returned reference is always valid. However, its value may be `nil`. /// Return `nil` if not found.
PK_API PK_DEPRECATED py_GlobalRef py_tpgetmagic(py_Type type, py_Name name); PK_API PK_DEPRECATED py_GlobalRef py_tpgetmagic(py_Type type, py_Name name);
/// Search the magic method from the given type to the base type. /// Search the magic method from the given type to the base type.
/// Return `NULL` if not found. /// Return `NULL` if not found.
@ -333,6 +333,11 @@ PK_API py_GlobalRef py_tpfindmagic(py_Type, py_Name name);
/// Search the name from the given type to the base type. /// Search the name from the given type to the base type.
/// Return `NULL` if not found. /// Return `NULL` if not found.
PK_API py_ItemRef py_tpfindname(py_Type, py_Name name); PK_API py_ItemRef py_tpfindname(py_Type, py_Name name);
/// Get ordered attributes of the type.
// These attributes must be defined under `class` statement.
PK_API py_Name* py_tpclassattrs(py_Type, int* out_length);
/// Get the base type of the given type.
PK_API py_Type py_tpbase(py_Type type);
/// Get the type object of the given type. /// Get the type object of the given type.
PK_API py_GlobalRef py_tpobject(py_Type type); PK_API py_GlobalRef py_tpobject(py_Type type);

View File

@ -1079,6 +1079,8 @@ FrameResult VM__run_top_frame(VM* self) {
} }
case OP_STORE_CLASS_ATTR: { case OP_STORE_CLASS_ATTR: {
assert(self->curr_class); 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]; py_Name name = co_names[byte.arg];
// TOP() can be a function, classmethod or custom decorator // TOP() can be a function, classmethod or custom decorator
py_Ref actual_func = TOP(); py_Ref actual_func = TOP();
@ -1090,6 +1092,7 @@ FrameResult VM__run_top_frame(VM* self) {
ud->clazz = self->curr_class->_obj; ud->clazz = self->curr_class->_obj;
} }
py_setdict(self->curr_class, name, TOP()); py_setdict(self->curr_class, name, TOP());
c11_vector__push(py_Name, &ti->ordered_attrs, name);
POP(); POP();
DISPATCH(); DISPATCH();
} }

View File

@ -12,7 +12,7 @@ void TypeList__ctor(TypeList* self) {
void TypeList__dtor(TypeList* self) { void TypeList__dtor(TypeList* self) {
for(py_Type t = 0; t < self->length; t++) { for(py_Type t = 0; t < self->length; t++) {
py_TypeInfo* info = TypeList__get(self, t); py_TypeInfo* info = TypeList__get(self, t);
(void)info; c11_vector__dtor(&info->ordered_attrs);
} }
for(int i = 0; i < PK_MAX_CHUNK_LENGTH; i++) { for(int i = 0; i < PK_MAX_CHUNK_LENGTH; i++) {
if(self->chunks[i]) PK_FREE(self->chunks[i]); if(self->chunks[i]) PK_FREE(self->chunks[i]);

View File

@ -63,6 +63,7 @@ static void py_TypeInfo__ctor(py_TypeInfo* self,
self->module = module; self->module = module;
self->annotations = *py_NIL(); self->annotations = *py_NIL();
c11_vector__ctor(&self->ordered_attrs, sizeof(py_Name));
} }
void VM__ctor(VM* self) { void VM__ctor(VM* self) {

View File

@ -247,6 +247,18 @@ py_Ref py_tpfindname(py_Type t, py_Name name) {
return NULL; return NULL;
} }
py_Name* py_tpclassattrs(py_Type t, int* out_length) {
py_TypeInfo* ti = pk__type_info(t);
*out_length = ti->ordered_attrs.length;
return ti->ordered_attrs.data;
}
py_Type py_tpbase(py_Type t) {
assert(t);
py_TypeInfo* ti = pk__type_info(t);
return py_totype(&ti->base_ti->self);
}
PK_DEPRECATED py_Ref py_tpgetmagic(py_Type type, py_Name name) { PK_DEPRECATED py_Ref py_tpgetmagic(py_Type type, py_Name name) {
assert(py_ismagicname(name)); assert(py_ismagicname(name));
py_TypeInfo* ti = pk__type_info(type); py_TypeInfo* ti = pk__type_info(type);