diff mbox

[v2,04/24] qom: make Object a type

Message ID 1334179842-6061-4-git-send-email-pbonzini@redhat.com
State New
Headers show

Commit Message

Paolo Bonzini April 11, 2012, 9:30 p.m. UTC
Right now the base Object class has a special NULL type.  Change this so
that we will be able to add class_init and class_base_init callbacks.
To do this, remove some special casing of ObjectClass that is not really
necessary.

Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
---
 include/qemu/object.h |    2 +-
 qom/object.c          |   59 +++++++++++++++++++++++++------------------------
 2 files changed, 31 insertions(+), 30 deletions(-)

Comments

Andreas Färber April 12, 2012, 4:09 p.m. UTC | #1
Am 11.04.2012 23:30, schrieb Paolo Bonzini:
> Right now the base Object class has a special NULL type.  Change this so
> that we will be able to add class_init and class_base_init callbacks.
> To do this, remove some special casing of ObjectClass that is not really
> necessary.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
> ---
>  include/qemu/object.h |    2 +-
>  qom/object.c          |   59 +++++++++++++++++++++++++------------------------
>  2 files changed, 31 insertions(+), 30 deletions(-)
[...]
> diff --git a/qom/object.c b/qom/object.c
> index 6ff1c19..585619d 100644
> --- a/qom/object.c
> +++ b/qom/object.c
[...]
> @@ -1233,3 +1214,23 @@ void object_property_add_str(Object *obj, const char *name,
>                          property_release_str,
>                          prop, errp);
>  }
> +
> +static void register_types(void)
> +{
> +    static TypeInfo interface_info = {
> +        .name = TYPE_INTERFACE,
> +        .instance_size = sizeof(Interface),
> +        .abstract = true,
> +    };
> +
> +    static TypeInfo object_info = {
> +        .name = TYPE_OBJECT,
> +        .instance_size = sizeof(Object),
> +        .abstract = true,
> +    };
> +
> +    type_interface = type_register_static(&interface_info);
> +    type_register_static(&object_info);
> +}
> +
> +type_init(register_types)

I think I had suggested static const and moving them to before the
register_types() function?

Andreas
Paolo Bonzini April 12, 2012, 4:11 p.m. UTC | #2
Il 12/04/2012 18:09, Andreas Färber ha scritto:
> I think I had suggested static const and moving them to before the
> register_types() function?

I'm not sure why that would be useful...

Paolo
Andreas Färber April 12, 2012, 4:18 p.m. UTC | #3
Am 12.04.2012 18:11, schrieb Paolo Bonzini:
> Il 12/04/2012 18:09, Andreas Färber ha scritto:
>> I think I had suggested static const and moving them to before the
>> register_types() function?
> 
> I'm not sure why that would be useful...

Well, I'm not sure why Anthony is doing it differently from everywhere
else here. :)

Outside function:
Since you move it to the bottom of the file now (which I appreciate)
there's no need to shield it against misuse.

const:
Moves it to different ELF section iiuc and assures no unintentional
modification. We do that for the MemoryRegionOps and I am planning to
post a patch to clean up all old TypeInfo uses (in an intermediate step
by Anthony it was being used in a non-const way) so that they don't
propagate further in the code.

Andreas
Andreas Färber April 12, 2012, 4:26 p.m. UTC | #4
Am 11.04.2012 23:30, schrieb Paolo Bonzini:
> Right now the base Object class has a special NULL type.  Change this so
> that we will be able to add class_init and class_base_init callbacks.
> To do this, remove some special casing of ObjectClass that is not really
> necessary.
> 
> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>

I had also pointed out that no longer handling .parent = NULL as
TYPE_OBJECT can have unwanted effects of not deriving some objects from
TYPE_OBJECT. I see no statement that the code was reviewed for TypeInfos
that don't set .parent (or set it to NULL). Nor do I see the suggested
check against whitelisted base classes "object" and "interface" to
detect such uses at startup. Do you want a patch for that, forgot or
decided against?

