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;