RFC-0025:位标记 | |
---|---|
状态 | 已接受 |
领域 |
|
说明 | 使用位标志声明扩展 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]
注意:
bits-declaration
允许在语法中使用更为自由的type-constructor
,但编译器将此功能限制为无符号整数类型,请参阅基元。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
不能。
例如,如果 OpenRights
为 enum
,则仅可发送 1
、2
和 4
这三个值。不过,作为 bits
类型,0
、3
、5
、6
和 7
也都有效。
绑定关系
每种语言绑定都将进行扩展,以便以惯用方式处理这些值。最糟糕的是,这样只会为每个 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++ 中的绑定必须支持此概念。