| RFC-0025:位元旗標 | |
|---|---|
| 狀態 | 已接受 | 
| 區域 | 
 | 
| 說明 | 使用位元旗標宣告擴充 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]
注意:
- bits-declaration允許文法中使用較為自由的- type-constructor,但編譯器會將這項限制設為未簽署的整數類型,請參閱「原始元素」。
- 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 則不一定是。舉例來說,如果 OpenRights 是 enum,則唯一可傳送的有效值為 1、2 和 4。不過,0、3、5、6 和 7 也都是有效的 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++ 中的這些概念永遠令人困惑,而這些概念的繫結必須支援此概念。