RFC-0025:位元標記

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

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

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

「Just a Little Bit」

摘要

使用位元旗標宣告擴充 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]

注意:

  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 來源的回溯相容性變更。

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

成效

將 FIDL 中的類型從 uint32 變更為 bits 值,會在檢查序列化或反序列化值是否有效的繫結中增加一些額外負擔。

這是位元遮罩和分支,不太可能會被發現。

安全性

我認為這不會造成安全性問題。較佳的型別安全性或許是較小的優點。

測試

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

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

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

這項提案建議只允許位元組用於未簽署的整數類型。我認為可以允許在已簽署的基礎類型中使用,但在所有語言繫結中,這項操作需要比必要更謹慎。我特別不希望我們在 C/C++ 中意外地將位元移位太多。

一般位元組模式似乎比這個提案更複雜,也就是將整數類型切割成幾個位元範圍,並為每個位元範圍提供一個欄位名稱。

&~ 運算式至少在剛開始時似乎不必要。目標語言可選擇支援位元旗標值的這種算術運算式,但我目前還不認為需要在 FIDL 常數中直接使用這種運算式。

既有技術與參考資料

之所以不願意使用成員值執行任何過於複雜的操作,以及避免使用已簽署的型別,是因為 C 和 C++ 中的這些概念永遠令人困惑,而這些概念的繫結必須支援此概念。