1
0
Fork 0
forked from wry/wry

wayland: optimize formatting of fixed-size messages

This commit is contained in:
Julian Orth 2026-03-28 22:24:54 +01:00
parent 755bfdd661
commit 9a85958479
2 changed files with 76 additions and 29 deletions

View file

@ -193,35 +193,75 @@ fn write_message<W: Write>(f: &mut W, obj: &str, message: &Message) -> Result<()
lifetime, message.camel_name, lifetime
)?;
writeln!(f, " fn format(self, fmt: &mut MsgFormatter<'_>) {{")?;
writeln!(f, " fmt.header(self.self_id, {});", uppercase)?;
fn write_fmt_expr<W: Write>(f: &mut W, prefix: &str, ty: &Type, access: &str) -> Result<()> {
let p = match ty {
Type::Id(..) => "object",
Type::U32 => "uint",
Type::I32 => "int",
Type::U64 => "u64",
Type::U64Rev => "u64_rev",
Type::OptStr => "optstr",
Type::Str | Type::BStr => "string",
Type::Fixed => "fixed",
Type::Fd => "fd",
Type::Array(..) => "binary",
Type::Pod(..) => "binary",
};
let rf = match ty {
Type::Pod(..) => "&",
_ => "",
};
writeln!(f, " {}fmt.{}({}{});", prefix, p, rf, access)?;
Ok(())
}
for field in &message.fields {
write_fmt_expr(
f,
"",
&field.val.ty.val,
&format!("self.{}", field.val.name),
)?;
if message.is_fixed_size {
writeln!(f, " fmt.data(&[")?;
writeln!(f, " self.self_id.0,")?;
writeln!(f, " {uppercase},")?;
for field in &message.fields {
let prefix = format!(" self.{}", field.val.name);
match &field.val.ty.val {
Type::Id(_, _) => writeln!(f, "{prefix}.0,")?,
Type::U32 => writeln!(f, "{prefix},")?,
Type::I32 => writeln!(f, "{prefix} as u32,")?,
Type::U64 => {
writeln!(f, " (self.{} >> 32) as u32,", field.val.name)?;
writeln!(f, "{prefix} as u32,")?;
}
Type::U64Rev => {
writeln!(f, "{prefix} as u32,")?;
writeln!(f, " (self.{} >> 32) as u32,", field.val.name)?;
}
Type::Str => unreachable!(),
Type::OptStr => unreachable!(),
Type::BStr => unreachable!(),
Type::Fixed => writeln!(f, "{prefix}.0 as u32,")?,
Type::Fd => {}
Type::Array(_) => unreachable!(),
Type::Pod(_) => unreachable!(),
}
}
writeln!(f, " ]);")?;
for field in &message.fields {
if let Type::Fd = &field.val.ty.val {
writeln!(f, " fmt.fd(self.{});", field.val.name)?;
}
}
} else {
writeln!(f, " fmt.header(self.self_id, {});", uppercase)?;
fn write_fmt_expr<W: Write>(
f: &mut W,
prefix: &str,
ty: &Type,
access: &str,
) -> Result<()> {
let p = match ty {
Type::Id(..) => "object",
Type::U32 => "uint",
Type::I32 => "int",
Type::U64 => "u64",
Type::U64Rev => "u64_rev",
Type::OptStr => "optstr",
Type::Str | Type::BStr => "string",
Type::Fixed => "fixed",
Type::Fd => "fd",
Type::Array(..) => "binary",
Type::Pod(..) => "binary",
};
let rf = match ty {
Type::Pod(..) => "&",
_ => "",
};
writeln!(f, " {}fmt.{}({}{});", prefix, p, rf, access)?;
Ok(())
}
for field in &message.fields {
write_fmt_expr(
f,
"",
&field.val.ty.val,
&format!("self.{}", field.val.name),
)?;
}
}
writeln!(f, " }}")?;
writeln!(f, " fn id(&self) -> ObjectId {{")?;

View file

@ -33,6 +33,11 @@ impl<'a> MsgFormatter<'a> {
self.meta.write_pos += bytes.len();
}
#[inline(always)]
pub fn data(&mut self, data: &[u32]) {
self.write(uapi::as_bytes(data));
}
pub fn int(&mut self, int: i32) -> &mut Self {
self.write(uapi::as_bytes(&int));
self
@ -43,11 +48,13 @@ impl<'a> MsgFormatter<'a> {
self
}
#[expect(dead_code)]
pub fn u64(&mut self, int: u64) -> &mut Self {
self.uint((int >> 32) as u32);
self.uint(int as u32)
}
#[expect(dead_code)]
pub fn u64_rev(&mut self, int: u64) -> &mut Self {
self.uint(int as u32);
self.uint((int >> 32) as u32)