示例#1
0
 def test_field_is_not_read_only(self):
     self.assertFalse(
         ir_util.field_is_read_only(
             ir_pb2.Field(location=ir_pb2.FieldLocation())))
     self.assertFalse(
         ir_util.field_is_read_only(
             ir_pb2.Field(write_method=ir_pb2.WriteMethod())))
示例#2
0
def _add_size_virtuals(structure, type_definition):
    """Adds a $size_in_bits or $size_in_bytes virtual field to structure."""
    names = {
        ir_pb2.TypeDefinition.BIT: "$size_in_bits",
        ir_pb2.TypeDefinition.BYTE: "$size_in_bytes",
    }
    size_field_name = names[type_definition.addressable_unit]
    size_clauses = []
    for field in structure.field:
        # Virtual fields do not have a physical location, and thus do not contribute
        # to the size of the structure.
        if ir_util.field_is_virtual(field):
            continue
        size_clause = ir_pb2.Expression()
        size_clause.CopyFrom(_SIZE_CLAUSE_SKELETON)
        # Copy the appropriate clauses into `existence_condition ? start + size : 0`
        size_clause.function.args[0].CopyFrom(field.existence_condition)
        size_clause.function.args[1].function.args[0].CopyFrom(
            field.location.start)
        size_clause.function.args[1].function.args[1].CopyFrom(
            field.location.size)
        size_clauses.append(size_clause)
    size_expression = ir_pb2.Expression()
    size_expression.CopyFrom(_SIZE_SKELETON)
    size_expression.function.args.extend(size_clauses)
    _mark_as_synthetic(size_expression)
    size_field = ir_pb2.Field(
        read_transform=size_expression,
        name=ir_pb2.NameDefinition(name=ir_pb2.Word(text=size_field_name)),
        existence_condition=ir_pb2.Expression(
            boolean_constant=ir_pb2.BooleanConstant(value=True)),
        attribute=[_skip_text_output_attribute()])
    structure.field.extend([size_field])
示例#3
0
def _add_size_bound_virtuals(structure, type_definition):
    """Adds ${min,max}_size_in_{bits,bytes} virtual fields to structure."""
    names = {
        ir_pb2.TypeDefinition.BIT: ("$max_size_in_bits", "$min_size_in_bits"),
        ir_pb2.TypeDefinition.BYTE:
        ("$max_size_in_bytes", "$min_size_in_bytes"),
    }
    for name in names[type_definition.addressable_unit]:
        bound_field = ir_pb2.Field(
            read_transform=_SIZE_BOUNDS[name],
            name=ir_pb2.NameDefinition(name=ir_pb2.Word(text=name)),
            existence_condition=expression_parser.parse("true"),
            attribute=[_skip_text_output_attribute()])
        _mark_as_synthetic(bound_field.read_transform)
        structure.field.extend([bound_field])
示例#4
0
 def test_field_is_read_only(self):
     self.assertTrue(
         ir_util.field_is_read_only(
             ir_pb2.Field(write_method=ir_pb2.WriteMethod(read_only=True))))
示例#5
0
 def test_field_is_not_virtual(self):
     self.assertFalse(
         ir_util.field_is_virtual(
             ir_pb2.Field(location=ir_pb2.FieldLocation())))
示例#6
0
 def test_field_is_virtual(self):
     self.assertTrue(ir_util.field_is_virtual(ir_pb2.Field()))
示例#7
0
def _add_anonymous_aliases(structure, type_definition):
    """Adds synthetic alias fields for all fields in anonymous fields.

  This essentially completes the rewrite of this:

      struct Foo:
        0  [+4]  bits:
          0  [+1]  Flag  low
          31 [+1]  Flag  high

  Into this:

      struct Foo:
        bits EmbossReservedAnonymous0:
          [text_output: "Skip"]
          0  [+1]  Flag  low
          31 [+1]  Flag  high
        0 [+4]  EmbossReservedAnonymous0  emboss_reserved_anonymous_1
        let low = emboss_reserved_anonymous_1.low
        let high = emboss_reserved_anonymous_1.high

  Note that this pass runs very, very early -- even before symbols have been
  resolved -- so very little in ir_util will work at this point.

  Arguments:
      structure: The ir_pb2.Structure on which to synthesize fields.
      type_definition: The ir_pb2.TypeDefinition containing structure.

  Returns:
      None
  """
    new_fields = []
    for field in structure.field:
        new_fields.append(field)
        if not field.name.is_anonymous:
            continue
        field.attribute.extend([_skip_text_output_attribute()])
        for subtype in type_definition.subtype:
            if (subtype.name.name.text ==
                    field.type.atomic_type.reference.source_name[-1].text):
                field_type = subtype
                break
        else:
            assert False, (
                "Unable to find corresponding type {} for anonymous field "
                "in {}.".format(field.type.atomic_type.reference,
                                type_definition))
        anonymous_reference = ir_pb2.Reference(source_name=[field.name.name])
        anonymous_field_reference = ir_pb2.FieldReference(
            path=[anonymous_reference])
        for subfield in field_type.structure.field:
            alias_field_reference = ir_pb2.FieldReference(path=[
                anonymous_reference,
                ir_pb2.Reference(source_name=[subfield.name.name]),
            ])
            new_existence_condition = ir_pb2.Expression()
            new_existence_condition.CopyFrom(
                _ANONYMOUS_BITS_ALIAS_EXISTENCE_SKELETON)
            existence_clauses = new_existence_condition.function.args
            existence_clauses[0].function.args[0].field_reference.CopyFrom(
                anonymous_field_reference)
            existence_clauses[1].function.args[0].field_reference.CopyFrom(
                alias_field_reference)
            new_read_transform = ir_pb2.Expression(
                field_reference=alias_field_reference)
            # This treats *most* of the alias field as synthetic, but not its name(s):
            # leaving the name(s) as "real" means that symbol collisions with the
            # surrounding structure will be properly reported to the user.
            _mark_as_synthetic(new_existence_condition)
            _mark_as_synthetic(new_read_transform)
            new_alias = ir_pb2.Field(
                read_transform=new_read_transform,
                existence_condition=new_existence_condition,
                name=subfield.name)
            if subfield.HasField("abbreviation"):
                new_alias.abbreviation.CopyFrom(subfield.abbreviation)
            _mark_as_synthetic(new_alias.existence_condition)
            _mark_as_synthetic(new_alias.read_transform)
            new_fields.append(new_alias)
            # Since the alias field's name(s) are "real," it is important to mark the
            # original field's name(s) as synthetic, to avoid duplicate error
            # messages.
            _mark_as_synthetic(subfield.name)
            if subfield.HasField("abbreviation"):
                _mark_as_synthetic(subfield.abbreviation)
    del structure.field[:]
    structure.field.extend(new_fields)