Revision 9970bd88

b/qom/object.c
63 63

  
64 64
#define INTERFACE(obj) OBJECT_CHECK(Interface, obj, TYPE_INTERFACE)
65 65

  
66
static Type type_interface;
67

  
66 68
static GHashTable *type_table_get(void)
67 69
{
68 70
    static GHashTable *type_table;
......
384 386
    return false;
385 387
}
386 388

  
387
static bool object_is_type(Object *obj, const char *typename)
389
static bool object_is_type(Object *obj, TypeImpl *target_type)
388 390
{
389
    TypeImpl *target_type;
390

  
391
    if (typename == TYPE_OBJECT) {
392
        return true;
393
    }
394
    target_type = type_get_by_name(typename);
395
    return type_is_ancestor(obj->class->type, target_type);
391
    return !target_type || type_is_ancestor(obj->class->type, target_type);
396 392
}
397 393

  
398 394
Object *object_dynamic_cast(Object *obj, const char *typename)
399 395
{
396
    TypeImpl *target_type = type_get_by_name(typename);
400 397
    GSList *i;
401 398

  
402 399
    /* Check if typename is a direct ancestor.  Special-case TYPE_OBJECT,
403 400
     * we want to go back from interfaces to the parent.
404 401
    */
405
    if (typename && object_is_type(obj, typename)) {
402
    if (target_type && object_is_type(obj, target_type)) {
406 403
        return obj;
407 404
    }
408 405

  
......
410 407
     * ancestor of typename.  In principle we could do this test at the very
411 408
     * beginning of object_dynamic_cast, avoiding a second call to
412 409
     * object_is_type.  However, casting between interfaces is relatively
413
     * rare, and object_is_type(obj, TYPE_INTERFACE) would fail almost always.
410
     * rare, and object_is_type(obj, type_interface) would fail almost always.
414 411
     *
415 412
     * Perhaps we could add a magic value to the object header for increased
416 413
     * (run-time) type safety and to speed up tests like this one.  If we ever
417 414
     * do that we can revisit the order here.
418 415
     */
419
    if (object_is_type(obj, TYPE_INTERFACE)) {
416
    if (object_is_type(obj, type_interface)) {
420 417
        assert(!obj->interfaces);
421 418
        obj = INTERFACE(obj)->obj;
422
        if (object_is_type(obj, typename)) {
419
        if (object_is_type(obj, target_type)) {
423 420
            return obj;
424 421
        }
425 422
    }
426 423

  
427
    if (typename == TYPE_OBJECT) {
424
    if (!target_type) {
428 425
        return obj;
429 426
    }
430 427

  
......
432 429
    for (i = obj->interfaces; i; i = i->next) {
433 430
        Interface *iface = i->data;
434 431

  
435
        if (object_is_type(OBJECT(iface), typename)) {
432
        if (object_is_type(OBJECT(iface), target_type)) {
436 433
            return OBJECT(iface);
437 434
        }
438 435
    }
......
449 446
        .abstract = true,
450 447
    };
451 448

  
452
    type_register_static(&interface_info);
449
    type_interface = type_register_static(&interface_info);
453 450
}
454 451

  
455 452
device_init(register_interface);

Also available in: Unified diff