Skip to content

Commit cf501b4

Browse files
authored
Merge pull request #18163 from DougGregor/protocol-context-descriptor
2 parents 61c4e85 + 191db1e commit cf501b4

22 files changed

+703
-697
lines changed

docs/ABI/TypeMetadata.rst

Lines changed: 42 additions & 74 deletions
Original file line numberDiff line numberDiff line change
@@ -159,27 +159,32 @@ contain the following fields:
159159
describe the existential container layout used to represent
160160
values of the type. The word is laid out as follows:
161161

162-
* The **number of witness tables** is stored in the least significant 31 bits.
162+
* The **number of witness tables** is stored in the least significant 24 bits.
163163
Values of the protocol type contain this number of witness table pointers
164164
in their layout.
165+
* The **special protocol kind** is stored in 6 bits starting at
166+
bit 24. Only one special protocol kind is defined: the `Error` protocol has
167+
value 1.
168+
* The **superclass constraint indicator** is stored at bit 30. When set, the
169+
protocol type includes a superclass constraint (described below).
165170
* The **class constraint** is stored at bit 31. This bit is set if the type
166171
is **not** class-constrained, meaning that struct, enum, or class values
167172
can be stored in the type. If not set, then only class values can be stored
168173
in the type, and the type uses a more efficient layout.
169174

170-
Note that the field is pointer-sized, even though only the lowest 32 bits are
171-
currently inhabited on all platforms. These values can be derived from the
172-
`protocol descriptor`_ records, but are pre-calculated for convenience.
173-
174175
- The **number of protocols** that make up the protocol composition is stored at
175-
**offset 2**. For the "any" types ``Any`` or ``Any : class``, this
176+
**offset 2**. For the "any" types ``Any`` or ``AnyObject``, this
176177
is zero. For a single-protocol type ``P``, this is one. For a protocol
177178
composition type ``P & Q & ...``, this is the number of protocols.
178179

179-
- The **protocol descriptor vector** begins at **offset 3**. This is an inline
180-
array of pointers to the `protocol descriptor`_ for every protocol in the
181-
composition, or the single protocol descriptor for a protocol type. For
182-
an "any" type, there is no protocol descriptor vector.
180+
- If the **superclass constraint indicator** is set, type metadata for the
181+
superclass follows at the next offset.
182+
183+
- The **protocol vector** follows. This is an inline array of pointers to
184+
descriptions of each protocol in the composition. Each pointer references
185+
either a Swift `protocol descriptor`_ or an Objective-C `Protocol`; the low
186+
bit will be set to indicate when it references an Objective-C protocol. For an
187+
"any" or "AnyObject" type, there is no protocol descriptor vector.
183188

184189
Metatype Metadata
185190
~~~~~~~~~~~~~~~~~
@@ -405,72 +410,35 @@ See the `protocol descriptor`_ description below.
405410
Protocol Descriptor
406411
~~~~~~~~~~~~~~~~~~~
407412

