qapi: Introduce a first class 'any' type

It's first class, because unlike '**', it actually works, i.e. doesn't
require 'gen': false.

'**' will go away next.

Backports commit 28770e057f265a4e70bcbdfc2447cce7b5f2dc19 from qemu
This commit is contained in:
Markus Armbruster 2018-02-19 17:45:25 -05:00 committed by Lioncash
parent 66def00922
commit f93438ba43
No known key found for this signature in database
GPG key ID: 4E3C3CC1031BA9C7
12 changed files with 96 additions and 22 deletions

View file

@ -100,6 +100,21 @@ void qapi_free_X86CPURegister32List(X86CPURegister32List *obj)
qapi_dealloc_visitor_cleanup(md);
}
void qapi_free_anyList(anyList *obj)
{
QapiDeallocVisitor *md;
Visitor *v;
if (!obj) {
return;
}
md = qapi_dealloc_visitor_new();
v = qapi_dealloc_get_visitor(md);
visit_type_anyList(v, &obj, NULL, NULL);
qapi_dealloc_visitor_cleanup(md);
}
void qapi_free_boolList(boolList *obj)
{
QapiDeallocVisitor *md;

View file

@ -16,12 +16,23 @@
#ifndef QAPI_TYPES_H
#define QAPI_TYPES_H
#include "qapi/qmp/qobject.h"
#include "unicorn/platform.h"
#ifndef QAPI_TYPES_BUILTIN
#define QAPI_TYPES_BUILTIN
typedef struct anyList anyList;
struct anyList {
union {
QObject *value;
uint64_t padding;
};
struct anyList *next;
};
void qapi_free_anyList(anyList *obj);
typedef struct boolList boolList;
struct boolList {
union {

View file

@ -141,6 +141,30 @@ out:
error_propagate(errp, err);
}
void visit_type_anyList(Visitor *m, anyList **obj, const char *name, Error **errp)
{
Error *err = NULL;
GenericList *i, **prev;
visit_start_list(m, name, &err);
if (err) {
goto out;
}
for (prev = (GenericList **)obj;
!err && (i = visit_next_list(m, prev)) != NULL;
prev = &i) {
anyList *native_i = (anyList *)i;
visit_type_any(m, &native_i->value, NULL, &err);
}
error_propagate(errp, err);
err = NULL;
visit_end_list(m);
out:
error_propagate(errp, err);
}
void visit_type_boolList(Visitor *m, boolList **obj, const char *name, Error **errp)
{
Error *err = NULL;

View file

@ -23,46 +23,28 @@
#ifndef QAPI_VISIT_BUILTIN
#define QAPI_VISIT_BUILTIN
void visit_type_anyList(Visitor *m, anyList **obj, const char *name, Error **errp);
void visit_type_boolList(Visitor *m, boolList **obj, const char *name, Error **errp);
void visit_type_int16List(Visitor *m, int16List **obj, const char *name, Error **errp);
void visit_type_int32List(Visitor *m, int32List **obj, const char *name, Error **errp);
void visit_type_int64List(Visitor *m, int64List **obj, const char *name, Error **errp);
void visit_type_int8List(Visitor *m, int8List **obj, const char *name, Error **errp);
void visit_type_intList(Visitor *m, intList **obj, const char *name, Error **errp);
void visit_type_numberList(Visitor *m, numberList **obj, const char *name, Error **errp);
void visit_type_sizeList(Visitor *m, sizeList **obj, const char *name, Error **errp);
void visit_type_strList(Visitor *m, strList **obj, const char *name, Error **errp);
void visit_type_uint16List(Visitor *m, uint16List **obj, const char *name, Error **errp);
void visit_type_uint32List(Visitor *m, uint32List **obj, const char *name, Error **errp);
void visit_type_uint64List(Visitor *m, uint64List **obj, const char *name, Error **errp);
void visit_type_uint8List(Visitor *m, uint8List **obj, const char *name, Error **errp);
#endif /* QAPI_VISIT_BUILTIN */
void visit_type_ErrorClass(Visitor *m, ErrorClass *obj, const char *name, Error **errp);
void visit_type_ErrorClassList(Visitor *m, ErrorClassList **obj, const char *name, Error **errp);
void visit_type_X86CPUFeatureWordInfo(Visitor *m, X86CPUFeatureWordInfo **obj, const char *name, Error **errp);
void visit_type_X86CPUFeatureWordInfoList(Visitor *m, X86CPUFeatureWordInfoList **obj, const char *name, Error **errp);
void visit_type_X86CPURegister32(Visitor *m, X86CPURegister32 *obj, const char *name, Error **errp);
void visit_type_X86CPURegister32List(Visitor *m, X86CPURegister32List **obj, const char *name, Error **errp);
#endif

View file

@ -48,6 +48,8 @@ struct Visitor
void (*type_str)(Visitor *v, char **obj, const char *name, Error **errp);
void (*type_number)(Visitor *v, double *obj, const char *name,
Error **errp);
void (*type_any)(Visitor *v, QObject **obj, const char *name,
Error **errp);
/* May be NULL */
void (*optional)(Visitor *v, bool *present, const char *name,

View file

@ -58,6 +58,7 @@ void visit_type_size(Visitor *v, uint64_t *obj, const char *name, Error **errp);
void visit_type_bool(Visitor *v, bool *obj, const char *name, Error **errp);
void visit_type_str(Visitor *v, char **obj, const char *name, Error **errp);
void visit_type_number(Visitor *v, double *obj, const char *name, Error **errp);
void visit_type_any(Visitor *v, QObject **obj, const char *name, Error **errp);
bool visit_start_union(Visitor *v, bool data_present, Error **errp);
void visit_end_union(Visitor *v, bool data_present, Error **errp);

View file

@ -156,6 +156,14 @@ static void qapi_dealloc_type_number(Visitor *v, double *obj, const char *name,
{
}
static void qapi_dealloc_type_anything(Visitor *v, QObject **obj,
const char *name, Error **errp)
{
if (obj) {
qobject_decref(*obj);
}
}
static void qapi_dealloc_type_size(Visitor *v, uint64_t *obj, const char *name,
Error **errp)
{
@ -222,6 +230,7 @@ QapiDeallocVisitor *qapi_dealloc_visitor_new(void)
v->visitor.type_bool = qapi_dealloc_type_bool;
v->visitor.type_str = qapi_dealloc_type_str;
v->visitor.type_number = qapi_dealloc_type_number;
v->visitor.type_any = qapi_dealloc_type_anything;
v->visitor.type_size = qapi_dealloc_type_size;
v->visitor.start_union = qapi_dealloc_start_union;

View file

@ -255,6 +255,12 @@ void visit_type_number(Visitor *v, double *obj, const char *name, Error **errp)
v->type_number(v, obj, name, errp);
}
void visit_type_any(Visitor *v, QObject **obj, const char *name,
Error **errp)
{
v->type_any(v, obj, name, errp);
}
void output_type_enum(Visitor *v, int *obj, const char * const strings[],
const char *kind, const char *name,
Error **errp)

View file

@ -306,6 +306,16 @@ static void qmp_input_type_number(Visitor *v, double *obj, const char *name,
"number");
}
static void qmp_input_type_any(Visitor *v, QObject **obj, const char *name,
Error **errp)
{
QmpInputVisitor *qiv = to_qiv(v);
QObject *qobj = qmp_input_get_object(qiv, name, true);
qobject_incref(qobj);
*obj = qobj;
}
static void qmp_input_optional(Visitor *v, bool *present, const char *name,
Error **errp)
{
@ -350,6 +360,7 @@ QmpInputVisitor *qmp_input_visitor_new(QObject *obj)
v->visitor.type_bool = qmp_input_type_bool;
v->visitor.type_str = qmp_input_type_str;
v->visitor.type_number = qmp_input_type_number;
v->visitor.type_any = qmp_input_type_any;
v->visitor.optional = qmp_input_optional;
v->visitor.get_next_type = qmp_input_get_next_type;

View file

@ -195,6 +195,14 @@ static void qmp_output_type_number(Visitor *v, double *obj, const char *name,
qmp_output_add(qov, name, qfloat_from_double(*obj));
}
static void qmp_output_type_any(Visitor *v, QObject **obj, const char *name,
Error **errp)
{
QmpOutputVisitor *qov = to_qov(v);
qobject_incref(*obj);
qmp_output_add_obj(qov, name, *obj);
}
QObject *qmp_output_get_qobject(QmpOutputVisitor *qov)
{
QObject *obj = qmp_output_first(qov);
@ -243,6 +251,7 @@ QmpOutputVisitor *qmp_output_visitor_new(void)
v->visitor.type_bool = qmp_output_type_bool;
v->visitor.type_str = qmp_output_type_str;
v->visitor.type_number = qmp_output_type_number;
v->visitor.type_any = qmp_output_type_any;
QTAILQ_INIT(&v->stack);

View file

@ -319,6 +319,7 @@ fdef.write(mcgen('''
prefix=prefix))
fdecl.write(mcgen('''
#include "qapi/qmp/qobject.h"
#include "unicorn/platform.h"
'''))

View file

@ -33,6 +33,7 @@ builtin_types = {
'uint32': 'QTYPE_QINT',
'uint64': 'QTYPE_QINT',
'size': 'QTYPE_QINT',
'any': None, # any qtype_code possible, actually
}
# Whitelist of commands allowed to return a non-dictionary
@ -1099,8 +1100,7 @@ class QAPISchema(object):
def _def_builtin_type(self, name, json_type, c_type, c_null):
self._def_entity(QAPISchemaBuiltinType(name, json_type,
c_type, c_null))
if name != '**':
self._make_array_type(name) # TODO really needed?
self._make_array_type(name) # TODO really needed?
def _def_predefineds(self):
for t in [('str', 'string', 'char' + pointer_suffix, 'NULL'),
@ -1116,8 +1116,9 @@ class QAPISchema(object):
('uint64', 'int', 'uint64_t', '0'),
('size', 'int', 'uint64_t', '0'),
('bool', 'boolean', 'bool', 'false'),
('**', 'value', None, None)]:
('any', 'value', 'QObject' + pointer_suffix, 'NULL')]:
self._def_builtin_type(*t)
self._entity_dict['**'] = self.lookup_type('any') # TODO drop this alias
def _make_implicit_enum_type(self, name, values):
name = name + 'Kind'
@ -1267,6 +1268,8 @@ class QAPISchema(object):
def visit(self, visitor):
visitor.visit_begin(self)
for name in sorted(self._entity_dict.keys()):
if self._entity_dict[name].name != name:
continue # ignore alias TODO drop alias and remove
self._entity_dict[name].visit(visitor)
visitor.visit_end()