@@ -3683,6 +3683,20 @@ struct TargetResilientSuperclass {
3683
3683
TargetRelativeDirectPointer<Runtime, const void , /* nullable*/ true > Superclass;
3684
3684
};
3685
3685
3686
+ template <typename Runtime>
3687
+ struct TargetObjCResilientClassStub {
3688
+ // / A relative pointer to an Objective-C resilient class stub:
3689
+ // / - isa pointer, always 1
3690
+ // / - an update callback, of type 'Class (*)(Class *, objc_class_stub *)'
3691
+ // /
3692
+ // / Class stubs are used for two purposes:
3693
+ // /
3694
+ // / - Objective-C can reference class stubs when calling static methods.
3695
+ // / - Objective-C and Swift can reference class stubs when emitting
3696
+ // / categories (in Swift, extensions with @objc members).
3697
+ TargetRelativeDirectPointer<Runtime, const void > Stub;
3698
+ };
3699
+
3686
3700
template <typename Runtime>
3687
3701
class TargetClassDescriptor final
3688
3702
: public TargetTypeContextDescriptor<Runtime>,
@@ -3695,7 +3709,8 @@ class TargetClassDescriptor final
3695
3709
TargetVTableDescriptorHeader<Runtime>,
3696
3710
TargetMethodDescriptor<Runtime>,
3697
3711
TargetOverrideTableHeader<Runtime>,
3698
- TargetMethodOverrideDescriptor<Runtime>> {
3712
+ TargetMethodOverrideDescriptor<Runtime>,
3713
+ TargetObjCResilientClassStub<Runtime>> {
3699
3714
private:
3700
3715
using TrailingGenericContextObjects =
3701
3716
TrailingGenericContextObjects<TargetClassDescriptor<Runtime>,
@@ -3706,7 +3721,8 @@ class TargetClassDescriptor final
3706
3721
TargetVTableDescriptorHeader<Runtime>,
3707
3722
TargetMethodDescriptor<Runtime>,
3708
3723
TargetOverrideTableHeader<Runtime>,
3709
- TargetMethodOverrideDescriptor<Runtime>>;
3724
+ TargetMethodOverrideDescriptor<Runtime>,
3725
+ TargetObjCResilientClassStub<Runtime>>;
3710
3726
3711
3727
using TrailingObjects =
3712
3728
typename TrailingGenericContextObjects::TrailingObjects;
@@ -3722,6 +3738,8 @@ class TargetClassDescriptor final
3722
3738
TargetForeignMetadataInitialization<Runtime>;
3723
3739
using SingletonMetadataInitialization =
3724
3740
TargetSingletonMetadataInitialization<Runtime>;
3741
+ using ObjCResilientClassStub =
3742
+ TargetObjCResilientClassStub<Runtime>;
3725
3743
3726
3744
using StoredPointer = typename Runtime::StoredPointer;
3727
3745
using StoredPointerDifference = typename Runtime::StoredPointerDifference;
@@ -3759,7 +3777,9 @@ class TargetClassDescriptor final
3759
3777
// / positive size of metadata objects of this class (in words).
3760
3778
uint32_t MetadataPositiveSizeInWords;
3761
3779
3762
- // Maybe add something here that's useful only for resilient types?
3780
+ // / Classes with resilient ancestry instead use this flags word to
3781
+ // / indicate the presence of an Objective-C resilient class stub.
3782
+ ExtraClassDescriptorFlags ExtraClassFlags;
3763
3783
};
3764
3784
3765
3785
// / The number of additional members added by this class to the class
@@ -3835,6 +3855,10 @@ class TargetClassDescriptor final
3835
3855
return getOverrideTable ()->NumEntries ;
3836
3856
}
3837
3857
3858
+ size_t numTrailingObjects (OverloadToken<ObjCResilientClassStub>) const {
3859
+ return hasObjCResilientClassStub () ? 1 : 0 ;
3860
+ }
3861
+
3838
3862
public:
3839
3863
const TargetRelativeDirectPointer<Runtime, const void , /* nullable*/ true > &
3840
3864
getResilientSuperclass () const {
@@ -3954,7 +3978,24 @@ class TargetClassDescriptor final
3954
3978
&& i < numTrailingObjects (OverloadToken<MethodDescriptor>{}));
3955
3979
return getMethodDescriptors ()[i].Impl .get ();
3956
3980
}
3957
-
3981
+
3982
+ // / Whether this context descriptor references an Objective-C resilient
3983
+ // / class stub. See the description of TargetObjCResilientClassStub above
3984
+ // / for details.
3985
+ bool hasObjCResilientClassStub () const {
3986
+ if (!hasResilientSuperclass ())
3987
+ return false ;
3988
+ return ExtraClassFlags.hasObjCResilientClassStub ();
3989
+ }
3990
+
3991
+ const void *getObjCResilientClassStub () const {
3992
+ if (!hasObjCResilientClassStub ())
3993
+ return nullptr ;
3994
+
3995
+ return this ->template getTrailingObjects <ObjCResilientClassStub>()
3996
+ ->Stub .get ();
3997
+ }
3998
+
3958
3999
static bool classof (const TargetContextDescriptor<Runtime> *cd) {
3959
4000
return cd->getKind () == ContextDescriptorKind::Class;
3960
4001
}
0 commit comments