mirror of
https://github.com/yuzu-emu/unicorn.git
synced 2025-05-03 18:16:26 +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);
|
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)
|
void qapi_free_boolList(boolList *obj)
|
||||||
{
|
{
|
||||||
QapiDeallocVisitor *md;
|
QapiDeallocVisitor *md;
|
||||||
|
|
|
@ -16,12 +16,23 @@
|
||||||
#ifndef QAPI_TYPES_H
|
#ifndef QAPI_TYPES_H
|
||||||
#define QAPI_TYPES_H
|
#define QAPI_TYPES_H
|
||||||
|
|
||||||
|
#include "qapi/qmp/qobject.h"
|
||||||
#include "unicorn/platform.h"
|
#include "unicorn/platform.h"
|
||||||
|
|
||||||
#ifndef QAPI_TYPES_BUILTIN
|
#ifndef QAPI_TYPES_BUILTIN
|
||||||
#define 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;
|
typedef struct boolList boolList;
|
||||||
struct boolList {
|
struct boolList {
|
||||||
union {
|
union {
|
||||||
|
|
|
@ -141,6 +141,30 @@ out:
|
||||||
error_propagate(errp, err);
|
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)
|
void visit_type_boolList(Visitor *m, boolList **obj, const char *name, Error **errp)
|
||||||
{
|
{
|
||||||
Error *err = NULL;
|
Error *err = NULL;
|
||||||
|
|
|
@ -23,46 +23,28 @@
|
||||||
#ifndef QAPI_VISIT_BUILTIN
|
#ifndef QAPI_VISIT_BUILTIN
|
||||||
#define 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_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_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_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_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_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_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_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_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_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_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_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_uint64List(Visitor *m, uint64List **obj, const char *name, Error **errp);
|
||||||
|
|
||||||
void visit_type_uint8List(Visitor *m, uint8List **obj, const char *name, Error **errp);
|
void visit_type_uint8List(Visitor *m, uint8List **obj, const char *name, Error **errp);
|
||||||
|
|
||||||
#endif /* QAPI_VISIT_BUILTIN */
|
#endif /* QAPI_VISIT_BUILTIN */
|
||||||
|
|
||||||
|
|
||||||
void visit_type_ErrorClass(Visitor *m, ErrorClass *obj, const char *name, Error **errp);
|
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_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_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_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_X86CPURegister32(Visitor *m, X86CPURegister32 *obj, const char *name, Error **errp);
|
||||||
|
|
||||||
void visit_type_X86CPURegister32List(Visitor *m, X86CPURegister32List **obj, const char *name, Error **errp);
|
void visit_type_X86CPURegister32List(Visitor *m, X86CPURegister32List **obj, const char *name, Error **errp);
|
||||||
|
|
||||||
#endif
|
#endif
|
||||||
|
|
|
@ -48,6 +48,8 @@ struct Visitor
|
||||||
void (*type_str)(Visitor *v, char **obj, const char *name, Error **errp);
|
void (*type_str)(Visitor *v, char **obj, const char *name, Error **errp);
|
||||||
void (*type_number)(Visitor *v, double *obj, const char *name,
|
void (*type_number)(Visitor *v, double *obj, const char *name,
|
||||||
Error **errp);
|
Error **errp);
|
||||||
|
void (*type_any)(Visitor *v, QObject **obj, const char *name,
|
||||||
|
Error **errp);
|
||||||
|
|
||||||
/* May be NULL */
|
/* May be NULL */
|
||||||
void (*optional)(Visitor *v, bool *present, const char *name,
|
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_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_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_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);
|
bool visit_start_union(Visitor *v, bool data_present, Error **errp);
|
||||||
void visit_end_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,
|
static void qapi_dealloc_type_size(Visitor *v, uint64_t *obj, const char *name,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
|
@ -222,6 +230,7 @@ QapiDeallocVisitor *qapi_dealloc_visitor_new(void)
|
||||||
v->visitor.type_bool = qapi_dealloc_type_bool;
|
v->visitor.type_bool = qapi_dealloc_type_bool;
|
||||||
v->visitor.type_str = qapi_dealloc_type_str;
|
v->visitor.type_str = qapi_dealloc_type_str;
|
||||||
v->visitor.type_number = qapi_dealloc_type_number;
|
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.type_size = qapi_dealloc_type_size;
|
||||||
v->visitor.start_union = qapi_dealloc_start_union;
|
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);
|
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[],
|
void output_type_enum(Visitor *v, int *obj, const char * const strings[],
|
||||||
const char *kind, const char *name,
|
const char *kind, const char *name,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
|
|
|
@ -306,6 +306,16 @@ static void qmp_input_type_number(Visitor *v, double *obj, const char *name,
|
||||||
"number");
|
"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,
|
static void qmp_input_optional(Visitor *v, bool *present, const char *name,
|
||||||
Error **errp)
|
Error **errp)
|
||||||
{
|
{
|
||||||
|
@ -350,6 +360,7 @@ QmpInputVisitor *qmp_input_visitor_new(QObject *obj)
|
||||||
v->visitor.type_bool = qmp_input_type_bool;
|
v->visitor.type_bool = qmp_input_type_bool;
|
||||||
v->visitor.type_str = qmp_input_type_str;
|
v->visitor.type_str = qmp_input_type_str;
|
||||||
v->visitor.type_number = qmp_input_type_number;
|
v->visitor.type_number = qmp_input_type_number;
|
||||||
|
v->visitor.type_any = qmp_input_type_any;
|
||||||
v->visitor.optional = qmp_input_optional;
|
v->visitor.optional = qmp_input_optional;
|
||||||
v->visitor.get_next_type = qmp_input_get_next_type;
|
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));
|
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 *qmp_output_get_qobject(QmpOutputVisitor *qov)
|
||||||
{
|
{
|
||||||
QObject *obj = qmp_output_first(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_bool = qmp_output_type_bool;
|
||||||
v->visitor.type_str = qmp_output_type_str;
|
v->visitor.type_str = qmp_output_type_str;
|
||||||
v->visitor.type_number = qmp_output_type_number;
|
v->visitor.type_number = qmp_output_type_number;
|
||||||
|
v->visitor.type_any = qmp_output_type_any;
|
||||||
|
|
||||||
QTAILQ_INIT(&v->stack);
|
QTAILQ_INIT(&v->stack);
|
||||||
|
|
||||||
|
|
|
@ -319,6 +319,7 @@ fdef.write(mcgen('''
|
||||||
prefix=prefix))
|
prefix=prefix))
|
||||||
|
|
||||||
fdecl.write(mcgen('''
|
fdecl.write(mcgen('''
|
||||||
|
#include "qapi/qmp/qobject.h"
|
||||||
#include "unicorn/platform.h"
|
#include "unicorn/platform.h"
|
||||||
'''))
|
'''))
|
||||||
|
|
||||||
|
|
|
@ -33,6 +33,7 @@ builtin_types = {
|
||||||
'uint32': 'QTYPE_QINT',
|
'uint32': 'QTYPE_QINT',
|
||||||
'uint64': 'QTYPE_QINT',
|
'uint64': 'QTYPE_QINT',
|
||||||
'size': 'QTYPE_QINT',
|
'size': 'QTYPE_QINT',
|
||||||
|
'any': None, # any qtype_code possible, actually
|
||||||
}
|
}
|
||||||
|
|
||||||
# Whitelist of commands allowed to return a non-dictionary
|
# Whitelist of commands allowed to return a non-dictionary
|
||||||
|
@ -1099,7 +1100,6 @@ class QAPISchema(object):
|
||||||
def _def_builtin_type(self, name, json_type, c_type, c_null):
|
def _def_builtin_type(self, name, json_type, c_type, c_null):
|
||||||
self._def_entity(QAPISchemaBuiltinType(name, json_type,
|
self._def_entity(QAPISchemaBuiltinType(name, json_type,
|
||||||
c_type, c_null))
|
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):
|
def _def_predefineds(self):
|
||||||
|
@ -1116,8 +1116,9 @@ class QAPISchema(object):
|
||||||
('uint64', 'int', 'uint64_t', '0'),
|
('uint64', 'int', 'uint64_t', '0'),
|
||||||
('size', 'int', 'uint64_t', '0'),
|
('size', 'int', 'uint64_t', '0'),
|
||||||
('bool', 'boolean', 'bool', 'false'),
|
('bool', 'boolean', 'bool', 'false'),
|
||||||
('**', 'value', None, None)]:
|
('any', 'value', 'QObject' + pointer_suffix, 'NULL')]:
|
||||||
self._def_builtin_type(*t)
|
self._def_builtin_type(*t)
|
||||||
|
self._entity_dict['**'] = self.lookup_type('any') # TODO drop this alias
|
||||||
|
|
||||||
def _make_implicit_enum_type(self, name, values):
|
def _make_implicit_enum_type(self, name, values):
|
||||||
name = name + 'Kind'
|
name = name + 'Kind'
|
||||||
|
@ -1267,6 +1268,8 @@ class QAPISchema(object):
|
||||||
def visit(self, visitor):
|
def visit(self, visitor):
|
||||||
visitor.visit_begin(self)
|
visitor.visit_begin(self)
|
||||||
for name in sorted(self._entity_dict.keys()):
|
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)
|
self._entity_dict[name].visit(visitor)
|
||||||
visitor.visit_end()
|
visitor.visit_end()
|
||||||
|
|
||||||
|
|
Loading…
Reference in a new issue