{% set rfcid = “RFC-0048” %} {% include “docs/contribute/governance/rfcs/_common/_rfc_header.md” %}
Note: Formerly known as FTP-048.
To better align ABI implications around extensible unions (or simply unions), we propose to:
These changes make flexible unions syntactically closer to tables, and correct odd[2] and unduly strict ABI restrictions today around renaming unions or union members.
Aside from unions, names have no ABI impact when it comes to types: enums, bits, struct, and tables can all be renamed, or have their members renamed without any worries to binary compatibility. Unions are different since we chose to use a hash based technique to assign variant ordinals (see RFC-0061: Extensible Unions).
We have recognized this shortcoming, and have proposed ways to address it: see Intent to implement: xunion ordinals change, which suggests changing the hashing scheme to only include the member name.
Instead, this proposal goes a step further and simply uses explicit ordinals, thus avoiding any correlation between names and ABI compatibility. We consider the extra effort to write ordinals in union declarations to be minimal: to date explicit ordinals in tables have not been an issue, and there is a vast precedent to numbering members or variants from other popular IDLs.
Additionally, and to further align with tables, we require that ordinals be sequentially assigned from 1, and allow the keyword reserved
to be used to explicitly skip a union variant.
Unlike types, protocols use a hash based approach to assign ordinals. This is motivated by two key use cases:
These use cases do not translate to types.
The effect of this proposal is that hashing is used only for protocols. There is only one hashing scheme, i.e. the one described in RFC-0029.
Right now, there are 4 bytes of padding in a union inline content:
uint32
)uint32
)Instead, we want all bytes to be called for explicitly in the format and therefore change the ordinal to 64b. Generally, we prefer padding-less structures since they are more efficient (e.g. do not require explicit memsets or extra coding tables).
See the Implementation Strategy section for how to soft-transition to 64-bit ordinals.
It's been discussed in the past that when we create a JSON wire format, renaming of types and members will pose ABI implications in that format.
It's useful to separate ABI breakage on a per ‘wire format’ basis. We can get different properties from different ones. The rare messages that need to be ABI compatible on all possible wire formats supported will be very limited in how they can evolve. Others should benefit from more flexible rules where possible.
There‘s been discussion of supporting sparse tables, i.e. a third layout to record-like data in addition to structs and tables. Should we decide to introduce this third option, the strawman syntax would follow this proposal, and the current tables’ syntax:
sparse_table Example { 1: T1 field1; 2: reserved; // deprecated 3: T3 field3; };
To enable a soft transition, we need to disambiguate between the classic (32-bit hashed) ordinal syntax and the proposed (64-bit explicit) ordinal syntax. This can be done by:
Makes ABI ergonomics much simpler, at the very minimal syntactic cost of having explicit ordinals.
At least:
Unions defined without the explicit ordinal syntax will continue to use the existing 32-bit, hashed-ordinal scheme. So, a union that exists today will continue to be API- and ABI-compatible.
Unions defined with explicit ordinal syntax will use the 64-bit ordinal scheme described in this RFC. See the Implementation Strategy section for how to support both the 32-bit and 64-bit ordinal schemes.
Extremely minor improvement: this scheme is more efficient than hashed ordinals due to better codegen for switch() statements.
No impact.
Trivial, as usual.
See Intent to implement: xunion ordinals change.
After further thought, we do not consider the above to enough since the syntactical advantage (no ordinals in source) does not compensate:
None that is particularly relevant.
“Union” in this document refers to extensible unions, not “static” unions nearing their end-of-life.
Odd in the sense that names have no impact on the binary wire format of messages (i.e. bits, enum, struct, table), except for unions. It's therefore a case that stands out as being different than others.
From: apang@google.com
To: fidl users list
Date: 5/23/2019
Hi FIDLers! When writing a test yesterday, the FIDL team saw a surprising behavior with the current xunion spec & impl. If one declares this:
xunion MyXUnion { int32 i; // ordinal might be 0x11111111 }
and renames the name of the xunion (not the field), the ordinal of the field changes:
// rename from MyXUnion to MyXUnion2 xunion MyXUnion2 { int32 i; // ordinal now changes to 0x22222222 since the xunion was renamed. d'oh! }
This is arguably unexpected behavior: changing the name of the xunion shouldn't change the ABI.
Making this better means two things:
(One lesson learnt: in the future, we should look carefully at what's included in an ordinal hash, and whether changing those things should change the ABI.)
We believe this is a low-risk plan given that it‘s possible to do a soft-transition, and Jeremy’s successfully done it for method ordinals. Please chime in with comments, otherwise we'll get started on this work soon.