RFC-0048:明確聯集普通

RFC-0048:明確的聯集序數
狀態已接受
區域
  • FIDL
說明

為讓 ABI 對可延伸聯集 (或單工聯集) 造成的影響更加一致,我們提議進行變更,讓其在更接近資料表的範圍內,進行彈性聯集的語法會保持正確,而今天在重新命名聯集或聯集成員時也修正了非常嚴格的 ABI 限制。

作者
提交日期 (年/月)2019-08-25
審查日期 (年/月)2019-09-26

摘要

為了讓 ABI 對可擴充聯集 (或單純聯集) 產生更一致的影響,我們建議採取下列做法:

  1. 變更變體成員的語法以要求使用明確序數 (類似於需要資料表序數的方式)。
  2. 請使用此明確序數,而非先前實作的雜湊序。
  3. 最後,我們變更有線格式,將聯集序數為 64 位元 (而非 32 位元)。

這些變更可讓彈性聯集的語法更接近資料表,而現在針對重新命名聯集或聯集成員的方面,均已正確修正1 和非常嚴格的 ABI 限制

動力與設計

除了聯集之外,就類型而言,名稱對於 ABI 沒有任何影響:您可以重新命名列舉、位元、結構和資料表,或者將成員重新命名,而無需擔心二進位檔的相容性。聯集有所不同,因為我們選擇使用以雜湊為基礎的技術來指派變化版本序數 (請參閱 RFC-0061:可擴充的節點)。

Google 發現這個簡稱,並已提議解決這項問題:請參閱「意圖實作:xunion ordinals 變更」一文,其中建議變更雜湊配置,使其只包含成員名稱。

相反地,本提案會進一步運用明確的序數,避免名稱與 ABI 相容性之間有任何關聯。我們認為,在聯集宣告中編寫序數需要多一點工夫:資料表至今沒有明確的序數沒有問題,而其他熱門 IDL 成員或變數的編號也已大幅增加。

此外,為了進一步與資料表對齊,我們要求序數從 1 依序指派,並允許使用關鍵字 reserved 明確略過聯集變化版本。

僅針對通訊協定進行雜湊處理

與類型不同,通訊協定是使用以雜湊為基礎的方法指派序數。這麼做是為了達成以下兩個主要用途:

這類使用案例不會轉譯為類型。

本提案的影響是僅用於通訊協定。只有一種雜湊配置,也就是 RFC-0029 中所述。

64 位元序數是標準的

目前,聯集內嵌內容有 4 個位元組的邊框間距:

  • 序數 (uint32)
  • 邊框間距 (uint32)
  • 信封 (16 個位元組)

相反地,我們希望在格式中明確呼叫所有位元組,進而將序數變更為 64b。一般而言,我們偏好無邊框的結構,因為這類結構較有效率 (例如,不需要明確的網路迷集或額外的程式設計表)。

請參閱「實作策略」一節,瞭解如何將自己轉換成 64 位元序數。

JSON 線格式

我們之前已討論過,當我們建立 JSON 傳輸格式時,重新命名類型和成員時,會對該格式產生 ABI 的影響。

建議您依「線路」格式區分 ABI 故障情形。我們可以透過不同屬性取得不同的屬性。極少數訊息需要與 ABI 相容所有支援的可能傳輸格式,在改進方式上將非常有限。有些客戶應盡可能使用更彈性的規則。

預做準備:稀疏資料表

目前我們已討論支援稀疏資料表,例如除了結構資料表外,還有第三個版面配置和類似記錄的資料。如果我們決定導入這個第三個選項,就會遵循本提案和目前資料表的語法:

sparse_table Example {
    1: T1 field1;
    2: reserved; // deprecated
    3: T3 field3;
};

導入策略

