Skip to content

Commit 4e1962a

Browse files
committed
[RemoteMirror] Fix generic subclasses of resilient superclasses with non-resilient super-superclasses.
When we hit the end of the hasResilientSuperclass chain, compute the bounds using the class descriptor's data instead of using the root class bounds and adjusting them. rdar://134448718
1 parent a3c9ba1 commit 4e1962a

File tree

1 file changed

+27
-4
lines changed

1 file changed

+27
-4
lines changed

include/swift/Remote/MetadataReader.h

Lines changed: 27 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -1814,7 +1814,7 @@ class MetadataReader {
18141814
if (!type->hasResilientSuperclass())
18151815
return type->getNonResilientGenericArgumentOffset();
18161816

1817-
auto bounds = readMetadataBoundsOfSuperclass(descriptor);
1817+
auto bounds = computeMetadataBoundsFromSuperclass(descriptor);
18181818
if (!bounds)
18191819
return std::nullopt;
18201820

@@ -1838,9 +1838,32 @@ class MetadataReader {
18381838

18391839
using ClassMetadataBounds = TargetClassMetadataBounds<Runtime>;
18401840

1841-
// This follows computeMetadataBoundsForSuperclass.
1841+
// This follows getMetadataBounds in ABI/Metadata.h.
18421842
std::optional<ClassMetadataBounds>
1843-
readMetadataBoundsOfSuperclass(ContextDescriptorRef subclassRef) {
1843+
getClassMetadataBounds(ContextDescriptorRef classRef) {
1844+
auto classDescriptor = cast<TargetClassDescriptor<Runtime>>(classRef);
1845+
1846+
if (!classDescriptor->hasResilientSuperclass()) {
1847+
auto nonResilientImmediateMembersOffset =
1848+
classDescriptor->areImmediateMembersNegative()
1849+
? -int32_t(classDescriptor->MetadataNegativeSizeInWords)
1850+
: int32_t(classDescriptor->MetadataPositiveSizeInWords -
1851+
classDescriptor->NumImmediateMembers);
1852+
typename Runtime::StoredPointerDifference immediateMembersOffset =
1853+
nonResilientImmediateMembersOffset * sizeof(StoredPointer);
1854+
1855+
ClassMetadataBounds bounds{immediateMembersOffset,
1856+
classDescriptor->MetadataNegativeSizeInWords,
1857+
classDescriptor->MetadataPositiveSizeInWords};
1858+
return bounds;
1859+
}
1860+
1861+
return computeMetadataBoundsFromSuperclass(classRef);
1862+
}
1863+
1864+
// This follows computeMetadataBoundsFromSuperclass in Metadata.cpp.
1865+
std::optional<ClassMetadataBounds>
1866+
computeMetadataBoundsFromSuperclass(ContextDescriptorRef subclassRef) {
18441867
auto subclass = cast<TargetClassDescriptor<Runtime>>(subclassRef);
18451868
std::optional<ClassMetadataBounds> bounds;
18461869

@@ -1859,7 +1882,7 @@ class MetadataReader {
18591882
-> std::optional<ClassMetadataBounds> {
18601883
if (!isa<TargetClassDescriptor<Runtime>>(superclass))
18611884
return std::nullopt;
1862-
return readMetadataBoundsOfSuperclass(superclass);
1885+
return getClassMetadataBounds(superclass);
18631886
},
18641887
[&](MetadataRef metadata) -> std::optional<ClassMetadataBounds> {
18651888
auto cls = dyn_cast<TargetClassMetadata>(metadata);

0 commit comments

Comments
 (0)