diff --git a/msvc/unicorn/unicorn/unicorn.vcxproj b/msvc/unicorn/unicorn/unicorn.vcxproj
index 1eb39037..60a86f7b 100644
--- a/msvc/unicorn/unicorn/unicorn.vcxproj
+++ b/msvc/unicorn/unicorn/unicorn.vcxproj
@@ -212,6 +212,7 @@ copy $(SolutionDir)..\include\unicorn\*.h $(SolutionDir)distro\include\unicorn\
+
diff --git a/msvc/unicorn/unicorn/unicorn.vcxproj.filters b/msvc/unicorn/unicorn/unicorn.vcxproj.filters
index fcc0b331..06ccc6d4 100644
--- a/msvc/unicorn/unicorn/unicorn.vcxproj.filters
+++ b/msvc/unicorn/unicorn/unicorn.vcxproj.filters
@@ -101,6 +101,9 @@
qemu\qobject
+
+ qemu\qobject
+
qemu\qobject
diff --git a/msvc/unicorn/unicorn_static/unicorn_static.vcxproj b/msvc/unicorn/unicorn_static/unicorn_static.vcxproj
index 9417890a..b97f308b 100644
--- a/msvc/unicorn/unicorn_static/unicorn_static.vcxproj
+++ b/msvc/unicorn/unicorn_static/unicorn_static.vcxproj
@@ -40,6 +40,7 @@
+
diff --git a/msvc/unicorn/unicorn_static/unicorn_static.vcxproj.filters b/msvc/unicorn/unicorn_static/unicorn_static.vcxproj.filters
index 3a3ed5e8..e5b77683 100644
--- a/msvc/unicorn/unicorn_static/unicorn_static.vcxproj.filters
+++ b/msvc/unicorn/unicorn_static/unicorn_static.vcxproj.filters
@@ -135,6 +135,9 @@
qemu\qobject
+
+ qemu\qobject
+
qemu\qobject
diff --git a/qemu/include/qapi/qmp/qbool.h b/qemu/include/qapi/qmp/qbool.h
index 31677d04..e7aecd43 100644
--- a/qemu/include/qapi/qmp/qbool.h
+++ b/qemu/include/qapi/qmp/qbool.h
@@ -25,5 +25,6 @@ typedef struct QBool {
QBool *qbool_from_bool(bool value);
bool qbool_get_bool(const QBool *qb);
QBool *qobject_to_qbool(const QObject *obj);
+void qbool_destroy_obj(QObject *obj);
#endif /* QBOOL_H */
diff --git a/qemu/include/qapi/qmp/qdict.h b/qemu/include/qapi/qmp/qdict.h
index 9e8d3df5..91668713 100644
--- a/qemu/include/qapi/qmp/qdict.h
+++ b/qemu/include/qapi/qmp/qdict.h
@@ -47,6 +47,7 @@ void qdict_iter(const QDict *qdict,
void *opaque);
const QDictEntry *qdict_first(const QDict *qdict);
const QDictEntry *qdict_next(const QDict *qdict, const QDictEntry *entry);
+void qdict_destroy_obj(QObject *obj);
/* Helper to qdict_put_obj(), accepts any object */
#define qdict_put(qdict, key, obj) \
diff --git a/qemu/include/qapi/qmp/qfloat.h b/qemu/include/qapi/qmp/qfloat.h
index b068ed3f..93f66307 100644
--- a/qemu/include/qapi/qmp/qfloat.h
+++ b/qemu/include/qapi/qmp/qfloat.h
@@ -25,5 +25,6 @@ typedef struct QFloat {
QFloat *qfloat_from_double(double value);
double qfloat_get_double(const QFloat *qi);
QFloat *qobject_to_qfloat(const QObject *obj);
+void qfloat_destroy_obj(QObject *obj);
#endif /* QFLOAT_H */
diff --git a/qemu/include/qapi/qmp/qint.h b/qemu/include/qapi/qmp/qint.h
index 0150b7e4..e239e2c8 100644
--- a/qemu/include/qapi/qmp/qint.h
+++ b/qemu/include/qapi/qmp/qint.h
@@ -24,5 +24,6 @@ typedef struct QInt {
QInt *qint_from_int(int64_t value);
int64_t qint_get_int(const QInt *qi);
QInt *qobject_to_qint(const QObject *obj);
+void qint_destroy_obj(QObject *obj);
#endif /* QINT_H */
diff --git a/qemu/include/qapi/qmp/qlist.h b/qemu/include/qapi/qmp/qlist.h
index 6cc4831d..b6f91afb 100644
--- a/qemu/include/qapi/qmp/qlist.h
+++ b/qemu/include/qapi/qmp/qlist.h
@@ -49,6 +49,7 @@ QObject *qlist_peek(QList *qlist);
int qlist_empty(const QList *qlist);
size_t qlist_size(const QList *qlist);
QList *qobject_to_qlist(const QObject *obj);
+void qlist_destroy_obj(QObject *obj);
static inline const QListEntry *qlist_first(const QList *qlist)
{
diff --git a/qemu/include/qapi/qmp/qobject.h b/qemu/include/qapi/qmp/qobject.h
index 3262e8d6..0643cde2 100644
--- a/qemu/include/qapi/qmp/qobject.h
+++ b/qemu/include/qapi/qmp/qobject.h
@@ -48,15 +48,8 @@ typedef enum {
QTYPE_MAX,
} qtype_code;
-struct QObject;
-
-typedef struct QType {
- qtype_code code;
- void (*destroy)(struct QObject *);
-} QType;
-
typedef struct QObject {
- const QType *type;
+ qtype_code type;
size_t refcnt;
} QObject;
@@ -76,9 +69,12 @@ typedef struct QObject {
qobject_decref(obj ? QOBJECT(obj) : NULL)
/* Initialize an object to default values */
-#define QOBJECT_INIT(obj, qtype_type) \
- obj->base.refcnt = 1; \
- obj->base.type = qtype_type
+static inline void qobject_init(QObject *obj, qtype_code type)
+{
+ assert(QTYPE_NONE < type && type < QTYPE_MAX);
+ obj->refcnt = 1;
+ obj->type = type;
+}
/**
* qobject_incref(): Increment QObject's reference count
@@ -89,6 +85,11 @@ static inline void qobject_incref(QObject *obj)
obj->refcnt++;
}
+/**
+ * qobject_destroy(): Free resources used by the object
+ */
+void qobject_destroy(QObject *obj);
+
/**
* qobject_decref(): Decrement QObject's reference count, deallocate
* when it reaches zero
@@ -97,9 +98,7 @@ static inline void qobject_decref(QObject *obj)
{
assert(!obj || obj->refcnt);
if (obj && --obj->refcnt == 0) {
- assert(obj->type != NULL);
- assert(obj->type->destroy != NULL);
- obj->type->destroy(obj);
+ qobject_destroy(obj);
}
}
@@ -108,8 +107,8 @@ static inline void qobject_decref(QObject *obj)
*/
static inline qtype_code qobject_type(const QObject *obj)
{
- assert(obj->type != NULL);
- return obj->type->code;
+ assert(QTYPE_NONE < obj->type && obj->type < QTYPE_MAX);
+ return obj->type;
}
extern QObject qnull_;
diff --git a/qemu/include/qapi/qmp/qstring.h b/qemu/include/qapi/qmp/qstring.h
index 734e9127..e4618ba0 100644
--- a/qemu/include/qapi/qmp/qstring.h
+++ b/qemu/include/qapi/qmp/qstring.h
@@ -32,5 +32,6 @@ void qstring_append_int(QString *qstring, int64_t value);
void qstring_append(QString *qstring, const char *str);
void qstring_append_chr(QString *qstring, int c);
QString *qobject_to_qstring(const QObject *obj);
+void qstring_destroy_obj(QObject *obj);
#endif /* QSTRING_H */
diff --git a/qemu/qobject/Makefile.objs b/qemu/qobject/Makefile.objs
index 53714657..50bae58d 100644
--- a/qemu/qobject/Makefile.objs
+++ b/qemu/qobject/Makefile.objs
@@ -1 +1 @@
-util-obj-y = qint.o qnull.o qstring.o qdict.o qlist.o qfloat.o qbool.o
+util-obj-y = qint.o qnull.o qobject.o qstring.o qdict.o qlist.o qfloat.o qbool.o
diff --git a/qemu/qobject/qbool.c b/qemu/qobject/qbool.c
index 9c6acb13..0606bbd2 100644
--- a/qemu/qobject/qbool.c
+++ b/qemu/qobject/qbool.c
@@ -16,13 +16,6 @@
#include "qapi/qmp/qobject.h"
#include "qemu-common.h"
-static void qbool_destroy_obj(QObject *obj);
-
-static const QType qbool_type = {
- QTYPE_QBOOL,
- qbool_destroy_obj,
-};
-
/**
* qbool_from_bool(): Create a new QBool from a bool
*
@@ -33,8 +26,8 @@ QBool *qbool_from_bool(bool value)
QBool *qb;
qb = g_malloc(sizeof(*qb));
+ qobject_init(QOBJECT(qb), QTYPE_QBOOL);
qb->value = value;
- QOBJECT_INIT(qb, &qbool_type);
return qb;
}
@@ -62,7 +55,7 @@ QBool *qobject_to_qbool(const QObject *obj)
* qbool_destroy_obj(): Free all memory allocated by a
* QBool object
*/
-static void qbool_destroy_obj(QObject *obj)
+void qbool_destroy_obj(QObject *obj)
{
assert(obj != NULL);
g_free(qobject_to_qbool(obj));
diff --git a/qemu/qobject/qdict.c b/qemu/qobject/qdict.c
index 5b54d8df..58b1b314 100644
--- a/qemu/qobject/qdict.c
+++ b/qemu/qobject/qdict.c
@@ -20,13 +20,6 @@
#include "qemu/queue.h"
#include "qemu-common.h"
-static void qdict_destroy_obj(QObject *obj);
-
-static const QType qdict_type = {
- QTYPE_QDICT,
- qdict_destroy_obj,
-};
-
/**
* qdict_new(): Create a new QDict
*
@@ -37,7 +30,7 @@ QDict *qdict_new(void)
QDict *qdict;
qdict = g_malloc0(sizeof(*qdict));
- QOBJECT_INIT(qdict, &qdict_type);
+ qobject_init(QOBJECT(qdict), QTYPE_QDICT);
return qdict;
}
@@ -442,7 +435,7 @@ void qdict_del(QDict *qdict, const char *key)
/**
* qdict_destroy_obj(): Free all the memory allocated by a QDict
*/
-static void qdict_destroy_obj(QObject *obj)
+void qdict_destroy_obj(QObject *obj)
{
int i;
QDict *qdict;
diff --git a/qemu/qobject/qfloat.c b/qemu/qobject/qfloat.c
index c44e3005..d5da8477 100644
--- a/qemu/qobject/qfloat.c
+++ b/qemu/qobject/qfloat.c
@@ -16,13 +16,6 @@
#include "qapi/qmp/qobject.h"
#include "qemu-common.h"
-static void qfloat_destroy_obj(QObject *obj);
-
-static const QType qfloat_type = {
- QTYPE_QFLOAT,
- qfloat_destroy_obj,
-};
-
/**
* qfloat_from_int(): Create a new QFloat from a float
*
@@ -33,8 +26,8 @@ QFloat *qfloat_from_double(double value)
QFloat *qf;
qf = g_malloc(sizeof(*qf));
+ qobject_init(QOBJECT(qf), QTYPE_QFLOAT);
qf->value = value;
- QOBJECT_INIT(qf, &qfloat_type);
return qf;
}
@@ -62,7 +55,7 @@ QFloat *qobject_to_qfloat(const QObject *obj)
* qfloat_destroy_obj(): Free all memory allocated by a
* QFloat object
*/
-static void qfloat_destroy_obj(QObject *obj)
+void qfloat_destroy_obj(QObject *obj)
{
assert(obj != NULL);
g_free(qobject_to_qfloat(obj));
diff --git a/qemu/qobject/qint.c b/qemu/qobject/qint.c
index 190994d4..d7d1b302 100644
--- a/qemu/qobject/qint.c
+++ b/qemu/qobject/qint.c
@@ -15,13 +15,6 @@
#include "qapi/qmp/qobject.h"
#include "qemu-common.h"
-static void qint_destroy_obj(QObject *obj);
-
-static const QType qint_type = {
- QTYPE_QINT,
- qint_destroy_obj,
-};
-
/**
* qint_from_int(): Create a new QInt from an int64_t
*
@@ -32,8 +25,8 @@ QInt *qint_from_int(int64_t value)
QInt *qi;
qi = g_malloc(sizeof(*qi));
+ qobject_init(QOBJECT(qi), QTYPE_QINT);
qi->value = value;
- QOBJECT_INIT(qi, &qint_type);
return qi;
}
@@ -61,7 +54,7 @@ QInt *qobject_to_qint(const QObject *obj)
* qint_destroy_obj(): Free all memory allocated by a
* QInt object
*/
-static void qint_destroy_obj(QObject *obj)
+void qint_destroy_obj(QObject *obj)
{
assert(obj != NULL);
g_free(qobject_to_qint(obj));
diff --git a/qemu/qobject/qlist.c b/qemu/qobject/qlist.c
index a7701127..1ec74de2 100644
--- a/qemu/qobject/qlist.c
+++ b/qemu/qobject/qlist.c
@@ -16,13 +16,6 @@
#include "qemu/queue.h"
#include "qemu-common.h"
-static void qlist_destroy_obj(QObject *obj);
-
-static const QType qlist_type = {
- QTYPE_QLIST,
- qlist_destroy_obj,
-};
-
/**
* qlist_new(): Create a new QList
*
@@ -33,8 +26,8 @@ QList *qlist_new(void)
QList *qlist;
qlist = g_malloc(sizeof(*qlist));
+ qobject_init(QOBJECT(qlist), QTYPE_QLIST);
QTAILQ_INIT(&qlist->head);
- QOBJECT_INIT(qlist, &qlist_type);
return qlist;
}
@@ -152,7 +145,7 @@ QList *qobject_to_qlist(const QObject *obj)
/**
* qlist_destroy_obj(): Free all the memory allocated by a QList
*/
-static void qlist_destroy_obj(QObject *obj)
+void qlist_destroy_obj(QObject *obj)
{
QList *qlist;
QListEntry *entry, *next_entry;
diff --git a/qemu/qobject/qnull.c b/qemu/qobject/qnull.c
index 68f425a0..69cd1b34 100644
--- a/qemu/qobject/qnull.c
+++ b/qemu/qobject/qnull.c
@@ -13,17 +13,7 @@
#include "qemu-common.h"
#include "qapi/qmp/qobject.h"
-static void qnull_destroy_obj(QObject *obj)
-{
- assert(0);
-}
-
-static const QType qnull_type = {
- QTYPE_QNULL,
- qnull_destroy_obj,
-};
-
QObject qnull_ = {
- &qnull_type,
+ QTYPE_QNULL,
1,
};
diff --git a/qemu/qobject/qobject.c b/qemu/qobject/qobject.c
new file mode 100644
index 00000000..1a6845e3
--- /dev/null
+++ b/qemu/qobject/qobject.c
@@ -0,0 +1,34 @@
+/*
+ * QObject
+ *
+ * Copyright (C) 2015 Red Hat, Inc.
+ *
+ * This work is licensed under the terms of the GNU LGPL, version 2.1
+ * or later. See the COPYING.LIB file in the top-level directory.
+ */
+
+#include "qemu-common.h"
+#include "qapi/qmp/qbool.h"
+#include "qapi/qmp/qdict.h"
+#include "qapi/qmp/qfloat.h"
+#include "qapi/qmp/qint.h"
+#include "qapi/qmp/qlist.h"
+#include "qapi/qmp/qstring.h"
+
+static void (*qdestroy[QTYPE_MAX])(QObject *) = {
+ NULL, /* No such object exists */
+ NULL, /* qnull_ is indestructible */
+ qint_destroy_obj,
+ qstring_destroy_obj,
+ qdict_destroy_obj,
+ qlist_destroy_obj,
+ qfloat_destroy_obj,
+ qbool_destroy_obj,
+};
+
+void qobject_destroy(QObject *obj)
+{
+ assert(!obj->refcnt);
+ assert(QTYPE_QNULL < obj->type && obj->type < QTYPE_MAX);
+ qdestroy[obj->type](obj);
+}
diff --git a/qemu/qobject/qstring.c b/qemu/qobject/qstring.c
index 0a80f938..f1469dfe 100644
--- a/qemu/qobject/qstring.c
+++ b/qemu/qobject/qstring.c
@@ -15,13 +15,6 @@
#include "qapi/qmp/qstring.h"
#include "qemu-common.h"
-static void qstring_destroy_obj(QObject *obj);
-
-static const QType qstring_type = {
- QTYPE_QSTRING,
- qstring_destroy_obj,
-};
-
/**
* qstring_new(): Create a new empty QString
*
@@ -50,6 +43,7 @@ QString *qstring_from_substr(const char *str, int start, int end)
QString *qstring;
qstring = g_malloc(sizeof(*qstring));
+ qobject_init(QOBJECT(qstring), QTYPE_QSTRING);
qstring->length = end - start + 1;
qstring->capacity = qstring->length;
@@ -58,8 +52,6 @@ QString *qstring_from_substr(const char *str, int start, int end)
memcpy(qstring->string, str + start, qstring->length);
qstring->string[qstring->length] = 0;
- QOBJECT_INIT(qstring, &qstring_type);
-
return qstring;
}
@@ -139,7 +131,7 @@ const char *qstring_get_str(const QString *qstring)
* qstring_destroy_obj(): Free all memory allocated by a QString
* object
*/
-static void qstring_destroy_obj(QObject *obj)
+void qstring_destroy_obj(QObject *obj)
{
QString *qs;