mirror of https://github.com/xemu-project/xemu.git
qapi-gen: mark coroutine QMP command functions as coroutine_fn
Coroutine commands have to be declared as coroutine_fn, but the marker does not show up in the qapi-comands-* headers; likewise, the marshaling function calls the command and therefore must be coroutine_fn. Static analysis would want coroutine_fn to match between prototype and declaration, because in principle coroutines might be compiled to a completely different calling convention. So we would like to add the marker to the header. Reviewed-by: Markus Armbruster <armbru@redhat.com> Signed-off-by: Paolo Bonzini <pbonzini@redhat.com>
This commit is contained in:
parent
dfae46c3ba
commit
cf9d4e68d7
|
@ -41,11 +41,13 @@ from .source import QAPISourceInfo
|
||||||
def gen_command_decl(name: str,
|
def gen_command_decl(name: str,
|
||||||
arg_type: Optional[QAPISchemaObjectType],
|
arg_type: Optional[QAPISchemaObjectType],
|
||||||
boxed: bool,
|
boxed: bool,
|
||||||
ret_type: Optional[QAPISchemaType]) -> str:
|
ret_type: Optional[QAPISchemaType],
|
||||||
|
coroutine: bool) -> str:
|
||||||
return mcgen('''
|
return mcgen('''
|
||||||
%(c_type)s qmp_%(c_name)s(%(params)s);
|
%(c_type)s %(coroutine_fn)sqmp_%(c_name)s(%(params)s);
|
||||||
''',
|
''',
|
||||||
c_type=(ret_type and ret_type.c_type()) or 'void',
|
c_type=(ret_type and ret_type.c_type()) or 'void',
|
||||||
|
coroutine_fn='coroutine_fn ' if coroutine else '',
|
||||||
c_name=c_name(name),
|
c_name=c_name(name),
|
||||||
params=build_params(arg_type, boxed, 'Error **errp'))
|
params=build_params(arg_type, boxed, 'Error **errp'))
|
||||||
|
|
||||||
|
@ -157,16 +159,21 @@ static void qmp_marshal_output_%(c_name)s(%(c_type)s ret_in,
|
||||||
c_type=ret_type.c_type(), c_name=ret_type.c_name())
|
c_type=ret_type.c_type(), c_name=ret_type.c_name())
|
||||||
|
|
||||||
|
|
||||||
def build_marshal_proto(name: str) -> str:
|
def build_marshal_proto(name: str,
|
||||||
return ('void qmp_marshal_%s(QDict *args, QObject **ret, Error **errp)'
|
coroutine: bool) -> str:
|
||||||
% c_name(name))
|
return ('void %(coroutine_fn)sqmp_marshal_%(c_name)s(%(params)s)' % {
|
||||||
|
'coroutine_fn': 'coroutine_fn ' if coroutine else '',
|
||||||
|
'c_name': c_name(name),
|
||||||
|
'params': 'QDict *args, QObject **ret, Error **errp',
|
||||||
|
})
|
||||||
|
|
||||||
|
|
||||||
def gen_marshal_decl(name: str) -> str:
|
def gen_marshal_decl(name: str,
|
||||||
|
coroutine: bool) -> str:
|
||||||
return mcgen('''
|
return mcgen('''
|
||||||
%(proto)s;
|
%(proto)s;
|
||||||
''',
|
''',
|
||||||
proto=build_marshal_proto(name))
|
proto=build_marshal_proto(name, coroutine))
|
||||||
|
|
||||||
|
|
||||||
def gen_trace(name: str) -> str:
|
def gen_trace(name: str) -> str:
|
||||||
|
@ -181,7 +188,8 @@ def gen_marshal(name: str,
|
||||||
arg_type: Optional[QAPISchemaObjectType],
|
arg_type: Optional[QAPISchemaObjectType],
|
||||||
boxed: bool,
|
boxed: bool,
|
||||||
ret_type: Optional[QAPISchemaType],
|
ret_type: Optional[QAPISchemaType],
|
||||||
gen_tracing: bool) -> str:
|
gen_tracing: bool,
|
||||||
|
coroutine: bool) -> str:
|
||||||
have_args = boxed or (arg_type and not arg_type.is_empty())
|
have_args = boxed or (arg_type and not arg_type.is_empty())
|
||||||
if have_args:
|
if have_args:
|
||||||
assert arg_type is not None
|
assert arg_type is not None
|
||||||
|
@ -195,7 +203,7 @@ def gen_marshal(name: str,
|
||||||
bool ok = false;
|
bool ok = false;
|
||||||
Visitor *v;
|
Visitor *v;
|
||||||
''',
|
''',
|
||||||
proto=build_marshal_proto(name))
|
proto=build_marshal_proto(name, coroutine))
|
||||||
|
|
||||||
if ret_type:
|
if ret_type:
|
||||||
ret += mcgen('''
|
ret += mcgen('''
|
||||||
|
@ -387,10 +395,11 @@ void %(c_prefix)sqmp_init_marshal(QmpCommandList *cmds)
|
||||||
self._genh, self._genc):
|
self._genh, self._genc):
|
||||||
self._genc.add(gen_marshal_output(ret_type))
|
self._genc.add(gen_marshal_output(ret_type))
|
||||||
with ifcontext(ifcond, self._genh, self._genc):
|
with ifcontext(ifcond, self._genh, self._genc):
|
||||||
self._genh.add(gen_command_decl(name, arg_type, boxed, ret_type))
|
self._genh.add(gen_command_decl(name, arg_type, boxed,
|
||||||
self._genh.add(gen_marshal_decl(name))
|
ret_type, coroutine))
|
||||||
|
self._genh.add(gen_marshal_decl(name, coroutine))
|
||||||
self._genc.add(gen_marshal(name, arg_type, boxed, ret_type,
|
self._genc.add(gen_marshal(name, arg_type, boxed, ret_type,
|
||||||
self._gen_tracing))
|
self._gen_tracing, coroutine))
|
||||||
if self._gen_tracing:
|
if self._gen_tracing:
|
||||||
self._gen_trace_events.add(gen_trace(name))
|
self._gen_trace_events.add(gen_trace(name))
|
||||||
with self._temp_module('./init'):
|
with self._temp_module('./init'):
|
||||||
|
|
Loading…
Reference in New Issue