mirror of
https://github.com/apple/swift.git
synced 2025-12-21 12:14:44 +01:00
The key path pattern needs to include a reference to the external descriptor, along with hooks for lowering its type arguments and indices, if any. The runtime will need to instantiate and interpolate the external component when the key path object is instantiated. While we're here, let's also reserve some more component header bytes for future expansion, since this is an ABI we're going to be living with for a while.
220 lines
7.5 KiB
C++
220 lines
7.5 KiB
C++
//===--- KeyPath.h - ABI constants for key path objects ---------*- C++ -*-===//
|
|
//
|
|
// This source file is part of the Swift.org open source project
|
|
//
|
|
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
|
|
// Licensed under Apache License v2.0 with Runtime Library Exception
|
|
//
|
|
// See https://swift.org/LICENSE.txt for license information
|
|
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
//
|
|
// Constants used in the layout of key path objects.
|
|
//
|
|
//===----------------------------------------------------------------------===//
|
|
|
|
#ifndef __SWIFT_ABI_KEYPATH_H__
|
|
#define __SWIFT_ABI_KEYPATH_H__
|
|
|
|
// We include the basic constants in a shim header so that it can be shared with
|
|
// the Swift implementation in the standard library.
|
|
|
|
#include <cstdint>
|
|
#include <cassert>
|
|
#include "../../../stdlib/public/SwiftShims/KeyPath.h"
|
|
|
|
namespace swift {
|
|
|
|
/// Header layout for a key path's data buffer header.
|
|
class KeyPathBufferHeader {
|
|
uint32_t Data;
|
|
|
|
constexpr KeyPathBufferHeader(unsigned Data) : Data(Data) {}
|
|
|
|
static constexpr uint32_t validateSize(uint32_t size) {
|
|
return assert(size <= _SwiftKeyPathBufferHeader_SizeMask
|
|
&& "size too big!"),
|
|
size;
|
|
}
|
|
public:
|
|
constexpr KeyPathBufferHeader(unsigned size,
|
|
bool trivialOrInstantiableInPlace,
|
|
bool hasReferencePrefix)
|
|
: Data((validateSize(size) & _SwiftKeyPathBufferHeader_SizeMask)
|
|
| (trivialOrInstantiableInPlace ? _SwiftKeyPathBufferHeader_TrivialFlag : 0)
|
|
| (hasReferencePrefix ? _SwiftKeyPathBufferHeader_HasReferencePrefixFlag : 0))
|
|
{
|
|
}
|
|
|
|
constexpr KeyPathBufferHeader withSize(unsigned size) const {
|
|
return (Data & ~_SwiftKeyPathBufferHeader_SizeMask) | validateSize(size);
|
|
}
|
|
|
|
constexpr KeyPathBufferHeader withIsTrivial(bool isTrivial) const {
|
|
return (Data & ~_SwiftKeyPathBufferHeader_TrivialFlag)
|
|
| (isTrivial ? _SwiftKeyPathBufferHeader_TrivialFlag : 0);
|
|
}
|
|
constexpr KeyPathBufferHeader withIsInstantiableInPlace(bool isTrivial) const {
|
|
return (Data & ~_SwiftKeyPathBufferHeader_TrivialFlag)
|
|
| (isTrivial ? _SwiftKeyPathBufferHeader_TrivialFlag : 0);
|
|
}
|
|
|
|
constexpr KeyPathBufferHeader withHasReferencePrefix(bool hasPrefix) const {
|
|
return (Data & ~_SwiftKeyPathBufferHeader_HasReferencePrefixFlag)
|
|
| (hasPrefix ? _SwiftKeyPathBufferHeader_HasReferencePrefixFlag : 0);
|
|
}
|
|
|
|
constexpr uint32_t getData() const {
|
|
return Data;
|
|
}
|
|
};
|
|
|
|
/// Header layout for a key path component's header.
|
|
class KeyPathComponentHeader {
|
|
uint32_t Data;
|
|
|
|
constexpr KeyPathComponentHeader(unsigned Data) : Data(Data) {}
|
|
|
|
static constexpr uint32_t validateInlineOffset(uint32_t offset) {
|
|
return assert(offsetCanBeInline(offset)
|
|
&& "offset too big!"),
|
|
offset;
|
|
}
|
|
|
|
public:
|
|
static constexpr bool offsetCanBeInline(unsigned offset) {
|
|
return offset <= _SwiftKeyPathComponentHeader_MaximumOffsetPayload;
|
|
}
|
|
|
|
constexpr static KeyPathComponentHeader
|
|
forStructComponentWithInlineOffset(unsigned offset) {
|
|
return KeyPathComponentHeader(
|
|
(_SwiftKeyPathComponentHeader_StructTag
|
|
<< _SwiftKeyPathComponentHeader_DiscriminatorShift)
|
|
| validateInlineOffset(offset));
|
|
}
|
|
|
|
constexpr static KeyPathComponentHeader
|
|
forStructComponentWithOutOfLineOffset() {
|
|
return KeyPathComponentHeader(
|
|
(_SwiftKeyPathComponentHeader_StructTag
|
|
<< _SwiftKeyPathComponentHeader_DiscriminatorShift)
|
|
| _SwiftKeyPathComponentHeader_OutOfLineOffsetPayload);
|
|
}
|
|
|
|
constexpr static KeyPathComponentHeader
|
|
forStructComponentWithUnresolvedFieldOffset() {
|
|
return KeyPathComponentHeader(
|
|
(_SwiftKeyPathComponentHeader_StructTag
|
|
<< _SwiftKeyPathComponentHeader_DiscriminatorShift)
|
|
| _SwiftKeyPathComponentHeader_UnresolvedFieldOffsetPayload);
|
|
}
|
|
|
|
constexpr static KeyPathComponentHeader
|
|
forClassComponentWithInlineOffset(unsigned offset) {
|
|
return KeyPathComponentHeader(
|
|
(_SwiftKeyPathComponentHeader_ClassTag
|
|
<< _SwiftKeyPathComponentHeader_DiscriminatorShift)
|
|
| validateInlineOffset(offset));
|
|
}
|
|
|
|
constexpr static KeyPathComponentHeader
|
|
forClassComponentWithOutOfLineOffset() {
|
|
return KeyPathComponentHeader(
|
|
(_SwiftKeyPathComponentHeader_ClassTag
|
|
<< _SwiftKeyPathComponentHeader_DiscriminatorShift)
|
|
| _SwiftKeyPathComponentHeader_OutOfLineOffsetPayload);
|
|
}
|
|
|
|
constexpr static KeyPathComponentHeader
|
|
forClassComponentWithUnresolvedFieldOffset() {
|
|
return KeyPathComponentHeader(
|
|
(_SwiftKeyPathComponentHeader_ClassTag
|
|
<< _SwiftKeyPathComponentHeader_DiscriminatorShift)
|
|
| _SwiftKeyPathComponentHeader_UnresolvedFieldOffsetPayload);
|
|
}
|
|
|
|
constexpr static KeyPathComponentHeader
|
|
forClassComponentWithUnresolvedIndirectOffset() {
|
|
return KeyPathComponentHeader(
|
|
(_SwiftKeyPathComponentHeader_ClassTag
|
|
<< _SwiftKeyPathComponentHeader_DiscriminatorShift)
|
|
| _SwiftKeyPathComponentHeader_UnresolvedIndirectOffsetPayload);
|
|
}
|
|
|
|
constexpr static KeyPathComponentHeader
|
|
forOptionalChain() {
|
|
return KeyPathComponentHeader(
|
|
(_SwiftKeyPathComponentHeader_OptionalTag
|
|
<< _SwiftKeyPathComponentHeader_DiscriminatorShift)
|
|
| _SwiftKeyPathComponentHeader_OptionalChainPayload);
|
|
}
|
|
constexpr static KeyPathComponentHeader
|
|
forOptionalWrap() {
|
|
return KeyPathComponentHeader(
|
|
(_SwiftKeyPathComponentHeader_OptionalTag
|
|
<< _SwiftKeyPathComponentHeader_DiscriminatorShift)
|
|
| _SwiftKeyPathComponentHeader_OptionalWrapPayload);
|
|
}
|
|
constexpr static KeyPathComponentHeader
|
|
forOptionalForce() {
|
|
return KeyPathComponentHeader(
|
|
(_SwiftKeyPathComponentHeader_OptionalTag
|
|
<< _SwiftKeyPathComponentHeader_DiscriminatorShift)
|
|
| _SwiftKeyPathComponentHeader_OptionalForcePayload);
|
|
}
|
|
|
|
enum ComputedPropertyKind {
|
|
GetOnly,
|
|
SettableNonmutating,
|
|
SettableMutating,
|
|
};
|
|
|
|
enum ComputedPropertyIDKind {
|
|
Pointer,
|
|
StoredPropertyIndex,
|
|
VTableOffset,
|
|
};
|
|
|
|
constexpr static uint32_t
|
|
getResolutionStrategy(ComputedPropertyIDKind idKind) {
|
|
return idKind == Pointer ? _SwiftKeyPathComponentHeader_ComputedIDUnresolvedIndirectPointer
|
|
: (assert("no resolution strategy implemented" && false), 0);
|
|
}
|
|
|
|
constexpr static KeyPathComponentHeader
|
|
forComputedProperty(ComputedPropertyKind kind,
|
|
ComputedPropertyIDKind idKind,
|
|
bool hasArguments,
|
|
bool resolvedID) {
|
|
return KeyPathComponentHeader(
|
|
(_SwiftKeyPathComponentHeader_ComputedTag
|
|
<< _SwiftKeyPathComponentHeader_DiscriminatorShift)
|
|
| (kind != GetOnly
|
|
? _SwiftKeyPathComponentHeader_ComputedSettableFlag : 0)
|
|
| (kind == SettableMutating
|
|
? _SwiftKeyPathComponentHeader_ComputedMutatingFlag : 0)
|
|
| (idKind == StoredPropertyIndex
|
|
? _SwiftKeyPathComponentHeader_ComputedIDByStoredPropertyFlag : 0)
|
|
| (idKind == VTableOffset
|
|
? _SwiftKeyPathComponentHeader_ComputedIDByVTableOffsetFlag : 0)
|
|
| (hasArguments ? _SwiftKeyPathComponentHeader_ComputedHasArgumentsFlag : 0)
|
|
| (resolvedID ? _SwiftKeyPathComponentHeader_ComputedIDResolved
|
|
: getResolutionStrategy(idKind)));
|
|
}
|
|
|
|
constexpr static KeyPathComponentHeader
|
|
forExternalComponent() {
|
|
return KeyPathComponentHeader(
|
|
_SwiftKeyPathComponentHeader_ExternalTag
|
|
<< _SwiftKeyPathComponentHeader_DiscriminatorShift);
|
|
}
|
|
|
|
constexpr uint32_t getData() const { return Data; }
|
|
};
|
|
|
|
}
|
|
|
|
#endif
|