接前一篇文章: 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宏的地方,继续深入展开分析。