Donate to e Foundation | Murena handsets with /e/OS | Own a part of Murena! Learn more

Commit 36db1e2b authored by Henri Chataing's avatar Henri Chataing
Browse files

pdl: Specialize Field::Fixed into FixedScalar and FixedEnum

There existed an implicit assumption that width, value and
enum_id, tag_id were mutually exclusive in the Field::Fixed
case.
This change makes the assumption explicit by modiyfing
the AST to add specialized cases.

Test: cargo build && cargo test
Change-Id: Ib51f61ad2cd39f8686ad9d94a6699cf2b3b318e7
parent 1fb992a2
Loading
Loading
Loading
Loading
+8 −7
Original line number Diff line number Diff line
@@ -85,13 +85,14 @@ def parse_fields(data):
            width_or_enum = g(f'{g(integer, "width")}|{g(identifier, "enum_id")}')
            value_or_tag = g(f'{g(integer, "value")}|{g(identifier, "tag_id")}')
            m = re.match(rule(f' = {value_or_tag} : {width_or_enum}'), rest)
            fields.append({
                'kind': 'fixed_field',
                'width': int(m['width'], 0) if 'width' in m.groupdict() else None,
                'value': int(m['value'], 0) if 'value' in m.groupdict() else None,
                'enum_id': m['enum_id'],
                'tag_id': m['tag_id'],
            })
            fixed_field = {'kind': 'fixed_field'}
            if 'width' in m.groupdict():
                fixed_field['width'] = int(m['width'], 0)
                fixed_field['value'] = int(m['value'], 0)
            else:
                fixed_field['enum_id'] = m['enum_id']
                fixed_field['tag_id'] = m['tag_id']
            fields.append(fixed_field)
        elif name == '_reserved_':
            m = re.match(rule(f' : {g(integer, "width")}'), rest)
            fields.append({'kind': 'reserved_field', 'width': int(m['width'], 0)})
+7 −8
Original line number Diff line number Diff line
@@ -91,12 +91,9 @@ pub enum FieldDesc {
    #[serde(rename = "payload_field")]
    Payload { size_modifier: Option<String> },
    #[serde(rename = "fixed_field")]
    Fixed {
        width: Option<usize>,
        value: Option<usize>,
        enum_id: Option<String>,
        tag_id: Option<String>,
    },
    FixedScalar { width: usize, value: usize },
    #[serde(rename = "fixed_field")]
    FixedEnum { enum_id: String, tag_id: String },
    #[serde(rename = "reserved_field")]
    Reserved { width: usize },
    #[serde(rename = "array_field")]
@@ -277,7 +274,8 @@ impl<A: Annotation> Field<A> {
            | FieldDesc::ElementSize { .. }
            | FieldDesc::Body
            | FieldDesc::Payload { .. }
            | FieldDesc::Fixed { .. }
            | FieldDesc::FixedScalar { .. }
            | FieldDesc::FixedEnum { .. }
            | FieldDesc::Reserved { .. }
            | FieldDesc::Group { .. } => None,
            FieldDesc::Array { id, .. }
@@ -291,7 +289,8 @@ impl<A: Annotation> Field<A> {
            FieldDesc::Size { .. }
            | FieldDesc::Count { .. }
            | FieldDesc::ElementSize { .. }
            | FieldDesc::Fixed { .. }
            | FieldDesc::FixedScalar { .. }
            | FieldDesc::FixedEnum { .. }
            | FieldDesc::Reserved { .. }
            | FieldDesc::Scalar { .. } => true,
            FieldDesc::Typedef { type_id, .. } => {
+6 −6
Original line number Diff line number Diff line
@@ -159,12 +159,12 @@ fn compute_getters<'a>(
                    .insert(ComputedOffsetId::FieldOffset(id), ComputedOffset::Alias(curr_pos_id));
                ComputedOffset::ConstantPlusOffsetInBits(curr_pos_id, *width as i64)
            }
            ast::FieldDesc::Fixed { width, enum_id, .. } => {
                let offset = match (width, enum_id) {
                    (Some(width), _) => *width,
                    (_, Some(enum_id)) => schema.enums[enum_id.as_str()].width,
                    _ => unreachable!(),
                };
            ast::FieldDesc::FixedScalar { width, .. } => {
                let offset = *width;
                ComputedOffset::ConstantPlusOffsetInBits(curr_pos_id, offset as i64)
            }
            ast::FieldDesc::FixedEnum { enum_id, .. } => {
                let offset = schema.enums[enum_id.as_str()].width;
                ComputedOffset::ConstantPlusOffsetInBits(curr_pos_id, offset as i64)
            }
            ast::FieldDesc::Size { field_id, width } => {
+4 −2
Original line number Diff line number Diff line
@@ -42,7 +42,8 @@ pub fn generate_packet(
        match &field.desc {
            ast::FieldDesc::Padding { .. }
            | ast::FieldDesc::Reserved { .. }
            | ast::FieldDesc::Fixed { .. }
            | ast::FieldDesc::FixedScalar { .. }
            | ast::FieldDesc::FixedEnum { .. }
            | ast::FieldDesc::ElementSize { .. }
            | ast::FieldDesc::Count { .. }
            | ast::FieldDesc::Size { .. } => {
@@ -222,7 +223,8 @@ pub fn generate_packet(
        | ast::FieldDesc::Count { .. }
        | ast::FieldDesc::ElementSize { .. }
        | ast::FieldDesc::Body
        | ast::FieldDesc::Fixed { .. }
        | ast::FieldDesc::FixedScalar { .. }
        | ast::FieldDesc::FixedEnum { .. }
        | ast::FieldDesc::Reserved { .. } => {
            quote! {}
        }
+14 −14
Original line number Diff line number Diff line
@@ -35,7 +35,8 @@ pub fn generate_packet_serializer(
            match &field.desc {
                ast::FieldDesc::Padding { .. }
                | ast::FieldDesc::Reserved { .. }
                | ast::FieldDesc::Fixed { .. }
                | ast::FieldDesc::FixedScalar { .. }
                | ast::FieldDesc::FixedEnum { .. }
                | ast::FieldDesc::ElementSize { .. }
                | ast::FieldDesc::Count { .. }
                | ast::FieldDesc::Size { .. } => {
@@ -166,24 +167,23 @@ pub fn generate_packet_serializer(
                let field_ident = format_ident!("{id}");
                quote! { writer.write_bits(#width, || Ok(self.#field_ident))?; }
            }
            ast::FieldDesc::Fixed { width, enum_id, value, tag_id } => {
                let width = if let Some(width) = width {
                    quote! { #width }
                } else if let Some(enum_id) = enum_id {
            ast::FieldDesc::FixedScalar { width, value } => {
                let width = quote! { #width };
                let value = {
                    let value = *value as u64;
                    quote! { #value }
                };
                quote!{ writer.write_bits(#width, || Ok(#value))?; }
            }
            ast::FieldDesc::FixedEnum { enum_id, tag_id } => {
                let width = {
                    let width = schema.enums[enum_id.as_str()].width;
                    quote! { #width }
                } else {
                    unreachable!()
                };
                let value = if let Some(tag_id) = tag_id {
                    let enum_ident = format_ident!("{}", enum_id.as_ref().unwrap());
                let value = {
                    let enum_ident = format_ident!("{}", enum_id);
                    let tag_ident = format_ident!("{tag_id}");
                    quote! { #enum_ident::#tag_ident.value() }
                } else if let Some(value) = value {
                    let value = *value as u64;
                    quote! { #value }
                } else {
                    unreachable!()
                };
                quote!{ writer.write_bits(#width, || Ok(#value))?; }
            }
Loading