diff mbox

[v1,3/3] qom: Converged dynamic cast for interfaces & objs

Message ID 8fe64df91fc46d552142d2cae5101654755627f5.1339843070.git.peter.crosthwaite@petalogix.com
State New
Headers show

Commit Message

Peter A. G. Crosthwaite June 16, 2012, 10:39 a.m. UTC
Interfaces and Object for some reason have seperate code paths for dynamic
casting. AFAICT, Anthonys new interface specific cast is a functional superset
of the object cast, so this patch renames the interface cast to object cast and
blows away the original object cast.

Anyone want to shed any light on why the casts need to be different?

The problem (and the reason for this patch) is its not always possible for
user of interface to control how their object are going to be casted. Where this
broke down big-time is with links. The link setter code path explictly uses
object_dynamic_cast(), when link are set, which pretty much makes linking to
interfaces impossible. So either:

1: This patch
2: Explictly test objects/classes for interfacage in the link setting code
3: Ban linking to interfaces

Signed-off-by: Peter A. G. Crosthwaite <peter.crosthwaite@petalogix.com>
---
 include/qemu/object.h |   20 +-------------------
 qom/object.c          |   49 +++++++++----------------------------------------
 2 files changed, 10 insertions(+), 59 deletions(-)

Comments

Peter A. G. Crosthwaite June 18, 2012, 4:25 a.m. UTC | #1
On Sat, Jun 16, 2012 at 8:39 PM, Peter A. G. Crosthwaite
<peter.crosthwaite@petalogix.com> wrote:
> Interfaces and Object for some reason have seperate code paths for dynamic
> casting. AFAICT, Anthonys new interface specific cast is a functional superset
> of the object cast, so this patch renames the interface cast to object cast and
> blows away the original object cast.
>
> Anyone want to shed any light on why the casts need to be different?
>
> The problem (and the reason for this patch) is its not always possible for
> user of interface to control how their object are going to be casted. Where this
> broke down big-time is with links. The link setter code path explictly uses
> object_dynamic_cast(), when link are set, which pretty much makes linking to
> interfaces impossible. So either:
>
> 1: This patch
> 2: Explictly test objects/classes for interfacage in the link setting code
> 3: Ban linking to interfaces
>
> Signed-off-by: Peter A. G. Crosthwaite <peter.crosthwaite@petalogix.com>
> ---
>  include/qemu/object.h |   20 +-------------------
>  qom/object.c          |   49 +++++++++----------------------------------------
>  2 files changed, 10 insertions(+), 59 deletions(-)
>
> diff --git a/include/qemu/object.h b/include/qemu/object.h
> index 72cb290..a8916ce 100644
> --- a/include/qemu/object.h
> +++ b/include/qemu/object.h
> @@ -425,7 +425,7 @@ struct InterfaceClass
>  * Returns: @obj casted to @interface if cast is valid, otherwise raise error.
>  */
>  #define INTERFACE_CHECK(interface, obj, name) \
> -    ((interface *)interface_dynamic_cast_assert(OBJECT((obj)), (name)))
> +    ((interface *)object_dynamic_cast_assert(OBJECT((obj)), (name)))
>
>  /**
>  * object_new:
> @@ -564,24 +564,6 @@ ObjectClass *object_class_dynamic_cast(ObjectClass *klass,
>                                        const char *typename);
>
>  /**
> - * interface_dynamic_cast_assert:
> - * @obj: the object to cast to an interface type
> - * @typename: the type name of the interface
> - *
> - * Returns: @obj if @obj implements @typename, otherwise raise an error
> - */
> -Object *interface_dynamic_cast_assert(Object *obj, const char *typename);
> -
> -/**
> - * interface_dynamic_cast_assert:
> - * @obj: the object to cast to an interface type
> - * @typename: the type name of the interface
> - *
> - * Returns: @obj if @obj implements @typename, otherwise %NULL
> - */
> -Object *interface_dynamic_cast(Object *obj, const char *typename);
> -
> -/**
>  * object_class_get_name:
>  * @klass: The class to obtain the QOM typename for.
>  *
> diff --git a/qom/object.c b/qom/object.c
> index aa26693..7574666 100644
> --- a/qom/object.c
> +++ b/qom/object.c
> @@ -405,24 +405,6 @@ static bool object_is_type(Object *obj, TypeImpl *target_type)
>     return !target_type || type_is_ancestor(obj->class->type, target_type);
>  }
>

@@ -400,29 +400,6 @@ void object_delete(Object *obj)
     g_free(obj);
 }

Missing a hunk (that I found in my dirty tree) that belongs in this commit:

-static bool object_is_type(Object *obj, TypeImpl *target_type)
-{
-    return !target_type || type_is_ancestor(obj->class->type, target_type);
-}
-

Will remake (after review).

Regards,
Peter

> -Object *object_dynamic_cast(Object *obj, const char *typename)
> -{
> -    TypeImpl *target_type = type_get_by_name(typename);
> -
> -    /* Check if typename is a direct ancestor.  Special-case TYPE_OBJECT,
> -     * we want to go back from interfaces to the parent.
> -    */
> -    if (target_type && object_is_type(obj, target_type)) {
> -        return obj;
> -    }
> -
> -    if (!target_type) {
> -        return obj;
> -    }
> -
> -    return NULL;
> -}
> -
>  static void register_types(void)
>  {
>     static TypeInfo interface_info = {
> @@ -436,6 +418,15 @@ static void register_types(void)
>
>  type_init(register_types)
>
> +Object *object_dynamic_cast(Object *obj, const char *typename)
> +{
> +    if (object_class_dynamic_cast(object_get_class(obj), typename)) {
> +        return obj;
> +    }
> +
> +    return NULL;
> +}
> +
>  Object *object_dynamic_cast_assert(Object *obj, const char *typename)
>  {
>     Object *inst;
> @@ -496,28 +487,6 @@ ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
>     return ret;
>  }
>
> -Object *interface_dynamic_cast(Object *obj, const char *typename)
> -{
> -    if (object_class_dynamic_cast(object_get_class(obj), typename)) {
> -        return obj;
> -    }
> -
> -    return NULL;
> -}
> -
> -Object *interface_dynamic_cast_assert(Object *obj, const char *typename)
> -{
> -    Object *ret = interface_dynamic_cast(obj, typename);
> -
> -    if (!ret) {
> -        fprintf(stderr, "Object %p is not an instance of type %s\n",
> -                obj, typename);
> -        abort();
> -    }
> -
> -    return ret;
> -}
> -
>  const char *object_get_typename(Object *obj)
>  {
>     return obj->class->type->name;
> --
> 1.7.3.2
>
diff mbox

Patch

diff --git a/include/qemu/object.h b/include/qemu/object.h
index 72cb290..a8916ce 100644
--- a/include/qemu/object.h
+++ b/include/qemu/object.h
@@ -425,7 +425,7 @@  struct InterfaceClass
  * Returns: @obj casted to @interface if cast is valid, otherwise raise error.
  */
 #define INTERFACE_CHECK(interface, obj, name) \
-    ((interface *)interface_dynamic_cast_assert(OBJECT((obj)), (name)))
+    ((interface *)object_dynamic_cast_assert(OBJECT((obj)), (name)))
 
 /**
  * object_new:
@@ -564,24 +564,6 @@  ObjectClass *object_class_dynamic_cast(ObjectClass *klass,
                                        const char *typename);
 
 /**
- * interface_dynamic_cast_assert:
- * @obj: the object to cast to an interface type
- * @typename: the type name of the interface
- *
- * Returns: @obj if @obj implements @typename, otherwise raise an error
- */
-Object *interface_dynamic_cast_assert(Object *obj, const char *typename);
-
-/**
- * interface_dynamic_cast_assert:
- * @obj: the object to cast to an interface type
- * @typename: the type name of the interface
- *
- * Returns: @obj if @obj implements @typename, otherwise %NULL
- */
-Object *interface_dynamic_cast(Object *obj, const char *typename);
-
-/**
  * object_class_get_name:
  * @klass: The class to obtain the QOM typename for.
  *
diff --git a/qom/object.c b/qom/object.c
index aa26693..7574666 100644
--- a/qom/object.c
+++ b/qom/object.c
@@ -405,24 +405,6 @@  static bool object_is_type(Object *obj, TypeImpl *target_type)
     return !target_type || type_is_ancestor(obj->class->type, target_type);
 }
 
-Object *object_dynamic_cast(Object *obj, const char *typename)
-{
-    TypeImpl *target_type = type_get_by_name(typename);
-
-    /* Check if typename is a direct ancestor.  Special-case TYPE_OBJECT,
-     * we want to go back from interfaces to the parent.
-    */
-    if (target_type && object_is_type(obj, target_type)) {
-        return obj;
-    }
-
-    if (!target_type) {
-        return obj;
-    }
-
-    return NULL;
-}
-
 static void register_types(void)
 {
     static TypeInfo interface_info = {
@@ -436,6 +418,15 @@  static void register_types(void)
 
 type_init(register_types)
 
+Object *object_dynamic_cast(Object *obj, const char *typename)
+{
+    if (object_class_dynamic_cast(object_get_class(obj), typename)) {
+        return obj;
+    }
+
+    return NULL;
+}
+
 Object *object_dynamic_cast_assert(Object *obj, const char *typename)
 {
     Object *inst;
@@ -496,28 +487,6 @@  ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
     return ret;
 }
 
-Object *interface_dynamic_cast(Object *obj, const char *typename)
-{
-    if (object_class_dynamic_cast(object_get_class(obj), typename)) {
-        return obj;
-    }
-
-    return NULL;
-}
-
-Object *interface_dynamic_cast_assert(Object *obj, const char *typename)
-{
-    Object *ret = interface_dynamic_cast(obj, typename);
-
-    if (!ret) {
-        fprintf(stderr, "Object %p is not an instance of type %s\n",
-                obj, typename);
-        abort();
-    }
-
-    return ret;
-}
-
 const char *object_get_typename(Object *obj)
 {
     return obj->class->type->name;