summary refs log tree commit diff stats
path: root/qapi
diff options
context:
space:
mode:
Diffstat (limited to 'qapi')
-rw-r--r--qapi/opts-visitor.c4
-rw-r--r--qapi/qapi-dealloc-visitor.c47
-rw-r--r--qapi/qapi-visit-core.c12
-rw-r--r--qapi/qmp-input-visitor.c11
-rw-r--r--qapi/qmp-output-visitor.c23
-rw-r--r--qapi/string-input-visitor.c7
-rw-r--r--qapi/string-output-visitor.c5
7 files changed, 42 insertions, 67 deletions
diff --git a/qapi/opts-visitor.c b/qapi/opts-visitor.c
index 4cf1cf885b..dcfbf92faf 100644
--- a/qapi/opts-visitor.c
+++ b/qapi/opts-visitor.c
@@ -180,7 +180,7 @@ opts_check_struct(Visitor *v, Error **errp)
 
 
 static void
-opts_end_struct(Visitor *v)
+opts_end_struct(Visitor *v, void **obj)
 {
     OptsVisitor *ov = to_ov(v);
 
@@ -273,7 +273,7 @@ opts_next_list(Visitor *v, GenericList *tail, size_t size)
 
 
 static void
-opts_end_list(Visitor *v)
+opts_end_list(Visitor *v, void **obj)
 {
     OptsVisitor *ov = to_ov(v);
 
diff --git a/qapi/qapi-dealloc-visitor.c b/qapi/qapi-dealloc-visitor.c
index cd68b55a1a..9391dea203 100644
--- a/qapi/qapi-dealloc-visitor.c
+++ b/qapi/qapi-dealloc-visitor.c
@@ -19,53 +19,18 @@
 #include "qapi/qmp/types.h"
 #include "qapi/visitor-impl.h"
 
-typedef struct StackEntry
-{
-    void *value;
-    QTAILQ_ENTRY(StackEntry) node;
-} StackEntry;
-
 struct QapiDeallocVisitor
 {
     Visitor visitor;
-    QTAILQ_HEAD(, StackEntry) stack;
 };
 
-static QapiDeallocVisitor *to_qov(Visitor *v)
-{
-    return container_of(v, QapiDeallocVisitor, visitor);
-}
-
-static void qapi_dealloc_push(QapiDeallocVisitor *qov, void *value)
-{
-    StackEntry *e = g_malloc0(sizeof(*e));
-
-    e->value = value;
-
-    QTAILQ_INSERT_HEAD(&qov->stack, e, node);
-}
-
-static void *qapi_dealloc_pop(QapiDeallocVisitor *qov)
-{
-    StackEntry *e = QTAILQ_FIRST(&qov->stack);
-    QObject *value;
-    QTAILQ_REMOVE(&qov->stack, e, node);
-    value = e->value;
-    g_free(e);
-    return value;
-}
-
 static void qapi_dealloc_start_struct(Visitor *v, const char *name, void **obj,
                                       size_t unused, Error **errp)
 {
-    QapiDeallocVisitor *qov = to_qov(v);
-    qapi_dealloc_push(qov, obj);
 }
 
-static void qapi_dealloc_end_struct(Visitor *v)
+static void qapi_dealloc_end_struct(Visitor *v, void **obj)
 {
-    QapiDeallocVisitor *qov = to_qov(v);
-    void **obj = qapi_dealloc_pop(qov);
     if (obj) {
         g_free(*obj);
     }
@@ -75,14 +40,10 @@ static void qapi_dealloc_start_alternate(Visitor *v, const char *name,
                                          GenericAlternate **obj, size_t size,
                                          bool promote_int, Error **errp)
 {
-    QapiDeallocVisitor *qov = to_qov(v);
-    qapi_dealloc_push(qov, obj);
 }
 
-static void qapi_dealloc_end_alternate(Visitor *v)
+static void qapi_dealloc_end_alternate(Visitor *v, void **obj)
 {
-    QapiDeallocVisitor *qov = to_qov(v);
-    void **obj = qapi_dealloc_pop(qov);
     if (obj) {
         g_free(*obj);
     }
@@ -102,7 +63,7 @@ static GenericList *qapi_dealloc_next_list(Visitor *v, GenericList *tail,
     return next;
 }
 
-static void qapi_dealloc_end_list(Visitor *v)
+static void qapi_dealloc_end_list(Visitor *v, void **obj)
 {
 }
 
@@ -178,7 +139,5 @@ QapiDeallocVisitor *qapi_dealloc_visitor_new(void)
     v->visitor.type_any = qapi_dealloc_type_anything;
     v->visitor.type_null = qapi_dealloc_type_null;
 
-    QTAILQ_INIT(&v->stack);
-
     return v;
 }
diff --git a/qapi/qapi-visit-core.c b/qapi/qapi-visit-core.c
index eada4676a2..dba11c66a7 100644
--- a/qapi/qapi-visit-core.c
+++ b/qapi/qapi-visit-core.c
@@ -43,9 +43,9 @@ void visit_check_struct(Visitor *v, Error **errp)
     }
 }
 
-void visit_end_struct(Visitor *v)
+void visit_end_struct(Visitor *v, void **obj)
 {
-    v->end_struct(v);
+    v->end_struct(v, obj);
 }
 
 void visit_start_list(Visitor *v, const char *name, GenericList **list,
@@ -67,9 +67,9 @@ GenericList *visit_next_list(Visitor *v, GenericList *tail, size_t size)
     return v->next_list(v, tail, size);
 }
 
-void visit_end_list(Visitor *v)
+void visit_end_list(Visitor *v, void **obj)
 {
-    v->end_list(v);
+    v->end_list(v, obj);
 }
 
 void visit_start_alternate(Visitor *v, const char *name,
@@ -89,10 +89,10 @@ void visit_start_alternate(Visitor *v, const char *name,
     error_propagate(errp, err);
 }
 
-void visit_end_alternate(Visitor *v)
+void visit_end_alternate(Visitor *v, void **obj)
 {
     if (v->end_alternate) {
-        v->end_alternate(v);
+        v->end_alternate(v, obj);
     }
 }
 
diff --git a/qapi/qmp-input-visitor.c b/qapi/qmp-input-visitor.c
index aea90a1378..e16b4b0725 100644
--- a/qapi/qmp-input-visitor.c
+++ b/qapi/qmp-input-visitor.c
@@ -26,6 +26,7 @@
 typedef struct StackObject
 {
     QObject *obj; /* Object being visited */
+    void *qapi; /* sanity check that caller uses same pointer */
 
     GHashTable *h;           /* If obj is dict: unvisited keys */
     const QListEntry *entry; /* If obj is list: unvisited tail */
@@ -96,7 +97,7 @@ static void qdict_add_key(const char *key, QObject *obj, void *opaque)
 }
 
 static const QListEntry *qmp_input_push(QmpInputVisitor *qiv, QObject *obj,
-                                        Error **errp)
+                                        void *qapi, Error **errp)
 {
     GHashTable *h;
     StackObject *tos = &qiv->stack[qiv->nb_stack];
@@ -108,6 +109,7 @@ static const QListEntry *qmp_input_push(QmpInputVisitor *qiv, QObject *obj,
     }
 
     tos->obj = obj;
+    tos->qapi = qapi;
     assert(!tos->h);
     assert(!tos->entry);
 
@@ -145,12 +147,13 @@ static void qmp_input_check_struct(Visitor *v, Error **errp)
     }
 }
 