408-
`Protocol metadata` contains references to zero, one, or more **protocol
409-
descriptors** that describe the protocols values of the type are required to
410-
conform to. The protocol descriptor is laid out to be compatible with
411-
Objective-C ``Protocol`` objects. The layout is as follows:
412-
413-
- An **isa** placeholder is stored at **offset 0**. This field is populated by
414-
the Objective-C runtime.
415-
- The mangled **name** is referenced as a null-terminated C string at
416-
**offset 1**.
417-
- If the protocol inherits one or more other protocols, a pointer to the
418-
**inherited protocols list** is stored at **offset 2**. The list starts with
419-
the number of inherited protocols as a pointer-sized integer, and is followed
420-
by that many protocol descriptor pointers. If the protocol inherits no other
421-
protocols, this pointer is null.
422-
- For an ObjC-compatible protocol, its **required instance methods** are stored
423-
at **offset 3** as an ObjC-compatible method list. This is null for native
424-
Swift protocols.
425-
- For an ObjC-compatible protocol, its **required class methods** are stored
426-
at **offset 4** as an ObjC-compatible method list. This is null for native
427-
Swift protocols.
428-
- For an ObjC-compatible protocol, its **optional instance methods** are stored
429-
at **offset 5** as an ObjC-compatible method list. This is null for native
430-
Swift protocols.
431-
- For an ObjC-compatible protocol, its **optional class methods** are stored
432-
at **offset 6** as an ObjC-compatible method list. This is null for native
433-
Swift protocols.
434-
- For an ObjC-compatible protocol, its **instance properties** are stored
435-
at **offset 7** as an ObjC-compatible property list. This is null for native
436-
Swift protocols.
437-
- The **size** of the protocol descriptor record is stored as a 32-bit integer
438-
at **offset 8**. This is currently 72 on 64-bit platforms and 40 on 32-bit
439-
platforms.
440-
- **Flags** are stored as a 32-bit integer after the size. The following bits
441-
are currently used (counting from least significant bit zero):
442-
443-
* **Bit 0** is the **Swift bit**. It is set for all protocols defined in
444-
Swift and unset for protocols defined in Objective-C.
445-
* **Bit 1** is the **class constraint bit**. It is set if the protocol is
413+
Protocol descriptors describe the requirements of a protocol, and act as a
414+
handle for the protocol itself. The are referenced by `Protocol metadata`_, as
415+
well as `Protocol Conformance Records`_ and generic requirements. Protocol
416+
descriptors are only created for non-`@objc` Swift protocols: `@objc` protocols
417+
are emitted as Objective-C metadata. The layout of Swift protocol descriptors is
418+
as follows:
419+
420+
- Protocol descriptors are context descriptors, so they are prefixed by context
421+
descriptor metadata. (FIXME: these are not yet documented)
422+
- The 16-bit kind-specific flags of a protocol are defined as follows:
423+
* **Bit 0** is the **class constraint bit**. It is set if the protocol is
446424
**not** class-constrained, meaning that any struct, enum, or class type
447425
may conform to the protocol. It is unset if only classes can conform to
448-
the protocol. (The inverted meaning is for compatibility with Objective-C
449-
protocol records, in which the bit is never set. Objective-C protocols can
450-
only be conformed to by classes.)
451-
* **Bit 2** is the **witness table bit**. It is set if dispatch to the
452-
protocol's methods is done through a witness table, which is either passed
453-
as an extra parameter to generic functions or included in the existential
454-
container layout of protocol types. It is unset if dispatch is done
455-
through ``objc_msgSend`` and requires no additional information to accompany
456-
a value of conforming type.
457-
* **Bit 31** is set by the Objective-C runtime when it has done its
458-
initialization of the protocol record. It is unused by the Swift runtime.
459-
- **Number of mandatory requirements** is stored as a 16-bit integer after
460-
the flags. It specifies the number of requirements that do not have default
461-
implementations.
462-
- **Number of requirements** is stored as a 16-bit integer after the flags. It
463-
specifies the total number of requirements for the protocol.
464-
- **Requirements pointer** stored as a 32-bit relative pointer to an array
465-
of protocol requirements. The number of elements in the array is specified
466-
by the preceding 16-bit integer.
467-
- **Superclass pointer** stored as a 32-bit relative pointer to class metadata,
468-
describing the superclass bound of the protocol.
469-
- **Associated type names** stored as a 32-bit relative pointer to a
470-
null-terminated string. The string contains the names of the associated
471-
types, in the order they apparent in the requirements list, separated by
472-
spaces.
473-
426+
the protocol.
427+
* **Bit 1** indicates that the protocol is **resilient**.
428+
* **Bits 2-7** indicate specify the **special protocol kind**. Only one
429+
special protocol kind is defined: the `Error` protocol has value 1.
430+
- A pointer to the **name** of the protocol.
431+
- The number of generic requirements within the **requirement signature** of
432+
the protocol. The generic requirements themselves follow the fixed part
433+
of the protocol descriptor.
434+
- The number of **protocol requirements** in the protocol. The protocol
435+
requirements follow the generic reuqirements that form the **requirement
436+
signature**.
437+
- A string containing the **associated type names**, a C string comprising the
438+
names of all of the associated types in this protocol, separated by spaces,
439+
and in the same order as they appear in the protocol requirements.
440+
- The **generic requirements** that form the **requirement signature**.
441+
- The **protocol requirements** of the protocol.
474442

475443
Protocol Conformance Records
476444
~~~~~~~~~~~~~~~~~~~~~~~~~~~~

0 commit comments

Comments
 (0)