Andreas
Paolo Bonzini April 12, 2012, 4:51 p.m. UTC | #5
Il 12/04/2012 18:26, Andreas Färber ha scritto:
> I had also pointed out that no longer handling .parent = NULL as
> TYPE_OBJECT can have unwanted effects of not deriving some objects from
> TYPE_OBJECT. I see no statement that the code was reviewed for TypeInfos
> that don't set .parent (or set it to NULL). Nor do I see the suggested
> check against whitelisted base classes "object" and "interface" to
> detect such uses at startup. Do you want a patch for that, forgot or
> decided against?

It should be later in the series; I moved it here on github.

Paolo
diff mbox

Patch

diff --git a/include/qemu/object.h b/include/qemu/object.h
index ccaea7d..22f646d 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -33,7 +33,7 @@  typedef struct TypeInfo TypeInfo;
 typedef struct InterfaceClass InterfaceClass;
 typedef struct InterfaceInfo InterfaceInfo;
 
-#define TYPE_OBJECT NULL
+#define TYPE_OBJECT "object"
 
 /**
  * SECTION:object.h
diff --git a/qom/object.c b/qom/object.c
index 6ff1c19..585619d 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -210,7 +210,7 @@  static void type_class_interface_init(TypeImpl *ti, InterfaceImpl *iface)
 
 static void type_initialize(TypeImpl *ti)
 {
-    size_t class_size = sizeof(ObjectClass);
+    TypeImpl *parent;
     int i;
 
     if (ti->class) {
@@ -221,30 +221,24 @@  static void type_initialize(TypeImpl *ti)
     ti->instance_size = type_object_get_size(ti);
 
     ti->class = g_malloc0(ti->class_size);
-    ti->class->type = ti;
-
-    if (type_has_parent(ti)) {
-        TypeImpl *parent = type_get_parent(ti);
 
+    parent = type_get_parent(ti);
+    if (parent) {
         type_initialize(parent);
 
-        class_size = parent->class_size;
         g_assert(parent->class_size <= ti->class_size);
+        memcpy(ti->class, parent->class, parent->class_size);
+    }
 
-        memcpy((void *)ti->class + sizeof(ObjectClass),
-               (void *)parent->class + sizeof(ObjectClass),
-               parent->class_size - sizeof(ObjectClass));
+    ti->class->type = ti;
 
-        while (parent) {
-            if (parent->class_base_init) {
-                parent->class_base_init(ti->class, ti->class_data);
-            }
-            parent = type_get_parent(parent);
+    while (parent) {
+        if (parent->class_base_init) {
+            parent->class_base_init(ti->class, ti->class_data);
         }
+        parent = type_get_parent(parent);
     }
 
-    memset((void *)ti->class + class_size, 0, ti->class_size - class_size);
-
     for (i = 0; i < ti->num_interfaces; i++) {
         type_class_interface_init(ti, &ti->interfaces[i]);
     }
@@ -467,19 +461,6 @@  Object *object_dynamic_cast(Object *obj, const char *typename)
 }
 
 
-static void register_types(void)
-{
-    static TypeInfo interface_info = {
-        .name = TYPE_INTERFACE,
-        .instance_size = sizeof(Interface),
-        .abstract = true,
-    };
-
-    type_interface = type_register_static(&interface_info);
-}
-
-type_init(register_types)
-
 Object *object_dynamic_cast_assert(Object *obj, const char *typename)
 {
     Object *inst;
@@ -1233,3 +1214,23 @@  void object_property_add_str(Object *obj, const char *name,
                         property_release_str,
                         prop, errp);
 }
+
+static void register_types(void)
+{
+    static TypeInfo interface_info = {
+        .name = TYPE_INTERFACE,
+        .instance_size = sizeof(Interface),
+        .abstract = true,
+    };
+
+    static TypeInfo object_info = {
+        .name = TYPE_OBJECT,
+        .instance_size = sizeof(Object),
+        .abstract = true,
+    };
+
+    type_interface = type_register_static(&interface_info);
+    type_register_static(&object_info);
+}
+
+type_init(register_types)