-static void qmp_input_pop(Visitor *v)
+static void qmp_input_pop(Visitor *v, void **obj)
 {
     QmpInputVisitor *qiv = to_qiv(v);
     StackObject *tos = &qiv->stack[qiv->nb_stack - 1];
 
     assert(qiv->nb_stack > 0);
+    assert(tos->qapi == obj);
 
     if (qiv->strict) {
         GHashTable * const top_ht = qiv->stack[qiv->nb_stack - 1].h;
@@ -179,7 +182,7 @@ static void qmp_input_start_struct(Visitor *v, const char *name, void **obj,
         return;
     }
 
-    qmp_input_push(qiv, qobj, &err);
+    qmp_input_push(qiv, qobj, obj, &err);
     if (err) {
         error_propagate(errp, err);
         return;
@@ -207,7 +210,7 @@ static void qmp_input_start_list(Visitor *v, const char *name,
         return;
     }
 
-    entry = qmp_input_push(qiv, qobj, errp);
+    entry = qmp_input_push(qiv, qobj, list, errp);
     if (list) {
         if (entry) {
             *list = g_malloc0(size);
diff --git a/qapi/qmp-output-visitor.c b/qapi/qmp-output-visitor.c
index 4d3cf78333..dca893584d 100644
--- a/qapi/qmp-output-visitor.c
+++ b/qapi/qmp-output-visitor.c
@@ -22,6 +22,7 @@
 typedef struct QStackEntry
 {
     QObject *value;
+    void *qapi; /* sanity check that caller uses same pointer */
     QTAILQ_ENTRY(QStackEntry) node;
 } QStackEntry;
 
@@ -36,7 +37,8 @@ struct QmpOutputVisitor
 
 #define qmp_output_add(qov, name, value) \
     qmp_output_add_obj(qov, name, QOBJECT(value))
-#define qmp_output_push(qov, value) qmp_output_push_obj(qov, QOBJECT(value))
+#define qmp_output_push(qov, value, qapi) \
+    qmp_output_push_obj(qov, QOBJECT(value), qapi)
 
 static QmpOutputVisitor *to_qov(Visitor *v)
 {
@@ -44,23 +46,26 @@ static QmpOutputVisitor *to_qov(Visitor *v)
 }
 
 /* Push @value onto the stack of current QObjects being built */
-static void qmp_output_push_obj(QmpOutputVisitor *qov, QObject *value)
+static void qmp_output_push_obj(QmpOutputVisitor *qov, QObject *value,
+                                void *qapi)
 {
     QStackEntry *e = g_malloc0(sizeof(*e));
 
     assert(qov->root);
     assert(value);
     e->value = value;
+    e->qapi = qapi;
     QTAILQ_INSERT_HEAD(&qov->stack, e, node);
 }
 
 /* Pop a value off the stack of QObjects being built, and return it. */
-static QObject *qmp_output_pop(QmpOutputVisitor *qov)
+static QObject *qmp_output_pop(QmpOutputVisitor *qov, void *qapi)
 {
     QStackEntry *e = QTAILQ_FIRST(&qov->stack);
     QObject *value;
 
     assert(e);
+    assert(e->qapi == qapi);
     QTAILQ_REMOVE(&qov->stack, e, node);
     value = e->value;
     assert(value);
@@ -104,13 +109,13 @@ static void qmp_output_start_struct(Visitor *v, const char *name, void **obj,
     QDict *dict = qdict_new();
 
     qmp_output_add(qov, name, dict);
-    qmp_output_push(qov, dict);
+    qmp_output_push(qov, dict, obj);
 }
 
-static void qmp_output_end_struct(Visitor *v)
+static void qmp_output_end_struct(Visitor *v, void **obj)
 {
     QmpOutputVisitor *qov = to_qov(v);
-    QObject *value = qmp_output_pop(qov);
+    QObject *value = qmp_output_pop(qov, obj);
     assert(qobject_type(value) == QTYPE_QDICT);
 }
 
@@ -122,7 +127,7 @@ static void qmp_output_start_list(Visitor *v, const char *name,
     QList *list = qlist_new();
 
     qmp_output_add(qov, name, list);
-    qmp_output_push(qov, list);
+    qmp_output_push(qov, list, listp);
 }
 
 static GenericList *qmp_output_next_list(Visitor *v, GenericList *tail,
@@ -131,10 +136,10 @@ static GenericList *qmp_output_next_list(Visitor *v, GenericList *tail,
     return tail->next;
 }
 
-static void qmp_output_end_list(Visitor *v)
+static void qmp_output_end_list(Visitor *v, void **obj)
 {
     QmpOutputVisitor *qov = to_qov(v);
-    QObject *value = qmp_output_pop(qov);
+    QObject *value = qmp_output_pop(qov, obj);
     assert(qobject_type(value) == QTYPE_QLIST);
 }
 
diff --git a/qapi/string-input-visitor.c b/qapi/string-input-visitor.c
index 0690abb7de..d7f3c2bd1e 100644
--- a/qapi/string-input-visitor.c
+++ b/qapi/string-input-visitor.c
@@ -30,6 +30,7 @@ struct StringInputVisitor
     int64_t cur;
 
     const char *string;
+    void *list; /* Only needed for sanity checking the caller */
 };
 
 static StringInputVisitor *to_siv(Visitor *v)
@@ -120,6 +121,7 @@ start_list(Visitor *v, const char *name, GenericList **list, size_t size,
 
     /* We don't support visits without a list */
     assert(list);
+    siv->list = list;
 
     if (parse_str(siv, name, errp) < 0) {
         *list = NULL;
@@ -168,8 +170,11 @@ static GenericList *next_list(Visitor *v, GenericList *tail, size_t size)
     return tail->next;
 }
 
-static void end_list(Visitor *v)
+static void end_list(Visitor *v, void **obj)
 {
+    StringInputVisitor *siv = to_siv(v);
+
+    assert(siv->list == obj);
 }
 
 static void parse_type_int64(Visitor *v, const char *name, int64_t *obj,
diff --git a/qapi/string-output-visitor.c b/qapi/string-output-visitor.c
index c6f01f9f9c..bdc0fd0be4 100644
--- a/qapi/string-output-visitor.c
+++ b/qapi/string-output-visitor.c
@@ -64,6 +64,7 @@ struct StringOutputVisitor
         uint64_t u;
     } range_start, range_end;
     GList *ranges;
+    void *list; /* Only needed for sanity checking the caller */
 };
 
 static StringOutputVisitor *to_sov(Visitor *v)
@@ -274,6 +275,7 @@ start_list(Visitor *v, const char *name, GenericList **list, size_t size,
     assert(sov->list_mode == LM_NONE);
     /* We don't support visits without a list */
     assert(list);
+    sov->list = list;
     /* List handling is only needed if there are at least two elements */
     if (*list && (*list)->next) {
         sov->list_mode = LM_STARTED;
@@ -291,10 +293,11 @@ static GenericList *next_list(Visitor *v, GenericList *tail, size_t size)
     return ret;
 }
 
-static void end_list(Visitor *v)
+static void end_list(Visitor *v, void **obj)
 {
     StringOutputVisitor *sov = to_sov(v);
 
+    assert(sov->list == obj);
     assert(sov->list_mode == LM_STARTED ||
            sov->list_mode == LM_END ||
            sov->list_mode == LM_NONE ||