RFC-0025:位元標記

RFC-0025:位元旗標
狀態已接受
區域
  • FIDL
說明

使用位元旗標宣告擴充 FIDL 語言。

作者
提交日期 (年-月-日)2019-01-14
審查日期 (年-月-日)2019-01-24

「Just a Little Bit」

摘要

使用位元旗標宣告擴充 FIDL 語言。

提振精神

在 FIDL 中,有幾種情況會需要描述整數上的旗標集。目前建議 FIDL 使用者建立一組相同基礎型別的常數。由於這些都是獨立的,繫結在執行階段無法偵測到無效值。

設計

變更來源語言

這項提案會在 FIDL 中新增 bits 關鍵字。

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 常數運算式中將這些運算式以 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 可能不是。舉例來說,如果 OpenRightsenum,則唯一可傳送的有效值為 124。不過,03567 也都是有效的 bits 類型。

繫結

每種語言繫結都會擴充,以處理這些慣用值。最糟的情況是,這只會為每個 bits 成員產生常數,就像是基礎型別的整數常數一樣。

bits 值的線路格式與基礎整數值相同。

序列化和還原序列化程式碼應確保值是所描述位元的子集。舉例來說,嘗試將 8 做為 OpenRights 值時,驗證應該會失敗。

信號和權利常數

我也建議在 zx 程式庫中加入信號和控制碼的正確值。 包括所有信號值和權利的 bits 宣告,以及可能為每種控制代碼類型設定預設權利的一組常數。

導入策略

階段 1

將所有來源變更 (包括剖析器測試) 新增至 FIDL 編譯器。

階段 2

為所有語言繫結和相容性測試套件新增支援。

第 3 階段

將現有的整數常數堆疊遷移至 bits

人體工學

這項變更可讓使用者明確表達意圖,讀者也能看到明確的分組,使 FIDL 更符合人體工學。

說明文件和範例

這項提案說明上述 FIDL 文法變更。

我會調整 FIDL 教學課程,加入這個模式的範例。

回溯相容性

這是 FIDL 來源的回溯相容變更。

線路格式可向後相容,也就是說,無論是做為 uint32bits Bits : uint32 傳送,(2 | 4)6 的值在線路上都相同。

效能

在 FIDL 中將型別從 uint32 變更為 bits 值,會在繫結中增加一些次要負荷,以檢查序列化或還原序列化的值是否有效。

這是位元遮罩和分支,不太可能引起注意。

安全性

我認為沒有安全方面的缺點。 或許型別安全性的提升只是小幅優勢。

測試

fidlc 主機單元測試會執行 FIDL 剖析器。

相容性測試套件將擴充各種大小和值的 bits 型別,以練習所有支援繫結的傳送和接收路徑。

缺點、替代方案和未知事項

這項提案建議只允許無符號整數型別的位元。我相信可以允許簽署基礎型別,但所有語言繫結都必須比預期更謹慎。我希望我們不要在 C/C++ 中意外地將位元移得太遠。

更一般的位元欄位模式似乎比這項提案的價值更複雜。也就是將整數型別分割成幾個位元範圍,並為每個位元範圍命名為欄位。

&~ 運算式似乎不必要,至少一開始是這樣。 目標語言可能會選擇支援位元旗標值的這類算術運算式,但我目前認為 FIDL 常數不需要直接支援這類運算式。

既有技術和參考資料

不願使用會員值執行過於複雜的作業,以及避免使用已簽署型別,是因為 C 和 C++ 中這些概念長期以來都令人困惑,而這些概念的繫結必須支援這項概念。