RFC-0025:Bit flag

RFC-0025:位标记
状态已接受
领域
  • FIDL
说明

使用位标志声明扩展 FIDL 语言。

作者
提交日期(年-月-日)2019-01-14
审核日期(年-月-日)2019-01-24

“只是一点”

总结

使用位标志声明扩展 FIDL 语言。

设计初衷

在 FIDL 中,可通过多种用例来描述一组用于通过整数描述一组标志的用例。目前,我们建议 FIDL 用户创建一组相同基础类型的常量。 由于这些都是独立的,因此绑定在运行时无法检测到无效值的创建。

设计

源语言更改

此提案将关键字 bits 添加到 FIDL 中。

bits 会引入一个类似于 enum 的顶级声明。正式的语法形式如下所示:

bits-declaration = ( attribute-list ) , "bits" , IDENTIFIER , ( ":" , type-constructor ) ,
                   "{" , ( bits-or-enum-member , ";" )+ , "}" ; [NOTE 1]

bits-or-enum-member = ( attribute-list ) , IDENTIFIER , ( "=" , bits-or-enum-member-value ) ;

bits-or-enum-member-value = IDENTIFIER | literal ; [NOTE 2]

注意:

  1. bits-declaration 允许在语法中使用更为自由的 type-constructor,但编译器将此功能限制为无符号整数类型,请参阅基元

  2. bits-or-enum-member-value 允许在语法中使用更为自由的 literal,但编译器将此限制限制为:

    • enum 上下文中的 NUMERIC-LITERAL
    • NUMERIC-LITERAL,在 bits 的上下文中必须是 2 的幂。

bits 声明中的每个成员都是 2 的幂。为简单起见,此方案建议不允许在 bits 声明本身中使用更复杂的表达式,也不允许这些表达式在 bits 常量表达式中组合使用。 未来它们可能会添加到 bits 声明中。

bits 声明示例(取自 fuchsia.io 库中当前存在的常量):

bits OpenRights : uint32 {
    READABLE = 0x00000001;
    WRITABLE = 0x00000002;
    ADMIN = 0x00000004;
};

此外,此方案还添加了一种二进制字面量语法,如下所示:

bits OpenRights : uint32 {
    READABLE = 0b0001;
    WRITABLE = 0b0010;
    ADMIN = 0b0100;
};

语义

溢出底层整数类型会导致编译错误。

每个 bits 成员值都必须不同。

如果对 bits 值进行序列化或反序列化,而该位集不是 bits 声明的成员,则会导致验证错误。

bits 的语义与 enum 不同。enum 值必须是 FIDL 声明的值之一,但 bits 不能。 例如,如果 OpenRightsenum,则仅可发送 124 这三个值。不过,作为 bits 类型,03567 也都有效。

绑定关系

每种语言绑定都将进行扩展,以便以惯用方式处理这些值。最糟糕的是,这样只会为每个 bits 成员生成一个常量,就像它是基础类型的整数常量一样。

bits 值的传输格式与基础整数值相同。

对代码进行序列化和反序列化应确保该值是所描述位的子集。例如,尝试使用 8 作为 OpenRights 值应无法通过验证。

信号和权利常量

我还提议向 zx 库添加信号并处理正确的值。这包括所有信号值和权限的 bits 声明,可能还包括一组常量,其中每个句柄类型具有默认权限。

实施策略

第 1 阶段

将所有源代码更改添加到 FIDL 编译器,包括解析器测试。

第 2 阶段

添加对所有语言绑定以及兼容性测试套件的支持。

第 3 阶段

将现有堆常量迁移到 bits

工效学设计

这一变更可让用户明确表达其意图,并让读者看到明确的分组,使 FIDL 更符合人体工程学。

文档和示例

此提案介绍了对上述 FIDL 语法的变更。

我会调整 FIDL 教程以添加此模式的示例。

向后兼容性

这是对 FIDL 源代码的向后兼容更改。

传输格式是向后兼容的,也就是说,无论以 uint32 还是 bits Bits : uint32 的形式发送,(2 | 4)(即 6)的值在传输中是相同的。

性能

将 FIDL 中的类型从 uint32 更改为 bits 值会增加绑定检查序列化或反序列化值是否有效的一些次要开销。

它是一个位掩码和一个分支,不太可能引起注意。

安全性

我没有发现安全方面的缺点。 更好的类型安全性也许是小的优势。

测试

fidlc 主机单元测试将运行 FIDL 解析器。

系统会使用不同大小和值的 bits 类型扩展兼容性测试套件,以执行所有受支持绑定的发送和接收路径。

缺点、替代方案和未知情况

此方案建议仅允许无符号整数类型的位。我认为可以允许带签名的底层类型,但在所有语言绑定中应更加谨慎。尤其是,我不希望我们在 C/C++ 中意外将位移得太远。

对于此方案,更通用的位字段模式似乎要复杂得多。 我的意思是将一个整数类型划分到若干位的范围中,并为每个位范围指定一个名称作为字段。

&~ 表达式让人感觉没有必要,至少一开始如此。目标语言可以选择支持针对位标志值使用此类算术表达式,但我目前还不需要在 FIDL 常量中直接使用它们。

早期技术和参考资料

您犹豫是否要使用成员值执行过于复杂的操作,并避免有符号类型,这是基于与 C 和 C++ 中的这些概念的永恒混淆,而 C 和 C++ 中的绑定必须支持此概念。