|
[Date Prev][Date Next][Thread Prev][Thread Next][Date Index][Thread Index] Re: [RFC PATCH 07/25] tools/xenbindgen: Add support for structs in TOML specs
On Mon Nov 25, 2024 at 12:39 PM GMT, Teddy Astie wrote:
> Hi Alejandro,
>
> Le 15/11/2024 à 12:51, Alejandro Vallejo a écrit :
> > Signed-off-by: Alejandro Vallejo <alejandro.vallejo@xxxxxxxxx>
> > ---
> > tools/rust/xenbindgen/src/c_lang.rs | 56 ++++++++++++++++++++++++-
> > tools/rust/xenbindgen/src/spec.rs | 64 ++++++++++++++++++++++++++++-
> > 2 files changed, 117 insertions(+), 3 deletions(-)
> >
> > diff --git a/tools/rust/xenbindgen/src/c_lang.rs
> > b/tools/rust/xenbindgen/src/c_lang.rs
> > index f05e36bb362f..597e0ed41362 100644
> > --- a/tools/rust/xenbindgen/src/c_lang.rs
> > +++ b/tools/rust/xenbindgen/src/c_lang.rs
> > @@ -17,9 +17,10 @@
> >
> > use std::fmt::Write;
> >
> > -use crate::spec::OutFileDef;
> > +use crate::spec::{OutFileDef, StructDef, Typ};
> >
> > use convert_case::{Case, Casing};
> > +use log::{debug, trace};
> >
> > /// An abstract indentation level. 0 is no indentation, 1 is
> > [`INDENT_WIDTH`]
> > /// and so on.
> > @@ -29,6 +30,39 @@ struct Indentation(usize);
> > /// Default width of each level of indentation
> > const INDENT_WIDTH: usize = 4;
> >
> > +/// Create a C-compatible struct field. Without the terminating semicolon.
> > +fn structfield(typ: &Typ, name: &str) -> String {
> > + match typ {
> > + Typ::Ptr(x) => {
> > + let t: &Typ = x;
> > + format!(
> > + "XEN_GUEST_HANDLE_64({}) {name}",
> > + match t {
> > + Typ::U8 => "uint8",
> > + Typ::U16 => "uint16",
> > + Typ::U32 => "uint32",
> > + Typ::U64 => "uint64_aligned_t",
> > + Typ::I8 => "int8",
> > + Typ::I16 => "int16",
> > + Typ::I32 => "int32",
> > + Typ::I64 => "int64_aligned_t",
> > + _ => panic!("foo {t:?}"),
> > + }
> > + )
> > + }
> > + Typ::Struct(x) => format!("struct {x} {name}"),
> > + Typ::Array(x, len) => format!("{}{name}[{len}]", structfield(x,
> > "")),
> > + Typ::U8 => format!("uint8_t {name}"),
> > + Typ::U16 => format!("uint16_t {name}"),
> > + Typ::U32 => format!("uint32_t {name}"),
> > + Typ::U64 => format!("uint64_aligned_t {name}"),
> > + Typ::I8 => format!("int8_t {name}"),
> > + Typ::I16 => format!("int16_t {name}"),
> > + Typ::I32 => format!("int32_t {name}"),
> > + Typ::I64 => format!("int64_aligned_t {name}"),
> > + }
> > +}
> > +
>
> I think _t are missing in the Ptr cases (we are currently generating
> XEN_GUEST_HANDLE_64(uint8) which I don't think is valid).
It is intentional. The handles are presently missing those _t in Xen's public
headers, but that's something I'll be changing in the interest of sanity. That
way we can just recurse to the inner type.
> Aside that, wouldn't it be better to have a separate function for
> converting the type to its C representation ?
>
> Something like
>
> impl Typ { // or blanket trait
> fn c_repr(&self) -> String {
> match self {
> /* ... */
> }
> }
> }
That's roughhly what typ_rs() does, and indeed what typ_c() used to do. There's
a complication though...
>
> fn structfield(typ: &Typ, name: &str) -> String {
> format!("{} {name}", typ.c_repr());
> }
>
> We can also consider Typ::Struct or Typ::Array cases to call recursively
> to c_repr on its inner type to get its representation.
>
> That way, we can have XEN_GUEST_HANDLE_64(struct something).
Initially structfield() was typ_c() (like the Rust backend). Then arrays
happened... Size and typename surround the name of the field (e.g: uint8_t
handle[16]) so I stopped doing it like that because I thought I couldn't.
I have since then noticed I can cheat! The following two fields are identical.
Except the first one is a heck of a lot simpler to generate.
__typeof__(uint8_t[16]) handle;
uint8_t handle[16];
My latest branch simplifies all this by s/structfield/typ_c/ and using that
typeof trick.
>
> Cheers
>
> Teddy
>
>
>
> Teddy Astie | Vates XCP-ng Developer
>
> XCP-ng & Xen Orchestra - Vates solutions
>
> web: https://vates.tech
Cheers,
Alejandro
|
![]() |
Lists.xenproject.org is hosted with RackSpace, monitoring our |