Skip to content

Commit ed8ca25

Browse files
committed
Runtime: Clean up logic for setting Objective-C name of generic classes
We're not currently doing it, but we will soon be able to use swift_initializeSuperclass() for class layouts which are not dependent on generic parameters. In this case, we still need to set the Objective-C class name. On the other hand, if we're doing resilient layout for a non-generic class, we don't need to set the Objective-C class name. NFC since this isn't hooked up completely yet.
1 parent 45c8282 commit ed8ca25

File tree

1 file changed

+56
-59
lines changed

1 file changed

+56
-59
lines changed

stdlib/public/runtime/Metadata.cpp

Lines changed: 56 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -1406,50 +1406,6 @@ void swift::swift_initStructMetadata_UniversalStrategy(size_t numFields,
14061406

14071407
/*** Classes ***************************************************************/
14081408

1409-
1410-
1411-
static void _swift_initializeSuperclass(ClassMetadata *theClass,
1412-
const ClassMetadata *theSuperclass,
1413-
bool copyFieldOffsetVectors) {
1414-
// If any ancestors had generic parameters or field offset vectors,
1415-
// inherit them.
1416-
auto ancestor = theSuperclass;
1417-
auto *classWords = reinterpret_cast<uintptr_t *>(theClass);
1418-
auto *superWords = reinterpret_cast<const uintptr_t *>(theSuperclass);
1419-
while (ancestor && ancestor->isTypeMetadata()) {
1420-
auto description = ancestor->getDescription();
1421-
auto &genericParams = description->GenericParams;
1422-
if (genericParams.hasGenericParams()) {
1423-
unsigned numParamWords = 0;
1424-
for (unsigned i = 0; i < genericParams.NumParams; ++i) {
1425-
// 1 word for the type metadata, and 1 for every protocol witness
1426-
numParamWords +=
1427-
1 + genericParams.Parameters[i].NumWitnessTables;
1428-
}
1429-
memcpy(classWords + genericParams.Offset,
1430-
superWords + genericParams.Offset,
1431-
numParamWords * sizeof(uintptr_t));
1432-
}
1433-
if (copyFieldOffsetVectors &&
1434-
description->Class.hasFieldOffsetVector()) {
1435-
unsigned fieldOffsetVector = description->Class.FieldOffsetVectorOffset;
1436-
memcpy(classWords + fieldOffsetVector,
1437-
superWords + fieldOffsetVector,
1438-
description->Class.NumFields * sizeof(uintptr_t));
1439-
}
1440-
ancestor = ancestor->SuperClass;
1441-
}
1442-
1443-
#if SWIFT_OBJC_INTEROP
1444-
// Set up the superclass of the metaclass, which is the metaclass of the
1445-
// superclass.
1446-
auto theMetaclass = (ClassMetadata *)object_getClass((id)theClass);
1447-
auto theSuperMetaclass
1448-
= (const ClassMetadata *)object_getClass((id)theSuperclass);
1449-
theMetaclass->SuperClass = theSuperMetaclass;
1450-
#endif
1451-
}
1452-
14531409
namespace {
14541410
/// The structure of ObjC class ivars as emitted by compilers.
14551411
struct ClassIvarEntry {
@@ -1530,31 +1486,76 @@ static void _swift_initGenericClassObjCName(ClassMetadata *theClass) {
15301486
}
15311487
#endif
15321488

1489+
static void _swift_initializeSuperclass(ClassMetadata *theClass,
1490+
bool copyFieldOffsetVectors) {
1491+
#if SWIFT_OBJC_INTEROP
1492+
// If the class is generic, we need to give it a name for Objective-C.
1493+
if (theClass->getDescription()->GenericParams.NumParams > 0)
1494+
_swift_initGenericClassObjCName(theClass);
1495+
#endif
1496+
1497+
const ClassMetadata *theSuperclass = theClass->SuperClass;
1498+
if (theSuperclass == nullptr)
1499+
return;
1500+
1501+
// If any ancestors had generic parameters or field offset vectors,
1502+
// inherit them.
1503+
auto ancestor = theSuperclass;
1504+
auto *classWords = reinterpret_cast<uintptr_t *>(theClass);
1505+
auto *superWords = reinterpret_cast<const uintptr_t *>(theSuperclass);
1506+
while (ancestor && ancestor->isTypeMetadata()) {
1507+
auto description = ancestor->getDescription();
1508+
auto &genericParams = description->GenericParams;
1509+
if (genericParams.hasGenericParams()) {
1510+
unsigned numParamWords = 0;
1511+
for (unsigned i = 0; i < genericParams.NumParams; ++i) {
1512+
// 1 word for the type metadata, and 1 for every protocol witness
1513+
numParamWords +=
1514+
1 + genericParams.Parameters[i].NumWitnessTables;
1515+
}
1516+
memcpy(classWords + genericParams.Offset,
1517+
superWords + genericParams.Offset,
1518+
numParamWords * sizeof(uintptr_t));
1519+
}
1520+
if (copyFieldOffsetVectors &&
1521+
description->Class.hasFieldOffsetVector()) {
1522+
unsigned fieldOffsetVector = description->Class.FieldOffsetVectorOffset;
1523+
memcpy(classWords + fieldOffsetVector,
1524+
superWords + fieldOffsetVector,
1525+
description->Class.NumFields * sizeof(uintptr_t));
1526+
}
1527+
ancestor = ancestor->SuperClass;
1528+
}
1529+
1530+
#if SWIFT_OBJC_INTEROP
1531+
// Set up the superclass of the metaclass, which is the metaclass of the
1532+
// superclass.
1533+
auto theMetaclass = (ClassMetadata *)object_getClass((id)theClass);
1534+
auto theSuperMetaclass
1535+
= (const ClassMetadata *)object_getClass((id)theSuperclass);
1536+
theMetaclass->SuperClass = theSuperMetaclass;
1537+
#endif
1538+
}
1539+
15331540
/// Initialize the field offset vector for a dependent-layout class, using the
15341541
/// "Universal" layout strategy.
15351542
void swift::swift_initClassMetadata_UniversalStrategy(ClassMetadata *self,
15361543
size_t numFields,
15371544
const ClassFieldLayout *fieldLayouts,
15381545
size_t *fieldOffsets) {
1539-
const ClassMetadata *super = self->SuperClass;
1540-
1541-
if (super) {
1542-
_swift_initializeSuperclass(self, super,
1543-
/*copyFieldOffsetVectors=*/true);
1544-
}
1546+
_swift_initializeSuperclass(self, /*copyFieldOffsetVectors=*/true);
15451547

15461548
// Start layout by appending to a standard heap object header.
15471549
size_t size, alignMask;
15481550

15491551
#if SWIFT_OBJC_INTEROP
1550-
ClassROData *rodata = (ClassROData*) (self->Data & ~uintptr_t(1));
1551-
1552-
// Generate a runtime name for the class.
1553-
_swift_initGenericClassObjCName(self);
1552+
ClassROData *rodata = getROData(self);
15541553
#endif
15551554

15561555
// If we have a superclass, start from its size and alignment instead.
15571556
if (classHasSuperclass(self)) {
1557+
const ClassMetadata *super = self->SuperClass;
1558+
15581559
// This is straightforward if the superclass is Swift.
15591560
#if SWIFT_OBJC_INTEROP
15601561
if (super->isTypeMetadata()) {
@@ -2495,11 +2496,7 @@ extern "C"
24952496
void swift_initializeSuperclass(ClassMetadata *theClass,
24962497
bool copyFieldOffsetVectors) {
24972498
// Copy generic parameters and field offset vectors from the superclass.
2498-
const ClassMetadata *theSuperclass = theClass->SuperClass;
2499-
if (theSuperclass) {
2500-
_swift_initializeSuperclass(theClass, theSuperclass,
2501-
copyFieldOffsetVectors);
2502-
}
2499+
_swift_initializeSuperclass(theClass, copyFieldOffsetVectors);
25032500

25042501
#if SWIFT_OBJC_INTEROP
25052502
// Register the class pair with the ObjC runtime.

0 commit comments

Comments
 (0)