RFC-0025:位标志 | |
---|---|
状态 | 已接受 |
区域 |
|
说明 | 使用位标志声明扩展 FIDL 语言。 |
作者 | |
提交日期(年-月-日) | 2019-01-14 |
审核日期(年-月-日) | 2019-01-24 |
“Just a Little Bit”
摘要
使用位标志声明扩展 FIDL 语言。
设计初衷
在 FDL 中,有几种使用场景可用于描述整数的一组标志。目前,建议 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]
注意:
bits-declaration
允许在语法中使用更宽松的type-constructor
,但编译器将其限制为无符号整数类型,请参阅基元。bits-or-enum-member-value
允许在语法中使用更宽松的literal
,但编译器将其限制为:enum
上下文中的NUMERIC-LITERAL
;bits
上下文中的NUMERIC-LITERAL
,必须为二的幂。
bits
声明中的每个成员都是二的幂。为简单起见,此提案建议不允许在 bits
声明本身中使用更复杂的表达式,也不允许在 bits
常量表达式中对这些表达式进行 OR 运算。这些属性日后可能会添加到 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
则不一定。例如,如果 OpenRights
为 enum
,则可发送的唯一有效值为 1
、2
和 4
。不过,作为 bits
类型,0
、3
、5
、6
和 7
也都是有效值。
绑定
每个语言绑定都将扩展,以便以惯用方式处理这些值。在最糟糕的情况下,这只会为每个 bits
成员生成一个常量,就像它是底层类型的整数常量一样。
bits
值的线格格式与底层整数值相同。
序列化和反序列化代码应确保该值是所述位的一小部分。例如,尝试将 8 用作 OpenRights
值应会失败验证。
信号和权限常量
我还建议向 zx
库添加信号和正确的处理程序值。
这包括所有信号值和权限的 bits
声明,以及可能包含每种句柄类型的默认权限的一组常量。
实施策略
第 1 阶段
将所有源代码更改添加到 FIDL 编译器,包括解析器测试。
第 2 阶段
为所有语言绑定和兼容性测试套件添加了支持。
第 3 阶段
将现有的 int 常量堆迁移到 bits
。
工效学设计
这项变更让用户可以明确表达其意图,读者可以看到明确的分组,从而使 FIDL 更加符合人体工学。
文档和示例
此提案介绍了对上述 FIDL 语法所做的更改。
我会调整 FIDL 教程,在其中添加此模式的示例。
向后兼容性
这是对 FIDL 源代码的向后兼容更改。
线格格式向后兼容,这意味着无论以 uint32
还是 bits Bits :
uint32
的形式发送,(2 |
4)
或 6
的值在线路上都是相同的。
性能
将 FIDL 中的类型从 uint32
更改为 bits
值会在检查序列化或反序列化值是否有效的绑定中增加一些小开销。
这是位掩码和分支,不太可能被注意到。
安全
我认为这不会带来安全问题。 更好的类型安全性可能是一项小优势。
测试
fidlc
主机单元测试将运行 FIDL 解析器。
兼容性测试套件将扩展为包含各种大小和值的 bits
类型,以演练所有受支持绑定的发送和接收路径。
缺点、替代方案和未知情况
此提案建议仅允许对无符号整数类型使用位。我认为可以允许对已签名的底层类型执行此操作,但在所有语言绑定中,需要比理想情况更谨慎。我更希望我们不要在 C/C++ 中意外地将位移得太远。
更通用的位字段模式似乎比此提案更复杂。我的意思是将整数类型划分为几个位范围,并为每个位范围指定一个字段名称。
&
和 ~
表达式似乎没有必要,至少在开始时是这样。目标语言可以选择支持对位标志值执行此类算术表达式,但我目前还没有看到直接在 FIDL 常量中使用它们的必要性。
在先技术和参考文档
人们不愿对成员值执行过于复杂的操作,并避免使用有符号类型,是因为他们对 C 和 C++ 中的这些概念一直存在混淆,而这些绑定必须支持此概念。