qemu-devel
[Top][All Lists]
Advanced

[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index]

[RFC v3 07/32] scripts/qapi: generate CABI dump for C types


From: marcandre . lureau
Subject: [RFC v3 07/32] scripts/qapi: generate CABI dump for C types
Date: Tue, 7 Sep 2021 16:19:18 +0400

From: Marc-André Lureau <marcandre.lureau@redhat.com>

With type units, generate the C ABI dump functions (as blocks protected
with QAPI_CABI define). The top-level function is qapi_cabi(), and it
calls the sub-modules dump functions.

Signed-off-by: Marc-André Lureau <marcandre.lureau@redhat.com>
---
 scripts/qapi/types.py | 58 ++++++++++++++++++++++++++++++++++++++++++-
 1 file changed, 57 insertions(+), 1 deletion(-)

diff --git a/scripts/qapi/types.py b/scripts/qapi/types.py
index 831294fe42..7ac3645d18 100644
--- a/scripts/qapi/types.py
+++ b/scripts/qapi/types.py
@@ -13,8 +13,15 @@
 # See the COPYING file in the top-level directory.
 """
 
-from typing import List, Optional
+from pathlib import Path
+from typing import (
+    Dict,
+    List,
+    Optional,
+    Set,
+)
 
+from .cabi import CABI, CABIEnum, gen_object_cabi
 from .common import c_enum_const, c_name, mcgen
 from .gen import QAPISchemaModularCVisitor, ifcontext
 from .schema import (
@@ -22,6 +29,7 @@
     QAPISchemaEnumMember,
     QAPISchemaFeature,
     QAPISchemaIfCond,
+    QAPISchemaModule,
     QAPISchemaObjectType,
     QAPISchemaObjectTypeMember,
     QAPISchemaType,
@@ -265,6 +273,13 @@ def __init__(self, prefix: str):
         super().__init__(
             prefix, 'qapi-types', ' * Schema-defined QAPI types',
             ' * Built-in QAPI types', __doc__)
+        self._cabi_functions: List[str] = []
+        self._cabi_functions_called: Set[str] = set()
+        self._cabi: Dict[str, CABI] = {}
+
+    def _cabi_add(self, cabis: List[CABI]) -> None:
+        for cabi in cabis:
+            self._cabi.setdefault(cabi.name, cabi)
 
     def _begin_builtin_module(self) -> None:
         self._genc.preamble_add(mcgen('''
@@ -295,6 +310,43 @@ def visit_begin(self, schema: QAPISchema) -> None:
         # gen_object() is recursive, ensure it doesn't visit the empty type
         objects_seen.add(schema.the_empty_object_type.name)
 
+    def _get_qapi_cabi_fn(self, name: str) -> str:
+        fn_name = 'qapi_cabi'
+        if QAPISchemaModule.is_builtin_module(name):
+            fn_name += '_builtin'
+        elif name != self._main_module:
+            name = Path(name).stem
+            fn_name += '_' + c_name(name)
+        return fn_name
+
+    def visit_include(self, name: str, info: Optional[QAPISourceInfo]) -> None:
+        super().visit_include(name, info)
+        cabi_fn = self._get_qapi_cabi_fn(name)
+        if cabi_fn not in self._cabi_functions_called:
+            self._cabi_functions.append(cabi_fn)
+
+    def visit_module_end(self, name: str) -> None:
+        cabi_gen = "".join(f'    {fn}();\n' for fn in self._cabi_functions)
+        self._cabi_functions_called |= set(self._cabi_functions)
+        self._cabi_functions = []
+        cabi_gen += "".join([c.gen_c() for _, c in sorted(self._cabi.items())])
+        self._cabi = {}
+        fn_name = self._get_qapi_cabi_fn(name)
+        self._genh.add(mcgen('''
+
+#ifdef QAPI_CABI
+void %(fn_name)s(void);
+#endif
+''', fn_name=fn_name))
+        self._genc.add(mcgen('''
+
+#ifdef QAPI_CABI
+void %(fn_name)s(void) {
+%(cabi_gen)s
+}
+#endif
+''', fn_name=fn_name, cabi_gen=cabi_gen))
+
     def _gen_type_cleanup(self, name: str) -> None:
         self._genh.add(gen_type_cleanup_decl(name))
         self._genc.add(gen_type_cleanup(name))
@@ -309,6 +361,7 @@ def visit_enum_type(self,
         with ifcontext(ifcond, self._genh, self._genc):
             self._genh.preamble_add(gen_enum(name, members, prefix))
             self._genc.add(gen_enum_lookup(name, members, prefix))
+        self._cabi_add([CABIEnum(name, ifcond, members, prefix)])
 
     def visit_array_type(self,
                          name: str,
@@ -334,6 +387,7 @@ def visit_object_type(self,
         with ifcontext(ifcond, self._genh):
             self._genh.preamble_add(gen_fwd_object_or_array(name))
         self._genh.add(gen_object(name, ifcond, base, members, variants))
+        self._cabi_add(gen_object_cabi(name, ifcond, base, members, variants))
         with ifcontext(ifcond, self._genh, self._genc):
             if base and not base.is_implicit():
                 self._genh.add(gen_upcast(name, base))
@@ -353,6 +407,8 @@ def visit_alternate_type(self,
             self._genh.preamble_add(gen_fwd_object_or_array(name))
         self._genh.add(gen_object(name, ifcond, None,
                                   [variants.tag_member], variants))
+        self._cabi_add(gen_object_cabi(name, ifcond, None,
+                                       [variants.tag_member], variants))
         with ifcontext(ifcond, self._genh, self._genc):
             self._gen_type_cleanup(name)
 
-- 
2.33.0.113.g6c40894d24




reply via email to

[Prev in Thread] Current Thread [Next in Thread]