RFC-0054:参数属性

RFC-0054:参数属性
状态已接受
区域
  • FIDL
说明

我们已经可以为 FIDL 的各种元素应用属性,但还不能为参数应用属性。此提案旨在扩展语法以接受形参属性。

作者
提交日期(年-月-日)2019-11-21
审核日期(年-月-日)2019-12-12

“有机会编写自我记录的 API”

摘要

我们已经可以为 FIDL 的各种元素应用属性,但还不能为参数应用属性。此提案旨在扩展语法以接受形参属性。

与其他 RFC 的关系

此 RFC 已被以下 RFC 取代:

设计初衷

为更多语言元素添加属性可提高语言一致性,并为未来实现更多功能奠定基础。任何无法在类型系统中编码的 API 相关事实都可以改为在属性中编码。任何无法在类型系统中编码的事实都可以通过属性中的更多结构来捕获,从而简化各种后端中的后期验证。这些属性对于代码检查非常有用,生成器还可以利用这些信息来生成更好的代码,或将这些信息传播到目标语言的属性中。这有助于对目标语言进行静态和/或动态分析。此外,属性还可以很好地用于为类型系统设计可能的扩展或改进原型。

此功能的主要使用场景是检查句柄泄漏、双重释放和释放后使用错误。

内核 ABI(即系统调用)也以 FIDL 格式表示,并且句柄的所有权通常不明确。用户是否应在 task_kill 系统调用后调用 handle_close?相关文档并未明确说明这一点。其他系统调用有非常清晰的文档,但只能通过手动检查:

[Transport = "Syscall"]
protocol handle {
    /// Close a handle.
    /// Rights: None.
    handle_close(handle handle) -> (status status);

    /// Close a number of handles.
    /// Rights: None.
    handle_close_many(vector<handle> handles) -> (status status);

    /// Duplicate a handle.
    /// Rights: handle must have ZX_RIGHT_DUPLICATE.
    handle_duplicate(handle handle, rights rights) -> (status status, handle out);

    /// Replace a handle.
    /// Rights: None.
    handle_replace(handle handle, rights rights) -> (status status, handle out);
};

在为参数启用属性后,我们可以将注释替换为属性。这些属性与注释一样易于理解,并且可以帮助生成器生成可使用静态和动态分析工具(例如此工具)进行检查的代码。kazoo 工具可以为 C 和 C++ 绑定生成相应的注释,使 Clang 静态分析器能够捕获句柄误用错误。

该原型已在 Fuchsia 中发现了一些 bug。

设计

建议向 FIDL 源语言添加形参属性。这些属性应以与处理其他属性类似的方式在 JSON IR 中公开。我们可能需要更新格式化程序。它不会影响有线格式。语言绑定仅受引入可更改生成代码的特定注释的影响,但不受此提案的直接影响。

我们的提案仅更改了 FIDL 语法的一条生产规则:

- parameter = type-constructor , IDENTIFIER ;
+ parameter = ( attribute-list ) , type-constructor , IDENTIFIER ;

我们还需要诊断参数上的三斜线文档或文档属性。

实施策略

此更改向后兼容,无需迁移。有很多文档需要随功能一起更新。此提案会更改解析器并向 IR 添加新信息。引入新的形参属性时,可以单独对生成器进行潜在更改。

工效学设计

这有助于使 FIDL API 更易于理解,并使绑定对静态和动态分析更加友好。额外的复杂性成本应较低。如需查看包含潜在形参属性的示例,请参阅下一部分。 编辑器支持可能也需要进行小幅更新。

文档和示例

语法文档和语言参考需要进行小幅更新。我们可能需要添加一些样式指南,说明在某些情况下如何为形参属性换行。这可能不太重要,因为当前样式指南中根本没有提及属性。

如需查看示例,请参阅动机部分

向后兼容性

此提案同时保持了 FIDL 源和线缆 ABI 兼容性。稍后引入的特定属性可能会导致有线 ABI 不兼容。这些属性应单独通过 RFC 流程。

性能

未来的属性可能会对效果产生良好影响。有关 API 的更多信息可能有助于目标语言的优化器。

安全

特定属性可能会提高安全性,因为它们可以帮助目标语言中的静态和动态分析工具。

测试

将为 fidlc 编写测试,以确保正确解析,并为编译失败提供合理的诊断信息。系统还会测试生成的 JSON IR。为了能够进行测试,我们需要引入至少一个适用于参数的属性。由于生成器最初不会被触及,因此无需进行额外测试。

缺点、替代方案和未知因素

实现成本相对较低。

RFC-0044 是一种可能的替代方案。接受该提案会在语言中引入一些不一致之处,因为一种描述参数的方式允许用户编写参数属性,而另一种则不允许。此外,RFC-0044 会产生性能开销,因此某些协议(例如 syscall)应谨慎使用或完全不使用。

在先技术和参考资料

Protobuf 在消息上具有选项,其行为与参数属性有些类似。FIDL 已经在某些语言元素(如成员和协议)上添加了属性。