@@ -770,14 +770,20 @@ struct TargetHeapMetadata : TargetMetadata<Runtime> {
770
770
};
771
771
using HeapMetadata = TargetHeapMetadata<InProcess>;
772
772
773
+ // / An opaque descriptor describing a class or protocol method. References to
774
+ // / these descriptors appear in the method override table of a class context
775
+ // / descriptor, or a resilient witness table pattern, respectively.
776
+ // /
777
+ // / Clients should not assume anything about the contents of this descriptor
778
+ // / other than it having 4 byte alignment.
773
779
template <typename Runtime>
774
780
struct TargetMethodDescriptor {
775
- // / The method implementation.
776
- TargetRelativeDirectPointer<Runtime, void > Impl;
777
-
778
781
// / Flags describing the method.
779
782
MethodDescriptorFlags Flags;
780
783
784
+ // / The method implementation.
785
+ TargetRelativeDirectPointer<Runtime, void > Impl;
786
+
781
787
// TODO: add method types or anything else needed for reflection.
782
788
};
783
789
@@ -804,14 +810,41 @@ struct TargetVTableDescriptorHeader {
804
810
// / entries occupy in instantiated class metadata.
805
811
uint32_t VTableSize;
806
812
807
- uint32_t getVTableOffset (const TargetClassMetadata<Runtime> *metadata) const {
808
- const auto *description = metadata->getDescription ();
809
- if (description->hasResilientSuperclass ())
810
- return metadata->Superclass ->getSizeInWords () + VTableOffset;
813
+ uint32_t getVTableOffset (const TargetClassDescriptor<Runtime> *description) const {
814
+ if (description->hasResilientSuperclass ()) {
815
+ auto bounds = description->getMetadataBounds ();
816
+ return (bounds.ImmediateMembersOffset / sizeof (StoredPointer)
817
+ + VTableOffset);
818
+ }
819
+
811
820
return VTableOffset;
812
821
}
813
822
};
814
823
824
+ // / An entry in the method override table, referencing a method from one of our
825
+ // / ancestor classes, together with an implementation.
826
+ template <typename Runtime>
827
+ struct TargetMethodOverrideDescriptor {
828
+ // / The class containing the base method.
829
+ TargetRelativeIndirectablePointer<Runtime, TargetClassDescriptor<Runtime>> Class;
830
+
831
+ // / The base method.
832
+ TargetRelativeIndirectablePointer<Runtime, TargetMethodDescriptor<Runtime>> Method;
833
+
834
+ // / The implementation of the override.
835
+ TargetRelativeDirectPointer<Runtime, void , /* Nullable=*/ true > Impl;
836
+ };
837
+
838
+ // / Header for a class vtable override descriptor. This is a variable-sized
839
+ // / structure that provides implementations for overrides of methods defined
840
+ // / in superclasses.
841
+ template <typename Runtime>
842
+ struct TargetOverrideTableHeader {
843
+ // / The number of MethodOverrideDescriptor records following the vtable
844
+ // / override header in the class's nominal type descriptor.
845
+ uint32_t NumEntries;
846
+ };
847
+
815
848
// / The bounds of a class metadata object.
816
849
// /
817
850
// / This type is a currency type and is not part of the ABI.
@@ -1107,7 +1140,7 @@ struct TargetClassMetadata : public TargetAnyClassMetadata<Runtime> {
1107
1140
// / Get a pointer to the field offset vector, if present, or null.
1108
1141
const StoredPointer *getFieldOffsets () const {
1109
1142
assert (isTypeMetadata ());
1110
- auto offset = getDescription ()->getFieldOffsetVectorOffset (this );
1143
+ auto offset = getDescription ()->getFieldOffsetVectorOffset ();
1111
1144
if (offset == 0 )
1112
1145
return nullptr ;
1113
1146
auto asWords = reinterpret_cast <const void * const *>(this );
@@ -3580,15 +3613,19 @@ class TargetClassDescriptor final
3580
3613
TargetForeignMetadataInitialization<Runtime>,
3581
3614
TargetSingletonMetadataInitialization<Runtime>,
3582
3615
TargetVTableDescriptorHeader<Runtime>,
3583
- TargetMethodDescriptor<Runtime>> {
3616
+ TargetMethodDescriptor<Runtime>,
3617
+ TargetOverrideTableHeader<Runtime>,
3618
+ TargetMethodOverrideDescriptor<Runtime>> {
3584
3619
private:
3585
3620
using TrailingGenericContextObjects =
3586
3621
TrailingGenericContextObjects<TargetClassDescriptor<Runtime>,
3587
3622
TargetTypeGenericContextDescriptorHeader,
3588
3623
TargetForeignMetadataInitialization<Runtime>,
3589
3624
TargetSingletonMetadataInitialization<Runtime>,
3590
3625
TargetVTableDescriptorHeader<Runtime>,
3591
- TargetMethodDescriptor<Runtime>>;
3626
+ TargetMethodDescriptor<Runtime>,
3627
+ TargetOverrideTableHeader<Runtime>,
3628
+ TargetMethodOverrideDescriptor<Runtime>>;
3592
3629
3593
3630
using TrailingObjects =
3594
3631
typename TrailingGenericContextObjects::TrailingObjects;
@@ -3597,6 +3634,8 @@ class TargetClassDescriptor final
3597
3634
public:
3598
3635
using MethodDescriptor = TargetMethodDescriptor<Runtime>;
3599
3636
using VTableDescriptorHeader = TargetVTableDescriptorHeader<Runtime>;
3637
+ using OverrideTableHeader = TargetOverrideTableHeader<Runtime>;
3638
+ using MethodOverrideDescriptor = TargetMethodOverrideDescriptor<Runtime>;
3600
3639
using ForeignMetadataInitialization =
3601
3640
TargetForeignMetadataInitialization<Runtime>;
3602
3641
using SingletonMetadataInitialization =
@@ -3707,6 +3746,17 @@ class TargetClassDescriptor final
3707
3746
return getVTableDescriptor ()->VTableSize ;
3708
3747
}
3709
3748
3749
+ size_t numTrailingObjects (OverloadToken<OverrideTableHeader>) const {
3750
+ return hasOverrideTable () ? 1 : 0 ;
3751
+ }
3752
+
3753
+ size_t numTrailingObjects (OverloadToken<MethodOverrideDescriptor>) const {
3754
+ if (!hasOverrideTable ())
3755
+ return 0 ;
3756
+
3757
+ return getOverrideTable ()->NumEntries ;
3758
+ }
3759
+
3710
3760
public:
3711
3761
const ForeignMetadataInitialization &getForeignMetadataInitialization () const {
3712
3762
assert (this ->hasForeignMetadataInitialization ());
@@ -3722,11 +3772,12 @@ class TargetClassDescriptor final
3722
3772
// / its stored properties.
3723
3773
bool hasFieldOffsetVector () const { return FieldOffsetVectorOffset != 0 ; }
3724
3774
3725
- unsigned getFieldOffsetVectorOffset (const ClassMetadata *metadata) const {
3726
- const auto *description = metadata->getDescription ();
3727
-
3728
- if (description->hasResilientSuperclass ())
3729
- return metadata->Superclass ->getSizeInWords () + FieldOffsetVectorOffset;
3775
+ unsigned getFieldOffsetVectorOffset () const {
3776
+ if (hasResilientSuperclass ()) {
3777
+ auto bounds = getMetadataBounds ();
3778
+ return (bounds.ImmediateMembersOffset / sizeof (StoredPointer)
3779
+ + FieldOffsetVectorOffset);
3780
+ }
3730
3781
3731
3782
return FieldOffsetVectorOffset;
3732
3783
}
@@ -3735,6 +3786,10 @@ class TargetClassDescriptor final
3735
3786
return this ->getTypeContextDescriptorFlags ().class_hasVTable ();
3736
3787
}
3737
3788
3789
+ bool hasOverrideTable () const {
3790
+ return this ->getTypeContextDescriptorFlags ().class_hasOverrideTable ();
3791
+ }
3792
+
3738
3793
bool hasResilientSuperclass () const {
3739
3794
return this ->getTypeContextDescriptorFlags ().class_hasResilientSuperclass ();
3740
3795
}
@@ -3744,14 +3799,27 @@ class TargetClassDescriptor final
3744
3799
return nullptr ;
3745
3800
return this ->template getTrailingObjects <VTableDescriptorHeader>();
3746
3801
}
3747
-
3802
+
3748
3803
llvm::ArrayRef<MethodDescriptor> getMethodDescriptors () const {
3749
3804
if (!hasVTable ())
3750
3805
return {};
3751
3806
return {this ->template getTrailingObjects <MethodDescriptor>(),
3752
3807
numTrailingObjects (OverloadToken<MethodDescriptor>{})};
3753
3808
}
3754
3809
3810
+ const OverrideTableHeader *getOverrideTable () const {
3811
+ if (!hasOverrideTable ())
3812
+ return nullptr ;
3813
+ return this ->template getTrailingObjects <OverrideTableHeader>();
3814
+ }
3815
+
3816
+ llvm::ArrayRef<MethodOverrideDescriptor> getMethodOverrideDescriptors () const {
3817
+ if (!hasOverrideTable ())
3818
+ return {};
3819
+ return {this ->template getTrailingObjects <MethodOverrideDescriptor>(),
3820
+ numTrailingObjects (OverloadToken<MethodOverrideDescriptor>{})};
3821
+ }
3822
+
3755
3823
// / Return the bounds of this class's metadata.
3756
3824
TargetClassMetadataBounds<Runtime> getMetadataBounds () const {
3757
3825
if (!hasResilientSuperclass ())
0 commit comments