mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-02-02 04:21:03 +00:00
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:
parent
66def00922
commit
f93438ba43
|
@ -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;
|
||||
|
|
|
@ -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 {
|
||||
|
|
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
|
@ -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,
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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)
|
||||
|
|
|
@ -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;
|
||||
|
||||
|
|
|
@ -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);
|
||||
|
||||
|
|
|
@ -319,6 +319,7 @@ fdef.write(mcgen('''
|
|||
prefix=prefix))
|
||||
|
||||
fdecl.write(mcgen('''
|
||||
#include "qapi/qmp/qobject.h"
|
||||
#include "unicorn/platform.h"
|
||||
'''))
|
||||
|
||||
|
|
|
@ -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()
|
||||
|
||||
|
|
Loading…
Reference in a new issue