Skip to content

Commit c8e3724

Browse files
authored
Merge pull request #13926 from xedin/rdar-26060144
[Runtime/ABI] Replace `emitTypeFieldAccessor` with a single runtime method
2 parents 535b12f + 4370190 commit c8e3724

32 files changed

+577
-557
lines changed

include/swift/Demangling/TypeDecoder.h

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -124,7 +124,8 @@ class TypeDecoder {
124124
}
125125
case NodeKind::BoundGenericClass:
126126
case NodeKind::BoundGenericEnum:
127-
case NodeKind::BoundGenericStructure: {
127+
case NodeKind::BoundGenericStructure:
128+
case NodeKind::BoundGenericOtherNominalType: {
128129
if (Node->getNumChildren() != 2)
129130
return BuiltType();
130131

include/swift/Reflection/Records.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,7 @@
1919

2020
#include "swift/Basic/RelativePointer.h"
2121
#include "swift/Demangling/Demangle.h"
22+
#include "llvm/ADT/ArrayRef.h"
2223

2324
const uint16_t SWIFT_REFLECTION_METADATA_VERSION = 3; // superclass field
2425

@@ -204,6 +205,10 @@ class FieldDescriptor {
204205
return const_iterator { End, End };
205206
}
206207

208+
llvm::ArrayRef<FieldRecord> getFields() const {
209+
return {getFieldRecordBuffer(), NumFields};
210+
}
211+
207212
bool hasMangledTypeName() const {
208213
return MangledTypeName;
209214
}

include/swift/Runtime/Metadata.h

Lines changed: 33 additions & 48 deletions
Original file line numberDiff line numberDiff line change
@@ -37,11 +37,13 @@
3737
#include "swift/Basic/RelativePointer.h"
3838
#include "swift/Demangling/Demangle.h"
3939
#include "swift/Demangling/ManglingMacros.h"
40+
#include "swift/Reflection/Records.h"
4041
#include "swift/Runtime/Unreachable.h"
4142
#include "../../../stdlib/public/SwiftShims/HeapObject.h"
4243
#if SWIFT_OBJC_INTEROP
4344
#include <objc/runtime.h>
4445
#endif
46+
#include "llvm/ADT/STLExtras.h"
4547
#include "llvm/Support/Casting.h"
4648

4749
namespace swift {
@@ -1287,16 +1289,6 @@ struct TargetClassMetadata : public TargetHeapMetadata<Runtime> {
12871289
auto asWords = reinterpret_cast<const void * const*>(this);
12881290
return reinterpret_cast<const StoredPointer *>(asWords + offset);
12891291
}
1290-
1291-
/// Get a pointer to the field type vector, if present, or null.
1292-
const FieldType *getFieldTypes() const {
1293-
assert(isTypeMetadata());
1294-
auto *getter = getDescription()->GetFieldTypes.get();
1295-
if (!getter)
1296-
return nullptr;
1297-
1298-
return getter(this);
1299-
}
13001292

13011293
uint32_t getSizeInWords() const {
13021294
assert(isTypeMetadata());
@@ -1569,15 +1561,6 @@ struct TargetStructMetadata : public TargetValueMetadata<Runtime> {
15691561
auto asWords = reinterpret_cast<const void * const*>(this);
15701562
return reinterpret_cast<const StoredPointer *>(asWords + offset);
15711563
}
1572-
1573-
/// Get a pointer to the field type vector, if present, or null.
1574-
const FieldType *getFieldTypes() const {
1575-
auto *getter = getDescription()->GetFieldTypes.get();
1576-
if (!getter)
1577-
return nullptr;
1578-
1579-
return getter(this);
1580-
}
15811564

15821565
static bool classof(const TargetMetadata<Runtime> *metadata) {
15831566
return metadata->getKind() == MetadataKind::Struct;
@@ -2531,6 +2514,12 @@ struct TargetContextDescriptor {
25312514
/// context is not generic.
25322515
const TargetGenericContext<Runtime> *getGenericContext() const;
25332516

2517+
unsigned getNumGenericParams() const {
2518+
auto *genericContext = getGenericContext();
2519+
return genericContext
2520+
? genericContext->getGenericContextHeader().NumParams
2521+
: 0;
2522+
}
25342523
private:
25352524
TargetContextDescriptor(const TargetContextDescriptor &) = delete;
25362525
TargetContextDescriptor(TargetContextDescriptor &&) = delete;
@@ -3165,15 +3154,11 @@ class TargetClassDescriptor final
31653154
}
31663155

31673156
public:
3168-
/// The field names. A doubly-null-terminated list of strings, whose
3169-
/// length and order is consistent with that of the field offset vector.
3170-
RelativeDirectPointer<const char, /*nullable*/ true> FieldNames;
3171-
3172-
/// The field type vector accessor. Returns a pointer to an array of
3173-
/// type metadata references whose order is consistent with that of the
3174-
/// field offset vector.
3175-
RelativeDirectPointer<const FieldType *
3176-
(const TargetMetadata<Runtime> *)> GetFieldTypes;
3157+
/// Indicates if the type represented by this descriptor
3158+
/// supports reflection (C and Obj-C enums currently don't).
3159+
/// FIXME: This is temporarily left as 32-bit integer to avoid
3160+
/// changing layout of context descriptor.
3161+
uint32_t IsReflectable;
31773162

31783163
/// True if metadata records for this type have a field offset vector for
31793164
/// its stored properties.
@@ -3275,15 +3260,11 @@ class TargetStructDescriptor final
32753260
/// vector.
32763261
uint32_t FieldOffsetVectorOffset;
32773262

3278-
/// The field names. A doubly-null-terminated list of strings, whose
3279-
/// length and order is consistent with that of the field offset vector.
3280-
RelativeDirectPointer<const char, /*nullable*/ true> FieldNames;
3281-
3282-
/// The field type vector accessor. Returns a pointer to an array of
3283-
/// type metadata references whose order is consistent with that of the
3284-
/// field offset vector.
3285-
RelativeDirectPointer<const FieldType *
3286-
(const TargetMetadata<Runtime> *)> GetFieldTypes;
3263+
/// Indicates if the type represented by this descriptor
3264+
/// supports reflection (C and Obj-C enums currently don't).
3265+
/// FIXME: This is temporarily left as 32-bit integer to avoid
3266+
/// changing layout of context descriptor.
3267+
uint32_t IsReflectable;
32873268

32883269
/// True if metadata records for this type have a field offset vector for
32893270
/// its stored properties.
@@ -3327,17 +3308,11 @@ class TargetEnumDescriptor final
33273308
/// The number of empty cases in the enum.
33283309
uint32_t NumEmptyCases;
33293310

3330-
/// The names of the cases. A doubly-null-terminated list of strings,
3331-
/// whose length is NumNonEmptyCases + NumEmptyCases. Cases are named in
3332-
/// tag order, non-empty cases first, followed by empty cases.
3333-
RelativeDirectPointer<const char, /*nullable*/ true> CaseNames;
3334-
3335-
/// The field type vector accessor. Returns a pointer to an array of
3336-
/// type metadata references whose order is consistent with that of the
3337-
/// CaseNames. Only types for payload cases are provided.
3338-
RelativeDirectPointer<
3339-
const FieldType * (const TargetMetadata<Runtime> *)>
3340-
GetCaseTypes;
3311+
/// Indicates if the type represented by this descriptor
3312+
/// supports reflection (C and Obj-C enums currently don't).
3313+
/// FIXME: This is temporarily left as 32-bit integer to avoid
3314+
/// changing layout of context descriptor.
3315+
uint32_t IsReflectable;
33413316

33423317
uint32_t getNumPayloadCases() const {
33433318
return NumPayloadCasesAndPayloadSizeOffset & 0x00FFFFFFU;
@@ -3760,12 +3735,22 @@ SWIFT_RUNTIME_EXPORT
37603735
void swift_registerTypeMetadataRecords(const TypeMetadataRecord *begin,
37613736
const TypeMetadataRecord *end);
37623737

3738+
/// Register a block of type field records for dynamic lookup.
3739+
SWIFT_RUNTIME_EXPORT
3740+
void swift_registerFieldDescriptors(const reflection::FieldDescriptor **records,
3741+
size_t size);
3742+
37633743
/// Return the superclass, if any. The result is nullptr for root
37643744
/// classes and class protocol types.
37653745
SWIFT_CC(swift)
37663746
SWIFT_RUNTIME_STDLIB_INTERFACE
37673747
const Metadata *_swift_class_getSuperclass(const Metadata *theClass);
37683748

3749+
SWIFT_RUNTIME_STDLIB_INTERFACE
3750+
void swift_getFieldAt(
3751+
const Metadata *type, unsigned index,
3752+
std::function<void(llvm::StringRef name, FieldType type)> callback);
3753+
37693754
} // end namespace swift
37703755

37713756
#pragma clang diagnostic pop

include/swift/Runtime/RuntimeFunctions.def

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1198,6 +1198,11 @@ FUNCTION(RegisterTypeMetadataRecords,
11981198
RETURNS(VoidTy),
11991199
ARGS(TypeMetadataRecordPtrTy, TypeMetadataRecordPtrTy),
12001200
ATTRS(NoUnwind))
1201+
FUNCTION(RegisterFieldDescriptors,
1202+
swift_registerFieldDescriptors, DefaultCC,
1203+
RETURNS(VoidTy),
1204+
ARGS(FieldDescriptorPtrPtrTy, SizeTy),
1205+
ATTRS(NoUnwind))
12011206

12021207
// void swift_beginAccess(void *pointer, ValueBuffer *scratch, size_t flags);
12031208
FUNCTION(BeginAccess, swift_beginAccess, C_CC,

lib/Demangling/Demangler.cpp

Lines changed: 31 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,10 @@ static bool isAnyGeneric(Node::Kind kind) {
6565
case Node::Kind::Class:
6666
case Node::Kind::Enum:
6767
case Node::Kind::Protocol:
68+
case Node::Kind::OtherNominalType:
6869
case Node::Kind::TypeAlias:
70+
case Node::Kind::SymbolicReference:
71+
case Node::Kind::UnresolvedSymbolicReference:
6972
return true;
7073
default:
7174
return false;
@@ -1237,11 +1240,35 @@ NodePointer Demangler::demangleBoundGenericType() {
12371240
NodePointer Demangler::demangleBoundGenericArgs(NodePointer Nominal,
12381241
const Vector<NodePointer> &TypeLists,
12391242
size_t TypeListIdx) {
1240-
if (!Nominal || Nominal->getNumChildren() < 2)
1243+
// TODO: This would be a lot easier if we represented bound generic args
1244+
// flatly in the demangling tree, since that's how they're mangled and also
1245+
// how the runtime generally wants to consume them.
1246+
1247+
if (!Nominal)
12411248
return nullptr;
12421249

12431250
if (TypeListIdx >= TypeLists.size())
12441251
return nullptr;
1252+
1253+
// Associate a symbolic reference with all remaining generic arguments.
1254+
if (Nominal->getKind() == Node::Kind::SymbolicReference
1255+
|| Nominal->getKind() == Node::Kind::UnresolvedSymbolicReference) {
1256+
auto remainingTypeList = createNode(Node::Kind::TypeList);
1257+
for (unsigned i = TypeLists.size() - 1;
1258+
i >= TypeListIdx && i < TypeLists.size();
1259+
--i) {
1260+
auto list = TypeLists[i];
1261+
for (auto child : *list) {
1262+
remainingTypeList->addChild(child, *this);
1263+
}
1264+
}
1265+
return createWithChildren(Node::Kind::BoundGenericOtherNominalType,
1266+
createType(Nominal), remainingTypeList);
1267+
}
1268+
1269+
if (Nominal->getNumChildren() < 2)
1270+
return nullptr;
1271+
12451272
NodePointer args = TypeLists[TypeListIdx++];
12461273

12471274
// Generic arguments for the outermost type come first.
@@ -1286,6 +1313,9 @@ NodePointer Demangler::demangleBoundGenericArgs(NodePointer Nominal,
12861313
case Node::Kind::Enum:
12871314
kind = Node::Kind::BoundGenericEnum;
12881315
break;
1316+
case Node::Kind::OtherNominalType:
1317+
kind = Node::Kind::BoundGenericOtherNominalType;
1318+
break;
12891319
default:
12901320
return nullptr;
12911321
}

lib/Demangling/Remangler.cpp

Lines changed: 7 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -470,6 +470,7 @@ void Remangler::mangleGenericArgs(Node *node, char &Separator) {
470470
Separator = '_';
471471
break;
472472

473+
case Node::Kind::BoundGenericOtherNominalType:
473474
case Node::Kind::BoundGenericStructure:
474475
case Node::Kind::BoundGenericEnum:
475476
case Node::Kind::BoundGenericClass: {
@@ -1983,11 +1984,13 @@ bool Demangle::isSpecialized(Node *node) {
19831984
case Node::Kind::BoundGenericStructure:
19841985
case Node::Kind::BoundGenericEnum:
19851986
case Node::Kind::BoundGenericClass:
1987+
case Node::Kind::BoundGenericOtherNominalType:
19861988
return true;
19871989

19881990
case Node::Kind::Structure:
19891991
case Node::Kind::Enum:
19901992
case Node::Kind::Class:
1993+
case Node::Kind::OtherNominalType:
19911994
return isSpecialized(node->getChild(0));
19921995

19931996
case Node::Kind::Extension:
@@ -2002,7 +2005,8 @@ NodePointer Demangle::getUnspecialized(Node *node, NodeFactory &Factory) {
20022005
switch (node->getKind()) {
20032006
case Node::Kind::Structure:
20042007
case Node::Kind::Enum:
2005-
case Node::Kind::Class: {
2008+
case Node::Kind::Class:
2009+
case Node::Kind::OtherNominalType: {
20062010
NodePointer result = Factory.createNode(node->getKind());
20072011
NodePointer parentOrModule = node->getChild(0);
20082012
if (isSpecialized(parentOrModule))
@@ -2015,7 +2019,8 @@ NodePointer Demangle::getUnspecialized(Node *node, NodeFactory &Factory) {
20152019

20162020
case Node::Kind::BoundGenericStructure:
20172021
case Node::Kind::BoundGenericEnum:
2018-
case Node::Kind::BoundGenericClass: {
2022+
case Node::Kind::BoundGenericClass:
2023+
case Node::Kind::BoundGenericOtherNominalType: {
20192024
NodePointer unboundType = node->getChild(0);
20202025
assert(unboundType->getKind() == Node::Kind::Type);
20212026
NodePointer nominalType = unboundType->getChild(0);

lib/Demangling/TypeDecoder.cpp

Lines changed: 3 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -24,6 +24,7 @@ NodePointer Demangle::stripGenericArgsFromContextNode(const NodePointer &node,
2424
case Demangle::Node::Kind::BoundGenericClass:
2525
case Demangle::Node::Kind::BoundGenericEnum:
2626
case Demangle::Node::Kind::BoundGenericStructure:
27+
case Demangle::Node::Kind::BoundGenericOtherNominalType:
2728
// Bound generic types have a 'Type' node under them, whose child is
2829
// the non-generic reference. If we don't see that structure, do nothing.
2930
if (node->getNumChildren() < 2 ||
@@ -37,7 +38,8 @@ NodePointer Demangle::stripGenericArgsFromContextNode(const NodePointer &node,
3738

3839
case Demangle::Node::Kind::Class:
3940
case Demangle::Node::Kind::Enum:
40-
case Demangle::Node::Kind::Structure: {
41+
case Demangle::Node::Kind::Structure:
42+
case Demangle::Node::Kind::OtherNominalType: {
4143
if (node->getNumChildren() < 2)
4244
return node;
4345

lib/IDE/TypeReconstruction.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -2105,6 +2105,7 @@ static void VisitNode(
21052105
case Demangle::Node::Kind::BoundGenericClass:
21062106
case Demangle::Node::Kind::BoundGenericStructure:
21072107
case Demangle::Node::Kind::BoundGenericEnum:
2108+
case Demangle::Node::Kind::BoundGenericOtherNominalType:
21082109
VisitNodeBoundGeneric(ast, node, result);
21092110
break;
21102111

@@ -2115,6 +2116,7 @@ static void VisitNode(
21152116
case Demangle::Node::Kind::Structure:
21162117
case Demangle::Node::Kind::Class:
21172118
case Demangle::Node::Kind::Enum:
2119+
case Demangle::Node::Kind::OtherNominalType:
21182120
case Demangle::Node::Kind::Protocol:
21192121
VisitNodeNominal(ast, node, result);
21202122
break;

0 commit comments

Comments
 (0)