39
39
#if SWIFT_OBJC_INTEROP
40
40
#include < objc/runtime.h>
41
41
#endif
42
+ #include " llvm/Support/Casting.h"
42
43
43
44
namespace swift {
44
45
@@ -1029,13 +1030,22 @@ struct GenericContextDescriptor {
1029
1030
};
1030
1031
1031
1032
// / Header for a generic parameter descriptor.
1032
- struct GenericParameterDescriptorHeader {
1033
+ template <typename Runtime>
1034
+ struct TargetGenericParameterDescriptorHeader {
1035
+ using StoredPointer = typename Runtime::StoredPointer;
1036
+ using ClassMetadata = TargetClassMetadata<Runtime>;
1037
+
1038
+ private:
1033
1039
// / The offset to the first generic argument from the start of
1034
- // / metadata record.
1040
+ // / metadata record, in words .
1035
1041
// /
1036
1042
// / This is meaningful if NumGenericRequirements is nonzero.
1043
+ // /
1044
+ // / If this class has a resilient superclass, this offset is relative to the
1045
+ // / size of the resilient superclass metadata. Otherwise, it is absolute.
1037
1046
uint32_t Offset;
1038
1047
1048
+ public:
1039
1049
// / The amount of generic requirement data in the metadata record, in
1040
1050
// / words, excluding the lexical parent type. A value of zero means
1041
1051
// / there is no generic requirement data.
@@ -1056,6 +1066,30 @@ struct GenericParameterDescriptorHeader {
1056
1066
// / Flags for this generic parameter descriptor.
1057
1067
GenericParameterDescriptorFlags Flags;
1058
1068
1069
+ // / This is factored in a silly way because remote mirrors cannot directly
1070
+ // / dereference the SuperClass field of class metadata.
1071
+ uint32_t getOffset (const ClassMetadata *classMetadata,
1072
+ const ClassMetadata *superMetadata) const {
1073
+ if (Flags.hasResilientSuperclass ())
1074
+ return superMetadata->getSizeInWords () + Offset;
1075
+
1076
+ return Offset;
1077
+ }
1078
+
1079
+ uint32_t getOffset () const {
1080
+ assert (!Flags.hasResilientSuperclass ());
1081
+ return Offset;
1082
+ }
1083
+
1084
+ uint32_t getOffset (const TargetMetadata<Runtime> *metadata) const {
1085
+ if (auto *classMetadata = llvm::dyn_cast<ClassMetadata>(metadata))
1086
+ if (auto *superclass = classMetadata->SuperClass )
1087
+ if (auto *superMetadata = llvm::dyn_cast<ClassMetadata>(superclass))
1088
+ return getOffset (classMetadata, superMetadata);
1089
+
1090
+ return getOffset ();
1091
+ }
1092
+
1059
1093
// / True if the nominal type has generic requirements other than its
1060
1094
// / parent metadata.
1061
1095
bool hasGenericRequirements () const { return NumGenericRequirements > 0 ; }
@@ -1080,14 +1114,31 @@ struct TargetMethodDescriptor {
1080
1114
// / Header for a class vtable descriptor. This is a variable-sized
1081
1115
// / structure that describes how to find and parse a vtable
1082
1116
// / within the type metadata for a class.
1083
- struct VTableDescriptorHeader {
1084
- // / The offset of the vtable for this class in its metadata, if any.
1117
+ template <typename Runtime>
1118
+ struct TargetVTableDescriptorHeader {
1119
+ using StoredPointer = typename Runtime::StoredPointer;
1120
+
1121
+ private:
1122
+ // / The offset of the vtable for this class in its metadata, if any,
1123
+ // / in words.
1124
+ // /
1125
+ // / If this class has a resilient superclass, this offset is relative to the
1126
+ // / size of the resilient superclass metadata. Otherwise, it is absolute.
1085
1127
uint32_t VTableOffset;
1128
+
1129
+ public:
1086
1130
// / The number of vtable entries. This is the number of MethodDescriptor
1087
1131
// / records following the vtable header in the class's nominal type
1088
1132
// / descriptor, which is equal to the number of words this subclass's vtable
1089
1133
// / entries occupy in instantiated class metadata.
1090
1134
uint32_t VTableSize;
1135
+
1136
+ uint32_t getVTableOffset (const TargetClassMetadata<Runtime> *metadata) const {
1137
+ const auto *description = metadata->getDescription ();
1138
+ if (description->GenericParams .Flags .hasResilientSuperclass ())
1139
+ return metadata->SuperClass ->getSizeInWords () + VTableOffset;
1140
+ return VTableOffset;
1141
+ }
1091
1142
};
1092
1143
1093
1144
template <typename Runtime> struct TargetNominalTypeDescriptor ;
@@ -1096,7 +1147,7 @@ template<typename Runtime>
1096
1147
using TargetNominalTypeDescriptorTrailingObjects
1097
1148
= swift::ABI::TrailingObjects<TargetNominalTypeDescriptor<Runtime>,
1098
1149
GenericContextDescriptor,
1099
- VTableDescriptorHeader ,
1150
+ TargetVTableDescriptorHeader<Runtime> ,
1100
1151
TargetMethodDescriptor<Runtime>>;
1101
1152
1102
1153
// / Common information about all nominal types. For generic types, this
@@ -1116,6 +1167,9 @@ struct TargetNominalTypeDescriptor final
1116
1167
public:
1117
1168
using StoredPointer = typename Runtime::StoredPointer;
1118
1169
using MethodDescriptor = TargetMethodDescriptor<Runtime>;
1170
+ using VTableDescriptorHeader = TargetVTableDescriptorHeader<Runtime>;
1171
+ using GenericParameterDescriptorHeader = TargetGenericParameterDescriptorHeader<Runtime>;
1172
+ using ClassMetadata = TargetClassMetadata<Runtime>;
1119
1173
1120
1174
// / The mangled name of the nominal type.
1121
1175
TargetRelativeDirectPointer<Runtime, const char > Name;
@@ -1127,19 +1181,22 @@ struct TargetNominalTypeDescriptor final
1127
1181
// / The number of stored properties in the class, not including its
1128
1182
// / superclasses. If there is a field offset vector, this is its length.
1129
1183
uint32_t NumFields;
1184
+
1185
+ private:
1130
1186
// / The offset of the field offset vector for this class's stored
1131
- // / properties in its metadata, if any . 0 means there is no field offset
1187
+ // / properties in its metadata, in words . 0 means there is no field offset
1132
1188
// / vector.
1133
1189
// /
1134
- // / To deal with resilient superclasses correctly , this will
1135
- // / eventually need to be relative to the start of this class's
1136
- // / metadata area .
1190
+ // / If this class has a resilient superclass , this offset is relative to
1191
+ // / the size of the resilient superclass metadata. Otherwise, it is
1192
+ // / absolute .
1137
1193
uint32_t FieldOffsetVectorOffset;
1138
-
1194
+
1195
+ public:
1139
1196
// / The field names. A doubly-null-terminated list of strings, whose
1140
1197
// / length and order is consistent with that of the field offset vector.
1141
1198
RelativeDirectPointer<const char , /* nullable*/ true > FieldNames;
1142
-
1199
+
1143
1200
// / The field type vector accessor. Returns a pointer to an array of
1144
1201
// / type metadata references whose order is consistent with that of the
1145
1202
// / field offset vector.
@@ -1148,7 +1205,16 @@ struct TargetNominalTypeDescriptor final
1148
1205
1149
1206
// / True if metadata records for this type have a field offset vector for
1150
1207
// / its stored properties.
1151
- bool hasFieldOffsetVector () const { return FieldOffsetVectorOffset != 0 ; }
1208
+ bool hasFieldOffsetVector () const { return FieldOffsetVectorOffset != 0 ; }
1209
+
1210
+ unsigned getFieldOffsetVectorOffset (const ClassMetadata *metadata) const {
1211
+ const auto *description = metadata->getDescription ();
1212
+
1213
+ if (description->GenericParams .Flags .hasResilientSuperclass ())
1214
+ return metadata->SuperClass ->getSizeInWords () + FieldOffsetVectorOffset;
1215
+
1216
+ return FieldOffsetVectorOffset;
1217
+ }
1152
1218
} Class;
1153
1219
1154
1220
// / Information about struct types.
@@ -1503,7 +1569,7 @@ struct TargetClassMetadata : public TargetHeapMetadata<Runtime> {
1503
1569
// / Get a pointer to the field offset vector, if present, or null.
1504
1570
const StoredPointer *getFieldOffsets () const {
1505
1571
assert (isTypeMetadata ());
1506
- auto offset = getDescription ()->Class .FieldOffsetVectorOffset ;
1572
+ auto offset = getDescription ()->Class .getFieldOffsetVectorOffset ( this ) ;
1507
1573
if (offset == 0 )
1508
1574
return nullptr ;
1509
1575
auto asWords = reinterpret_cast <const void * const *>(this );
@@ -1520,6 +1586,13 @@ struct TargetClassMetadata : public TargetHeapMetadata<Runtime> {
1520
1586
return getter (this );
1521
1587
}
1522
1588
1589
+ uint32_t getSizeInWords () const {
1590
+ assert (isTypeMetadata ());
1591
+ uint32_t size = getClassSize () - getClassAddressPoint ();
1592
+ assert (size % sizeof (StoredPointer) == 0 );
1593
+ return size / sizeof (StoredPointer);
1594
+ }
1595
+
1523
1596
static bool classof (const TargetMetadata<Runtime> *metadata) {
1524
1597
return metadata->getKind () == MetadataKind::Class;
1525
1598
}
@@ -1768,7 +1841,7 @@ struct TargetValueMetadata : public TargetMetadata<Runtime> {
1768
1841
1769
1842
auto asWords = reinterpret_cast <
1770
1843
ConstTargetMetadataPointer<Runtime, swift::TargetMetadata> const *>(this );
1771
- return (asWords + Description->GenericParams .Offset );
1844
+ return (asWords + Description->GenericParams .getOffset ( this ) );
1772
1845
}
1773
1846
1774
1847
const TargetNominalTypeDescriptor<Runtime> *getDescription () const {
0 commit comments