@@ -233,7 +233,7 @@ class MetadataReader {
233
233
return StoredPointer ();
234
234
235
235
auto classMeta = cast<TargetClassMetadata<Runtime>>(meta);
236
- return classMeta->SuperClass ;
236
+ return classMeta->Superclass ;
237
237
}
238
238
239
239
// / Given a remote pointer to class metadata, attempt to discover its class
@@ -537,32 +537,24 @@ class MetadataReader {
537
537
// /
538
538
// / The offset is in units of words, from the start of the class's
539
539
// / metadata.
540
- llvm::Optional<uint32_t >
540
+ llvm::Optional<int32_t >
541
541
readGenericArgsOffset (MetadataRef metadata,
542
542
ContextDescriptorRef descriptor) {
543
543
switch (descriptor->getKind ()) {
544
544
case ContextDescriptorKind::Class: {
545
545
auto type = cast<TargetClassDescriptor<Runtime>>(descriptor);
546
546
547
- auto *classMetadata = dyn_cast<TargetClassMetadata<Runtime>>(metadata);
548
- if (!classMetadata)
549
- return llvm::None;
550
-
551
- if (!classMetadata->SuperClass )
552
- return type->getGenericArgumentOffset (nullptr , nullptr );
547
+ if (!type->hasResilientSuperclass ())
548
+ return type->getNonResilientGenericArgumentOffset ();
553
549
554
- auto superMetadata = readMetadata (classMetadata-> SuperClass );
555
- if (!superMetadata )
550
+ auto bounds = readMetadataBoundsOfSuperclass (descriptor );
551
+ if (!bounds )
556
552
return llvm::None;
557
553
558
- auto superClassMetadata =
559
- dyn_cast<TargetClassMetadata<Runtime>>(superMetadata);
560
- if (!superClassMetadata)
561
- return llvm::None;
554
+ bounds->adjustForSubclass (type->areImmediateMembersNegative (),
555
+ type->NumImmediateMembers );
562
556
563
- auto result =
564
- type->getGenericArgumentOffset (classMetadata, superClassMetadata);
565
- return result;
557
+ return bounds->ImmediateMembersOffset / sizeof (StoredPointer);
566
558
}
567
559
568
560
case ContextDescriptorKind::Enum: {
@@ -580,6 +572,76 @@ class MetadataReader {
580
572
}
581
573
}
582
574
575
+ using ClassMetadataBounds = TargetClassMetadataBounds<Runtime>;
576
+
577
+ // This follows computeMetadataBoundsForSuperclass.
578
+ llvm::Optional<ClassMetadataBounds>
579
+ readMetadataBoundsOfSuperclass (ContextDescriptorRef subclassRef) {
580
+ auto subclass = cast<TargetClassDescriptor<Runtime>>(subclassRef);
581
+
582
+ auto rawSuperclass =
583
+ resolveNullableRelativeField (subclassRef, subclass->Superclass );
584
+ if (!rawSuperclass) {
585
+ return ClassMetadataBounds::forSwiftRootClass ();
586
+ }
587
+
588
+ return forTypeReference<ClassMetadataBounds>(
589
+ subclass->getSuperclassReferenceKind (), *rawSuperclass,
590
+ [&](ContextDescriptorRef superclass)
591
+ -> llvm::Optional<ClassMetadataBounds> {
592
+ if (!isa<TargetClassDescriptor<Runtime>>(superclass))
593
+ return llvm::None;
594
+ return readMetadataBoundsOfSuperclass (superclass);
595
+ },
596
+ [&](MetadataRef metadata) -> llvm::Optional<ClassMetadataBounds> {
597
+ auto cls = dyn_cast<TargetClassMetadata<Runtime>>(metadata);
598
+ if (!cls)
599
+ return llvm::None;
600
+
601
+ return cls->getClassBoundsAsSwiftSuperclass ();
602
+ });
603
+ }
604
+
605
+ template <class Result , class DescriptorFn , class MetadataFn >
606
+ llvm::Optional<Result>
607
+ forTypeReference (TypeMetadataRecordKind refKind, StoredPointer ref,
608
+ const DescriptorFn &descriptorFn,
609
+ const MetadataFn &metadataFn) {
610
+ switch (refKind) {
611
+ case TypeMetadataRecordKind::IndirectNominalTypeDescriptor: {
612
+ StoredPointer descriptorAddress = 0 ;
613
+ if (!Reader->readInteger (RemoteAddress (ref), &descriptorAddress))
614
+ return llvm::None;
615
+
616
+ ref = descriptorAddress;
617
+ LLVM_FALLTHROUGH;
618
+ }
619
+
620
+ case TypeMetadataRecordKind::DirectNominalTypeDescriptor: {
621
+ auto descriptor = readContextDescriptor (ref);
622
+ if (!descriptor)
623
+ return llvm::None;
624
+
625
+ return descriptorFn (descriptor);
626
+ }
627
+
628
+ case TypeMetadataRecordKind::IndirectObjCClass: {
629
+ StoredPointer classRef = 0 ;
630
+ if (!Reader->readInteger (RemoteAddress (ref), &classRef))
631
+ return llvm::None;
632
+
633
+ auto metadata = readMetadata (classRef);
634
+ if (!metadata)
635
+ return llvm::None;
636
+
637
+ return metadataFn (metadata);
638
+ }
639
+
640
+ default :
641
+ return llvm::None;
642
+ }
643
+ }
644
+
583
645
// / Read a single generic type argument from a bound generic type
584
646
// / metadata.
585
647
llvm::Optional<StoredPointer>
@@ -921,7 +983,7 @@ class MetadataReader {
921
983
if (descriptorAddress || !skipArtificialSubclasses)
922
984
return static_cast <StoredPointer>(descriptorAddress);
923
985
924
- auto superclassMetadataAddress = classMeta->SuperClass ;
986
+ auto superclassMetadataAddress = classMeta->Superclass ;
925
987
if (!superclassMetadataAddress)
926
988
return 0 ;
927
989
0 commit comments