mirror of
https://github.com/yuzu-emu/unicorn
synced 2024-11-25 01:48:16 +00:00
qapi-event: Utilize implicit struct visits
Rather than generate inline per-member visits, take advantage of the 'visit_type_FOO_members()' function for emitting events. This is possible now that implicit structs can be visited like any other. Generated code shrinks accordingly; by initializing a struct based on parameters, through a new gen_param_var() helper, like: |@@ -338,6 +250,9 @@ void qapi_event_send_block_job_error(con | QMPEventFuncEmit emit = qmp_event_get_func_emit(); | QmpOutputVisitor *qov; | Visitor *v; |+ q_obj_BLOCK_JOB_ERROR_arg param = { |+ (char *)device, operation, action |+ }; | | if (!emit) { | return; @@ -351,19 +266,7 @@ void qapi_event_send_block_job_error(con | if (err) { | goto out; | } |- visit_type_str(v, "device", (char **)&device, &err); |- if (err) { |- goto out_obj; |- } |- visit_type_IoOperationType(v, "operation", &operation, &err); |- if (err) { |- goto out_obj; |- } |- visit_type_BlockErrorAction(v, "action", &action, &err); |- if (err) { |- goto out_obj; |- } |-out_obj: |+ visit_type_q_obj_BLOCK_JOB_ERROR_arg_members(v, ¶m, &err); | visit_end_struct(v, err ? NULL : &err); Notice that the initialization of 'param' has to cast away const (just as the old gen_visit_members() had to do): we can't change the signature of the user function (which uses 'const char *'), but have to assign it to a non-const QAPI object (which requires 'char *'). While touching this, document with a FIXME comment that there is still a potential collision between QMP members and our choice of local variable names within qapi_event_send_FOO(). This patch also paves the way for some followup simplifications in the generator, in subsequent patches. Backports commit 0949e95b48e30715e157cabbc59dcb0ed912d3ff from qemu
This commit is contained in:
parent
eb4b02705a
commit
a86b89f166
1 changed files with 38 additions and 10 deletions
|
@ -27,7 +27,37 @@ def gen_event_send_decl(name, arg_type):
|
|||
proto=gen_event_send_proto(name, arg_type))
|
||||
|
||||
|
||||
# Declare and initialize an object 'qapi' using parameters from gen_params()
|
||||
def gen_param_var(typ):
|
||||
assert not typ.variants
|
||||
ret = mcgen('''
|
||||
%(c_name)s param = {
|
||||
''',
|
||||
c_name=typ.c_name())
|
||||
sep = ' '
|
||||
for memb in typ.members:
|
||||
ret += sep
|
||||
sep = ', '
|
||||
if memb.optional:
|
||||
ret += 'has_' + c_name(memb.name) + sep
|
||||
if memb.type.name == 'str':
|
||||
# Cast away const added in gen_params()
|
||||
ret += '(char *)'
|
||||
ret += c_name(memb.name)
|
||||
ret += mcgen('''
|
||||
|
||||
};
|
||||
''')
|
||||
return ret
|
||||
|
||||
|
||||
def gen_event_send(name, arg_type):
|
||||
# FIXME: Our declaration of local variables (and of 'errp' in the
|
||||
# parameter list) can collide with exploded members of the event's
|
||||
# data type passed in as parameters. If this collision ever hits in
|
||||
# practice, we can rename our local variables with a leading _ prefix,
|
||||
# or split the code into a wrapper function that creates a boxed
|
||||
# 'param' object then calls another to do the real work.
|
||||
ret = mcgen('''
|
||||
|
||||
%(proto)s
|
||||
|
@ -43,10 +73,11 @@ def gen_event_send(name, arg_type):
|
|||
ret += mcgen('''
|
||||
QmpOutputVisitor *qov;
|
||||
Visitor *v;
|
||||
|
||||
''')
|
||||
ret += gen_param_var(arg_type)
|
||||
|
||||
ret += mcgen('''
|
||||
|
||||
emit = qmp_event_get_func_emit();
|
||||
if (!emit) {
|
||||
return;
|
||||
|
@ -60,24 +91,21 @@ def gen_event_send(name, arg_type):
|
|||
if arg_type and arg_type.members:
|
||||
ret += mcgen('''
|
||||
qov = qmp_output_visitor_new();
|
||||
|
||||
v = qmp_output_get_visitor(qov);
|
||||
|
||||
visit_start_struct(v, "%(name)s", NULL, 0, &err);
|
||||
''',
|
||||
name=name)
|
||||
ret += gen_err_check()
|
||||
ret += gen_visit_members(arg_type.members, need_cast=True,
|
||||
label='out_obj')
|
||||
ret += mcgen('''
|
||||
out_obj:
|
||||
if (err) {
|
||||
goto out;
|
||||
}
|
||||
visit_type_%(c_name)s_members(v, ¶m, &err);
|
||||
visit_end_struct(v, err ? NULL : &err);
|
||||
if (err) {
|
||||
goto out;
|
||||
}
|
||||
|
||||
qdict_put_obj(qmp, "data", qmp_output_get_qobject(qov));
|
||||
''')
|
||||
''',
|
||||
name=name, c_name=arg_type.c_name())
|
||||
|
||||
ret += mcgen('''
|
||||
emit(%(c_enum)s, qmp, &err);
|
||||
|
|
Loading…
Reference in a new issue