如要啟用柔性轉換,我們必須區分傳統 (32 位元雜湊) 序數和建議的 (64 位元明確) 序數語法。做法如下:

  1. 在 fidlc 中新增檢查,確保 32 位元雜湊序數的值絕不會低於 N。舉例來說,如果 N 是 512,則雜湊序數的十六進位值至少必須為 0x200。
    • 如果雜湊序數小於 0x200,將導致編譯錯誤,且必須使用 [Selector=] 屬性手動重新命名欄位名稱。我們會先將 [Selector] 新增至適當欄位,再以 fidlc 套用這項變更。
    • 由於現有雜湊配置是隨機的,我們預期雜湊錯誤幾乎發生於零次,因此您可能不需要手動解決。
    • 新增這項檢查可有效將 [0..N] 序數空間分配給明確的序數,並確保該方法不會與雜湊序數衝突。
  2. 當語言繫結解讀序數時:
    • 如果序數介於 [0, N) 之間,則序數為 64 位元且明確。
    • 如果序數介於 [N, UINT32_MAX] 之間,則序數為 32 位元並經過雜湊處理。
    • 如果序數介於 [UINT32_MAX, UINT64_MAX) 之間,繫結「必須」叫用錯誤,並關閉管道,加上 Epitaph。

人體工學

讓 ABI 人體工學變得更簡單,大幅減少具有明確序數的語法成本。

說明文件與範例

至少:

回溯相容性

未採用明確序數語法定義的聯集將繼續使用現有的 32 位元雜湊普通配置。因此,現今的聯集將繼續與 API 和 ABI 相容。

以明確序數語法定義的聯集將使用此 RFC 中所述的 64 位元序數配置。如要瞭解如何同時支援 32 位元和 64 位元序數配置,請參閱「實作策略」一節。

效能

極度微幅的改善:這個配置比雜湊序數的效率更好,因為 Switch() 陳述式的程式碼產生器較佳。

安全性

沒有影響。

測試

和平常一樣焦頭。

缺點、替代方案和未知

替代方法:僅限成員名稱的序數雜湊

請參閱「意圖實作:xunion ordinals change」。

經過進一步思考,我們認為上述做法不夠充足,因為語法優勢 (來源中沒有序數) 無法獲得補償:

  • 難以瞭解 ABI 影響的兩種雜湊配置;
  • 在重新命名宣告或成員時,讓聯集與同層級列舉、位元、結構和資料表有所不同。

先前的圖片和參考資料

沒有特別相關。


Footnote1

本文件中的「聯合」是指可擴充的聯集,而非生命週期終止附近的「靜態」聯集。

Footnote3

From: apang@google.com
收件者:fidl 使用者名單
日期:2019 年 5 月 23 日

FIDLers,你好!昨天編寫測試時,FIDL 團隊發現以目前的 Xunion 規格和植入式程式碼,出現了意想不到的行為。若其中一個宣告:

xunion MyXUnion {
    int32 i;  // ordinal might be 0x11111111
}
````

and renames the name of the xunion (not the field), the ordinal of the field
changes:

```fidl
// rename from MyXUnion to MyXUnion2
xunion MyXUnion2 {
    int32 i;  // ordinal now changes to 0x22222222 since the xunion was renamed. d'oh!
}

這是預料之外的行為:變更 xunion 的名稱不應變更 ABI。

要在這個方面做得更好:

  1. 我們想要修改 xunion RFC (RFC-0061),確保序數只衍生自欄位名稱,並移除一般雜湊計算中的 xunion 名稱和程式庫名稱。
  2. 幸好,我們必須變更程式碼,這意味著 xunion ABI 的變更,可能導致建構作業不佳。幸好,我們可以採用 Jeremy Manson 為方法實作序數雜湊的先進技術,讓這項作業能夠進行柔軟的轉換:讓用戶端一併檢查新舊雜湊,直到變更在樹狀結構中完全套用變更為止。

(其中一堂課會學到:未來我們應仔細研究序數雜湊包含的內容,以及是否應變更這些元素是否應改變 ABI)。

我們相信這個是低風險的計畫,因為可以進行柔性轉換,而 Jeremy 成功完成方法序對。煩請留言告知我們,否則我們會盡快開始處理。


  1. 某種程度上,名稱對於訊息的二進位傳輸格式 (即位元、列舉、結構、資料表) 和聯集沒有任何影響。因此與其他同類應用程式的差異