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++ 中這些概念長期以來都令人困惑,而這些概念的繫結必須支援這項概念。