From b061dc41f62048acd4a34c6570c0ea396cd9d0b4 Mon Sep 17 00:00:00 2001 From: Paolo Bonzini Date: Tue, 3 Dec 2013 16:41:59 +0100 Subject: [PATCH] qom: Do not register interface "types" in the type table and fix names MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit There should be no need to look up nor enumerate the interface "types", whose "classes" are really just vtables. Just create the types and add them to the interface list of the parent type. Interfaces not registering their type anymore means that accessing superclass::interface by type name will fail when initializing subclass::interface. Thus, we need to pre-initialize the subclass's parent_type field before calling type_initialize. Apart from this, the interface "types" should never be used and thus it is harmless to leave them out of the hashtable. Further, the interface types had a bug with interfaces that are inherited from a superclass: The implementation type name was wrong (for example it was subclass::superclass::interface rather than just subclass::interface). This patch fixes this as well. Reported-by: Igor Mammedov Tested-by: Igor Mammedov Signed-off-by: Paolo Bonzini Signed-off-by: Andreas Färber --- include/qom/object.h | 1 + qom/object.c | 32 +++++++++++++++++++++----------- 2 files changed, 22 insertions(+), 11 deletions(-) diff --git a/include/qom/object.h b/include/qom/object.h index 5f78847d68..e0ff212cb6 100644 --- a/include/qom/object.h +++ b/include/qom/object.h @@ -536,6 +536,7 @@ struct InterfaceClass ObjectClass parent_class; /*< private >*/ ObjectClass *concrete_class; + Type interface_type; }; #define TYPE_INTERFACE "interface" diff --git a/qom/object.c b/qom/object.c index 21b5a0bbe1..470a1ac86d 100644 --- a/qom/object.c +++ b/qom/object.c @@ -88,7 +88,7 @@ static TypeImpl *type_table_lookup(const char *name) return g_hash_table_lookup(type_table_get(), name); } -static TypeImpl *type_register_internal(const TypeInfo *info) +static TypeImpl *type_new(const TypeInfo *info) { TypeImpl *ti = g_malloc0(sizeof(*ti)); int i; @@ -122,8 +122,15 @@ static TypeImpl *type_register_internal(const TypeInfo *info) } ti->num_interfaces = i; - type_table_add(ti); + return ti; +} +static TypeImpl *type_register_internal(const TypeInfo *info) +{ + TypeImpl *ti; + ti = type_new(info); + + type_table_add(ti); return ti; } @@ -206,22 +213,25 @@ static bool type_is_ancestor(TypeImpl *type, TypeImpl *target_type) static void type_initialize(TypeImpl *ti); -static void type_initialize_interface(TypeImpl *ti, const char *parent) +static void type_initialize_interface(TypeImpl *ti, TypeImpl *interface_type, + TypeImpl *parent_type) { InterfaceClass *new_iface; TypeInfo info = { }; TypeImpl *iface_impl; - info.parent = parent; - info.name = g_strdup_printf("%s::%s", ti->name, info.parent); + info.parent = parent_type->name; + info.name = g_strdup_printf("%s::%s", ti->name, interface_type->name); info.abstract = true; - iface_impl = type_register(&info); + iface_impl = type_new(&info); + iface_impl->parent_type = parent_type; type_initialize(iface_impl); g_free((char *)info.name); new_iface = (InterfaceClass *)iface_impl->class; new_iface->concrete_class = ti->class; + new_iface->interface_type = interface_type; ti->class->interfaces = g_slist_append(ti->class->interfaces, iface_impl->class); @@ -251,8 +261,10 @@ static void type_initialize(TypeImpl *ti) ti->class->interfaces = NULL; for (e = parent->class->interfaces; e; e = e->next) { - ObjectClass *iface = e->data; - type_initialize_interface(ti, object_class_get_name(iface)); + InterfaceClass *iface = e->data; + ObjectClass *klass = OBJECT_CLASS(iface); + + type_initialize_interface(ti, iface->interface_type, klass->type); } for (i = 0; i < ti->num_interfaces; i++) { @@ -269,7 +281,7 @@ static void type_initialize(TypeImpl *ti) continue; } - type_initialize_interface(ti, ti->interfaces[i].typename); + type_initialize_interface(ti, t, t); } } @@ -285,8 +297,6 @@ static void type_initialize(TypeImpl *ti) if (ti->class_init) { ti->class_init(ti->class, ti->class_data); } - - } static void object_init_with_type(Object *obj, TypeImpl *ti)