接前一篇文章:QEMU源码全解析38 —— Machine(8)
本文内容参考:
《QEMU/KVM》源码解析与应用 —— 李强,机械工业出版社
特此致谢!
上一回经过层层展开探索,终于看到了MACHINE的定义,实际上它是一个函数,代码如下(include/hw/boards.h中):
static inline G_GNUC_UNUSED MachineState *MACHINE(const void *obj)
{
return OBJECT_CHECK(MachineState, obj, TYPE_MACHINE);
}
OBJECT_CHECK是一个宏,在include/qom/object.h中定义,代码如下:
/**
* OBJECT_CHECK:
* @type: The C type to use for the return value.
* @obj: A derivative of @type to cast.
* @name: The QOM typename of @type
*
* A type safe version of @object_dynamic_cast_assert. Typically each class
* will define a macro based on this type to perform type safe dynamic_casts to
* this object type.
*
* If an invalid object is passed to this function, a run time assert will be
* generated.
*/
#define OBJECT_CHECK(type, obj, name) \
((type *)object_dynamic_cast_assert(OBJECT(obj), (name), \
__FILE__, __LINE__, __func__))
因此,代入宏定义后,MACHINE函数的最终代码为:
static inline G_GNUC_UNUSED MachineState *MACHINE(const void *obj)
{
return ((MachineState*)object_dynamic_cast_assert(OBJECT(obj), ("machine"), __FILE__, __LINE__, __func__));
}
object_dynamic_cast_assert函数在qom/object.c中,代码如下:
Object *object_dynamic_cast_assert(Object *obj, const char *typename,
const char *file, int line, const char *func)
{
trace_object_dynamic_cast_assert(obj ? obj->class->type->name : "(null)",
typename, file, line, func);
#ifdef CONFIG_QOM_CAST_DEBUG
int i;
Object *inst;
for (i = 0; obj && i < OBJECT_CLASS_CAST_CACHE; i++) {
if (qatomic_read(&obj->class->object_cast_cache[i]) == typename) {
goto out;
}
}
inst = object_dynamic_cast(obj, typename);
if (!inst && obj) {
fprintf(stderr, "%s:%d:%s: Object %p is not an instance of type %s\n",
file, line, func, obj, typename);
abort();
}
assert(obj == inst);
if (obj && obj == inst) {
for (i = 1; i < OBJECT_CLASS_CAST_CACHE; i++) {
qatomic_set(&obj->class->object_cast_cache[i - 1],
qatomic_read(&obj->class->object_cast_cache[i]));
}
qatomic_set(&obj->class->object_cast_cache[i - 1], typename);
}
out:
#endif
return obj;
}
Object前文已介绍过,是所有对象的祖先。这里为了便于理解,再给出其代码。在include/qemu/typedefs.h中定义,如下:
typedef struct Object Object;
struct Object在中定义,代码如下:
/**
* struct Object:
*
* The base for all objects. The first member of this object is a pointer to
* a #ObjectClass. Since C guarantees that the first member of a structure
* always begins at byte 0 of that structure, as long as any sub-object places
* its parent as the first member, we can cast directly to a #Object.
*
* As a result, #Object contains a reference to the objects type as its
* first member. This allows identification of the real type of the object at
* run time.
*/
struct Object
{
/* private: */
ObjectClass *class;
ObjectFree *free;
GHashTable *properties;
uint32_t ref;
Object *parent;
};
实际上就是类型进行检查,确保传入的对象类型是machine类型。
本着“一张一弛”的原则,本回就到这里。下一回将结合实际调用MACHINE宏的地方,继续深入展开分析。