[RFC PATCH] block-coroutine-wrapper: support generating wrappers for functions without arguments

Fiona Ebner posted 1 patch 5 months, 3 weeks ago
Patches applied successfully (tree, apply log)
git fetch https://github.com/patchew-project/qemu tags/patchew/20240604091208.39677-1-f.ebner@proxmox.com
Maintainers: John Snow <jsnow@redhat.com>, Cleber Rosa <crosa@redhat.com>
scripts/block-coroutine-wrapper.py | 17 +++++++++++++----
1 file changed, 13 insertions(+), 4 deletions(-)
[RFC PATCH] block-coroutine-wrapper: support generating wrappers for functions without arguments
Posted by Fiona Ebner 5 months, 3 weeks ago
Signed-off-by: Fiona Ebner <f.ebner@proxmox.com>
---

An alternative would be to detect whether the argument list is 'void'
in FuncDecl's __init__, assign the empty list to self.args there and
special case based on that in the rest of the code.

Not super happy about the introduction of the 'void_value' parameter,
but the different callers seem to make something like it necessary.
Could be avoided if there were a nice way to map a format which
contains no other keys besides '{name}' to the empty list if the
argument's 'name' is 'None'. At least until there is a format that
contains both '{name}' and another key which would require special
handling again.

The generated code unfortunately does contain a few extra blank lines.
Avoiding that would require turning some of the (currently static)
formatting surrounding gen_block() dynamic based upon whether the
argument list is 'void'.

Happy about any feedback/suggestions!

 scripts/block-coroutine-wrapper.py | 17 +++++++++++++----
 1 file changed, 13 insertions(+), 4 deletions(-)

diff --git a/scripts/block-coroutine-wrapper.py b/scripts/block-coroutine-wrapper.py
index dbbde99e39..533f6dbe12 100644
--- a/scripts/block-coroutine-wrapper.py
+++ b/scripts/block-coroutine-wrapper.py
@@ -54,6 +54,11 @@ class ParamDecl:
                           r')')
 
     def __init__(self, param_decl: str) -> None:
+        if param_decl.strip() == 'void':
+            self.decl = 'void'
+            self.type = 'void'
+            self.name = None
+            return
         m = self.param_re.match(param_decl.strip())
         if m is None:
             raise ValueError(f'Wrong parameter declaration: "{param_decl}"')
@@ -114,10 +119,14 @@ def gen_ctx(self, prefix: str = '') -> str:
         else:
             return 'qemu_get_aio_context()'
 
-    def gen_list(self, format: str) -> str:
+    def gen_list(self, format: str, void_value='') -> str:
+        if len(self.args) == 1 and self.args[0].type == 'void':
+            return void_value
         return ', '.join(format.format_map(arg.__dict__) for arg in self.args)
 
     def gen_block(self, format: str) -> str:
+        if len(self.args) == 1 and self.args[0].type == 'void':
+            return ''
         return '\n'.join(format.format_map(arg.__dict__) for arg in self.args)
 
 
@@ -158,7 +167,7 @@ def create_mixed_wrapper(func: FuncDecl) -> str:
     graph_assume_lock = 'assume_graph_lock();' if func.graph_rdlock else ''
 
     return f"""\
-{func.return_type} {func.name}({ func.gen_list('{decl}') })
+{func.return_type} {func.name}({ func.gen_list('{decl}', 'void') })
 {{
     if (qemu_in_coroutine()) {{
         {graph_assume_lock}
@@ -186,7 +195,7 @@ def create_co_wrapper(func: FuncDecl) -> str:
     name = func.target_name
     struct_name = func.struct_name
     return f"""\
-{func.return_type} {func.name}({ func.gen_list('{decl}') })
+{func.return_type} {func.name}({ func.gen_list('{decl}', 'void') })
 {{
     {struct_name} s = {{
         .poll_state.ctx = qemu_get_current_aio_context(),
@@ -284,7 +293,7 @@ def gen_no_co_wrapper(func: FuncDecl) -> str:
     aio_co_wake(s->co);
 }}
 
-{func.return_type} coroutine_fn {func.name}({ func.gen_list('{decl}') })
+{func.return_type} coroutine_fn {func.name}({ func.gen_list('{decl}', 'void') })
 {{
     {struct_name} s = {{
         .co = qemu_coroutine_self(),
-- 
2.39.2