qdev: prepare source tree for code conversion
[qemu.git] / qom / object.c
blobef37e080d4e21725588edfe540e764b1357a001c
1 /*
2 * QEMU Object Model
4 * Copyright IBM, Corp. 2011
6 * Authors:
7 * Anthony Liguori <aliguori@us.ibm.com>
9 * This work is licensed under the terms of the GNU GPL, version 2 or later.
10 * See the COPYING file in the top-level directory.
13 #include "qemu/object.h"
14 #include "qemu-common.h"
16 #define MAX_INTERFACES 32
18 typedef struct InterfaceImpl InterfaceImpl;
19 typedef struct TypeImpl TypeImpl;
21 struct InterfaceImpl
23 const char *parent;
24 void (*interface_initfn)(ObjectClass *class, void *data);
25 TypeImpl *type;
28 struct TypeImpl
30 const char *name;
32 size_t class_size;
34 size_t instance_size;
36 void (*class_init)(ObjectClass *klass, void *data);
37 void (*class_finalize)(ObjectClass *klass, void *data);
39 void *class_data;
41 void (*instance_init)(Object *obj);
42 void (*instance_finalize)(Object *obj);
44 bool abstract;
46 const char *parent;
47 TypeImpl *parent_type;
49 ObjectClass *class;
51 int num_interfaces;
52 InterfaceImpl interfaces[MAX_INTERFACES];
55 typedef struct Interface
57 Object parent;
58 Object *obj;
59 } Interface;
61 #define INTERFACE(obj) OBJECT_CHECK(Interface, obj, TYPE_INTERFACE)
63 static GHashTable *type_table_get(void)
65 static GHashTable *type_table;
67 if (type_table == NULL) {
68 type_table = g_hash_table_new(g_str_hash, g_str_equal);
71 return type_table;
74 static void type_table_add(TypeImpl *ti)
76 g_hash_table_insert(type_table_get(), (void *)ti->name, ti);
79 static TypeImpl *type_table_lookup(const char *name)
81 return g_hash_table_lookup(type_table_get(), name);
84 TypeImpl *type_register(const TypeInfo *info)
86 TypeImpl *ti = g_malloc0(sizeof(*ti));
88 g_assert(info->name != NULL);
90 ti->name = g_strdup(info->name);
91 ti->parent = g_strdup(info->parent);
93 ti->class_size = info->class_size;
94 ti->instance_size = info->instance_size;
96 ti->class_init = info->class_init;
97 ti->class_finalize = info->class_finalize;
98 ti->class_data = info->class_data;
100 ti->instance_init = info->instance_init;
101 ti->instance_finalize = info->instance_finalize;
103 ti->abstract = info->abstract;
105 if (info->interfaces) {
106 int i;
108 for (i = 0; info->interfaces[i].type; i++) {
109 ti->interfaces[i].parent = info->interfaces[i].type;
110 ti->interfaces[i].interface_initfn = info->interfaces[i].interface_initfn;
111 ti->num_interfaces++;
115 type_table_add(ti);
117 return ti;
120 TypeImpl *type_register_static(const TypeInfo *info)
122 return type_register(info);
125 static TypeImpl *type_get_by_name(const char *name)
127 if (name == NULL) {
128 return NULL;
131 return type_table_lookup(name);
134 static TypeImpl *type_get_parent(TypeImpl *type)
136 if (!type->parent_type && type->parent) {
137 type->parent_type = type_get_by_name(type->parent);
138 g_assert(type->parent_type != NULL);
141 return type->parent_type;
144 static bool type_has_parent(TypeImpl *type)
146 return (type->parent != NULL);
149 static size_t type_class_get_size(TypeImpl *ti)
151 if (ti->class_size) {
152 return ti->class_size;
155 if (type_has_parent(ti)) {
156 return type_class_get_size(type_get_parent(ti));
159 return sizeof(ObjectClass);
162 static void type_class_interface_init(TypeImpl *ti, InterfaceImpl *iface)
164 TypeInfo info = {
165 .instance_size = sizeof(Interface),
166 .parent = iface->parent,
167 .class_size = sizeof(InterfaceClass),
168 .class_init = iface->interface_initfn,
169 .abstract = true,
171 char *name = g_strdup_printf("<%s::%s>", ti->name, iface->parent);
173 info.name = name;
174 iface->type = type_register(&info);
175 g_free(name);
178 static void type_class_init(TypeImpl *ti)
180 size_t class_size = sizeof(ObjectClass);
181 int i;
183 if (ti->class) {
184 return;
187 ti->class_size = type_class_get_size(ti);
189 ti->class = g_malloc0(ti->class_size);
190 ti->class->type = ti;
192 if (type_has_parent(ti)) {
193 TypeImpl *parent = type_get_parent(ti);
195 type_class_init(parent);
197 class_size = parent->class_size;
198 g_assert(parent->class_size <= ti->class_size);
200 memcpy((void *)ti->class + sizeof(ObjectClass),
201 (void *)parent->class + sizeof(ObjectClass),
202 parent->class_size - sizeof(ObjectClass));
205 memset((void *)ti->class + class_size, 0, ti->class_size - class_size);
207 for (i = 0; i < ti->num_interfaces; i++) {
208 type_class_interface_init(ti, &ti->interfaces[i]);
211 if (ti->class_init) {
212 ti->class_init(ti->class, ti->class_data);
216 static void object_interface_init(Object *obj, InterfaceImpl *iface)
218 TypeImpl *ti = iface->type;
219 Interface *iface_obj;
221 iface_obj = INTERFACE(object_new(ti->name));
222 iface_obj->obj = obj;
224 obj->interfaces = g_slist_prepend(obj->interfaces, iface_obj);
227 static void object_init_with_type(Object *obj, TypeImpl *ti)
229 int i;
231 if (type_has_parent(ti)) {
232 object_init_with_type(obj, type_get_parent(ti));
235 for (i = 0; i < ti->num_interfaces; i++) {
236 object_interface_init(obj, &ti->interfaces[i]);
239 if (ti->instance_init) {
240 ti->instance_init(obj);
244 void object_initialize_with_type(void *data, TypeImpl *type)
246 Object *obj = data;
248 g_assert(type != NULL);
249 g_assert(type->instance_size >= sizeof(ObjectClass));
251 type_class_init(type);
252 g_assert(type->abstract == false);
254 memset(obj, 0, type->instance_size);
255 obj->class = type->class;
256 object_init_with_type(obj, type);
259 void object_initialize(void *data, const char *typename)
261 TypeImpl *type = type_get_by_name(typename);
263 object_initialize_with_type(data, type);
266 static void object_deinit(Object *obj, TypeImpl *type)
268 if (type->instance_finalize) {
269 type->instance_finalize(obj);
272 while (obj->interfaces) {
273 Interface *iface_obj = obj->interfaces->data;
274 obj->interfaces = g_slist_delete_link(obj->interfaces, obj->interfaces);
275 object_delete(OBJECT(iface_obj));
278 if (type_has_parent(type)) {
279 object_deinit(obj, type_get_parent(type));
283 void object_finalize(void *data)
285 Object *obj = data;
286 TypeImpl *ti = obj->class->type;
288 object_deinit(obj, ti);
291 Object *object_new_with_type(Type type)
293 Object *obj;
295 g_assert(type != NULL);
297 obj = g_malloc(type->instance_size);
298 object_initialize_with_type(obj, type);
300 return obj;
303 Object *object_new(const char *typename)
305 TypeImpl *ti = type_get_by_name(typename);
307 return object_new_with_type(ti);
310 void object_delete(Object *obj)
312 object_finalize(obj);
313 g_free(obj);
316 static bool object_is_type(Object *obj, const char *typename)
318 TypeImpl *target_type = type_get_by_name(typename);
319 TypeImpl *type = obj->class->type;
320 GSList *i;
322 /* Check if typename is a direct ancestor of type */
323 while (type) {
324 if (type == target_type) {
325 return true;
328 type = type_get_parent(type);
331 /* Check if obj has an interface of typename */
332 for (i = obj->interfaces; i; i = i->next) {
333 Interface *iface = i->data;
335 if (object_is_type(OBJECT(iface), typename)) {
336 return true;
340 return false;
343 Object *object_dynamic_cast(Object *obj, const char *typename)
345 GSList *i;
347 /* Check if typename is a direct ancestor */
348 if (object_is_type(obj, typename)) {
349 return obj;
352 /* Check if obj has an interface of typename */
353 for (i = obj->interfaces; i; i = i->next) {
354 Interface *iface = i->data;
356 if (object_is_type(OBJECT(iface), typename)) {
357 return OBJECT(iface);
361 /* Check if obj is an interface and its containing object is a direct
362 * ancestor of typename */
363 if (object_is_type(obj, TYPE_INTERFACE)) {
364 Interface *iface = INTERFACE(obj);
366 if (object_is_type(iface->obj, typename)) {
367 return iface->obj;
371 return NULL;
375 static void register_interface(void)
377 static TypeInfo interface_info = {
378 .name = TYPE_INTERFACE,
379 .instance_size = sizeof(Interface),
380 .abstract = true,
383 type_register_static(&interface_info);
386 device_init(register_interface);
388 Object *object_dynamic_cast_assert(Object *obj, const char *typename)
390 Object *inst;
392 inst = object_dynamic_cast(obj, typename);
394 if (!inst) {
395 fprintf(stderr, "Object %p is not an instance of type %s\n",
396 obj, typename);
397 abort();
400 return inst;
403 ObjectClass *object_class_dynamic_cast(ObjectClass *class,
404 const char *typename)
406 TypeImpl *target_type = type_get_by_name(typename);
407 TypeImpl *type = class->type;
409 while (type) {
410 if (type == target_type) {
411 return class;
414 type = type_get_parent(type);
417 return NULL;
420 ObjectClass *object_class_dynamic_cast_assert(ObjectClass *class,
421 const char *typename)
423 ObjectClass *ret = object_class_dynamic_cast(class, typename);
425 if (!ret) {
426 fprintf(stderr, "Object %p is not an instance of type %s\n",
427 class, typename);
428 abort();
431 return ret;
434 const char *object_get_typename(Object *obj)
436 return obj->class->type->name;
439 ObjectClass *object_get_class(Object *obj)
441 return obj->class;
444 const char *object_class_get_name(ObjectClass *klass)
446 return klass->type->name;
449 ObjectClass *object_class_by_name(const char *typename)
451 TypeImpl *type = type_get_by_name(typename);
453 if (!type) {
454 return NULL;
457 type_class_init(type);
459 return type->class;
462 typedef struct OCFData
464 void (*fn)(ObjectClass *klass, void *opaque);
465 void *opaque;
466 } OCFData;
468 static void object_class_foreach_tramp(gpointer key, gpointer value,
469 gpointer opaque)
471 OCFData *data = opaque;
472 TypeImpl *type = value;
474 type_class_init(type);
476 data->fn(value, type->class);
479 void object_class_foreach(void (*fn)(ObjectClass *klass, void *opaque),
480 void *opaque)
482 OCFData data = { fn, opaque };
484 g_hash_table_foreach(type_table_get(), object_class_foreach_tramp, &data);