@@ -1814,13 +1814,10 @@ class MetadataReader {
1814
1814
if (!type->hasResilientSuperclass ())
1815
1815
return type->getNonResilientGenericArgumentOffset ();
1816
1816
1817
- auto bounds = readMetadataBoundsOfSuperclass (descriptor);
1817
+ auto bounds = computeMetadataBoundsFromSuperclass (descriptor);
1818
1818
if (!bounds)
1819
1819
return std::nullopt;
1820
1820
1821
- bounds->adjustForSubclass (type->areImmediateMembersNegative (),
1822
- type->NumImmediateMembers );
1823
-
1824
1821
return bounds->ImmediateMembersOffset / sizeof (StoredPointer);
1825
1822
}
1826
1823
@@ -1841,39 +1838,72 @@ class MetadataReader {
1841
1838
1842
1839
using ClassMetadataBounds = TargetClassMetadataBounds<Runtime>;
1843
1840
1844
- // This follows computeMetadataBoundsForSuperclass .
1841
+ // This follows getMetadataBounds in ABI/Metadata.h .
1845
1842
std::optional<ClassMetadataBounds>
1846
- readMetadataBoundsOfSuperclass (ContextDescriptorRef subclassRef) {
1847
- auto subclass = cast<TargetClassDescriptor<Runtime>>(subclassRef);
1848
- if (!subclass->hasResilientSuperclass ())
1849
- return ClassMetadataBounds::forSwiftRootClass ();
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);
1850
1854
1851
- auto rawSuperclass =
1852
- resolveRelativeField (subclassRef, subclass-> getResilientSuperclass ());
1853
- if (!rawSuperclass) {
1854
- return ClassMetadataBounds::forSwiftRootClass () ;
1855
+ ClassMetadataBounds bounds{immediateMembersOffset,
1856
+ classDescriptor-> MetadataNegativeSizeInWords ,
1857
+ classDescriptor-> MetadataPositiveSizeInWords };
1858
+ return bounds ;
1855
1859
}
1856
1860
1857
- return forTypeReference<ClassMetadataBounds>(
1858
- subclass->getResilientSuperclassReferenceKind (), rawSuperclass,
1859
- [&](ContextDescriptorRef superclass)
1860
- -> std::optional<ClassMetadataBounds> {
1861
- if (!isa<TargetClassDescriptor<Runtime>>(superclass))
1862
- return std::nullopt;
1863
- return readMetadataBoundsOfSuperclass (superclass);
1864
- },
1865
- [&](MetadataRef metadata) -> std::optional<ClassMetadataBounds> {
1866
- auto cls = dyn_cast<TargetClassMetadata>(metadata);
1867
- if (!cls)
1868
- return std::nullopt;
1861
+ return computeMetadataBoundsFromSuperclass (classRef);
1862
+ }
1869
1863
1870
- return cls->getClassBoundsAsSwiftSuperclass ();
1871
- },
1872
- [](StoredPointer objcClassName) -> std::optional<ClassMetadataBounds> {
1873
- // We have no ability to look up an ObjC class by name.
1874
- // FIXME: add a query for this; clients may have a way to do it.
1875
- return std::nullopt;
1876
- });
1864
+ // This follows computeMetadataBoundsFromSuperclass in Metadata.cpp.
1865
+ std::optional<ClassMetadataBounds>
1866
+ computeMetadataBoundsFromSuperclass (ContextDescriptorRef subclassRef) {
1867
+ auto subclass = cast<TargetClassDescriptor<Runtime>>(subclassRef);
1868
+ std::optional<ClassMetadataBounds> bounds;
1869
+
1870
+ if (!subclass->hasResilientSuperclass ()) {
1871
+ bounds = ClassMetadataBounds::forSwiftRootClass ();
1872
+ } else {
1873
+ auto rawSuperclass =
1874
+ resolveRelativeField (subclassRef, subclass->getResilientSuperclass ());
1875
+ if (!rawSuperclass) {
1876
+ return std::nullopt;
1877
+ }
1878
+
1879
+ bounds = forTypeReference<ClassMetadataBounds>(
1880
+ subclass->getResilientSuperclassReferenceKind (), rawSuperclass,
1881
+ [&](ContextDescriptorRef superclass)
1882
+ -> std::optional<ClassMetadataBounds> {
1883
+ if (!isa<TargetClassDescriptor<Runtime>>(superclass))
1884
+ return std::nullopt;
1885
+ return getClassMetadataBounds (superclass);
1886
+ },
1887
+ [&](MetadataRef metadata) -> std::optional<ClassMetadataBounds> {
1888
+ auto cls = dyn_cast<TargetClassMetadata>(metadata);
1889
+ if (!cls)
1890
+ return std::nullopt;
1891
+
1892
+ return cls->getClassBoundsAsSwiftSuperclass ();
1893
+ },
1894
+ [](StoredPointer objcClassName)
1895
+ -> std::optional<ClassMetadataBounds> {
1896
+ // We have no ability to look up an ObjC class by name.
1897
+ // FIXME: add a query for this; clients may have a way to do it.
1898
+ return std::nullopt;
1899
+ });
1900
+ }
1901
+ if (!bounds) {
1902
+ return std::nullopt;
1903
+ }
1904
+ bounds->adjustForSubclass (subclass->areImmediateMembersNegative (),
1905
+ subclass->NumImmediateMembers );
1906
+ return bounds;
1877
1907
}
1878
1908
1879
1909
template <class Result , class DescriptorFn , class MetadataFn ,
@@ -1885,11 +1915,12 @@ class MetadataReader {
1885
1915
const ClassNameFn &classNameFn) {
1886
1916
switch (refKind) {
1887
1917
case TypeReferenceKind::IndirectTypeDescriptor: {
1888
- StoredPointer descriptorAddress = 0 ;
1889
- if (!Reader->readInteger (RemoteAddress (ref), &descriptorAddress))
1918
+ StoredSignedPointer descriptorAddress;
1919
+ if (!Reader->readInteger (RemoteAddress (ref), &descriptorAddress)) {
1890
1920
return std::nullopt;
1921
+ }
1891
1922
1892
- ref = descriptorAddress;
1923
+ ref = stripSignedPointer ( descriptorAddress) ;
1893
1924
LLVM_FALLTHROUGH;
1894
1925
}
1895
1926
0 commit comments