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

View file

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