@@ -46,6 +46,18 @@ static const V& getProperFunctionFromContainer(const std::vector<V>& container,
46
46
return *callee;
47
47
}
48
48
49
+ inline UInt8 encodeVersion (UInt8 majorVersion, UInt8 minorVersion) {
50
+ return (majorVersion << 3 ) | minorVersion;
51
+ }
52
+
53
+ inline UInt8 getMajorVersion (UInt8 encodedVersion) {
54
+ return encodedVersion >> 3 ;
55
+ }
56
+
57
+ inline UInt8 getMinorVersion (UInt8 encodedVersion) {
58
+ return encodedVersion & 0b111 ;
59
+ }
60
+
49
61
// Bit indices in flags section
50
62
enum MetaFlags {
51
63
HasName = 7 ,
@@ -126,6 +138,7 @@ enum BinaryTypeEncodingType : Byte {
126
138
template <typename T>
127
139
struct PtrTo ;
128
140
struct Meta ;
141
+ struct InterfaceMeta ;
129
142
struct ProtocolMeta ;
130
143
struct ModuleMeta ;
131
144
struct LibraryMeta ;
@@ -273,6 +286,12 @@ struct GlobalTable {
273
286
274
287
ArrayOfPtrTo<ArrayOfPtrTo<Meta>> buckets;
275
288
289
+ const InterfaceMeta* findInterfaceMeta (WTF::StringImpl* identifier) const ;
290
+
291
+ const InterfaceMeta* findInterfaceMeta (const char * identifierString) const ;
292
+
293
+ const InterfaceMeta* findInterfaceMeta (const char * identifierString, size_t length, unsigned hash) const ;
294
+
276
295
const Meta* findMeta (WTF::StringImpl* identifier, bool onlyIfAvailable = true ) const ;
277
296
278
297
const Meta* findMeta (const char * identifierString, bool onlyIfAvailable = true ) const ;
@@ -667,9 +686,24 @@ struct MethodMeta : MemberMeta {
667
686
const char * constructorTokens () const {
668
687
return this ->_constructorTokens .valuePtr ();
669
688
}
689
+
690
+ bool isImplementedInClass (Class klass, bool isStatic) const {
691
+ // class can be null for Protocol prototypes, treat all members in a protocol as implemented
692
+ if (klass == nullptr ) {
693
+ return true ;
694
+ }
695
+
696
+ return nullptr != (isStatic ? class_getClassMethod (klass, this ->selector ()) : class_getInstanceMethod (klass, this ->selector ()));
697
+ }
698
+
699
+ bool isAvailableInClass (Class klass, bool isStatic) const {
700
+ return this ->isAvailable () && this ->isImplementedInClass (klass, isStatic);
701
+ }
670
702
};
671
703
672
- std::unordered_map<std::string, std::vector<const MemberMeta*>> getMetasByJSNames (std::vector<const MemberMeta*> methods);
704
+ typedef HashSet<const MemberMeta*> MembersCollection;
705
+
706
+ std::unordered_map<std::string, MembersCollection> getMetasByJSNames (MembersCollection methods);
673
707
674
708
struct PropertyMeta : MemberMeta {
675
709
PtrTo<MethodMeta> method1;
@@ -691,6 +725,16 @@ struct PropertyMeta : MemberMeta {
691
725
const MethodMeta* setter () const {
692
726
return (this ->hasSetter ()) ? (this ->hasGetter () ? method2.valuePtr () : method1.valuePtr ()) : nullptr ;
693
727
}
728
+
729
+ bool isImplementedInClass (Class klass, bool isStatic) const {
730
+ bool getterAvailable = this ->hasGetter () && this ->getter ()->isImplementedInClass (klass, isStatic);
731
+ bool setterAvailable = this ->hasSetter () && this ->setter ()->isImplementedInClass (klass, isStatic);
732
+ return getterAvailable || setterAvailable;
733
+ }
734
+
735
+ bool isAvailableInClass (Class klass, bool isStatic) const {
736
+ return this ->isAvailable () && this ->isImplementedInClass (klass, isStatic);
737
+ }
694
738
};
695
739
696
740
struct BaseClassMeta : Meta {
@@ -706,7 +750,7 @@ struct BaseClassMeta : Meta {
706
750
707
751
const MethodMeta* member (const char * identifier, size_t length, MemberType type, size_t paramsCount, bool includeProtocols = true , bool onlyIfAvailable = true ) const ;
708
752
709
- const std::vector< const MemberMeta*> members (const char * identifier, size_t length, MemberType type, bool includeProtocols = true , bool onlyIfAvailable = true ) const ;
753
+ const MembersCollection members (const char * identifier, size_t length, MemberType type, bool includeProtocols = true , bool onlyIfAvailable = true ) const ;
710
754
711
755
const MemberMeta* member (StringImpl* identifier, MemberType type, bool includeProtocols = true ) const {
712
756
const char * identif = reinterpret_cast <const char *>(identifier->characters8 ());
@@ -720,7 +764,7 @@ struct BaseClassMeta : Meta {
720
764
return this ->member (identif, length, type, paramsCount, includeProtocols);
721
765
}
722
766
723
- const std::vector< const MemberMeta*> members (StringImpl* identifier, MemberType type, bool includeProtocols = true ) const {
767
+ const MembersCollection members (StringImpl* identifier, MemberType type, bool includeProtocols = true ) const {
724
768
const char * identif = reinterpret_cast <const char *>(identifier->characters8 ());
725
769
size_t length = (size_t )identifier->length ();
726
770
return this ->members (identif, length, type, includeProtocols);
@@ -731,101 +775,110 @@ struct BaseClassMeta : Meta {
731
775
}
732
776
733
777
// / instance methods
734
- const MethodMeta* instanceMethod (const char * identifier, size_t paramsCount, bool includeProtocols = true ) const {
735
- return this ->member (identifier, strlen (identifier), MemberType::InstanceMethod, paramsCount, includeProtocols);
736
- }
737
778
738
- const MethodMeta* instanceMethod (StringImpl* identifier, size_t paramsCount, bool includeProtocols = true ) const {
739
- return this ->member (identifier, MemberType::InstanceMethod, paramsCount, includeProtocols);
779
+ // Remove all optional methods/properties which are not implemented in the class
780
+ template <typename TMemberMeta>
781
+ static void filterUnavailableMembers (MembersCollection& members, Class klass, bool isStatic) {
782
+ members.removeIf ([klass, isStatic](const MemberMeta* memberMeta) {
783
+ return !static_cast <const TMemberMeta*>(memberMeta)->isAvailableInClass (klass, isStatic);
784
+ });
740
785
}
741
786
742
- const std::vector<const MemberMeta*> getInstanceMethods (StringImpl* identifier, bool includeProtocols = true ) const {
743
- return this ->members (identifier, MemberType::InstanceMethod, includeProtocols);
787
+ const MembersCollection getInstanceMethods (StringImpl* identifier, Class klass, bool includeProtocols = true ) const {
788
+ MembersCollection methods = this ->members (identifier, MemberType::InstanceMethod, includeProtocols);
789
+
790
+ filterUnavailableMembers<MethodMeta>(methods, klass, false );
791
+
792
+ return methods;
744
793
}
745
794
746
795
// / static methods
747
- const MethodMeta* staticMethod (const char * identifier, size_t paramsCount, bool includeProtocols = true ) const {
748
- return this ->member (identifier, strlen (identifier), MemberType::StaticMethod, paramsCount, includeProtocols);
749
- }
796
+ const MembersCollection getStaticMethods (StringImpl* identifier, Class klass, bool includeProtocols = true ) const {
797
+ MembersCollection methods = this ->members (identifier, MemberType::StaticMethod, includeProtocols);
750
798
751
- const std::vector<const MemberMeta*> getStaticMethods (StringImpl* identifier, bool includeProtocols = true ) const {
752
- return this ->members (identifier, MemberType::StaticMethod, includeProtocols);
753
- }
799
+ filterUnavailableMembers<MethodMeta>(methods, klass, true );
754
800
755
- const MethodMeta* staticMethod (StringImpl* identifier, size_t paramsCount, bool includeProtocols = true ) const {
756
- return this ->member (identifier, MemberType::StaticMethod, paramsCount, includeProtocols);
801
+ return methods;
757
802
}
758
803
759
804
// / instance properties
760
- const PropertyMeta* instanceProperty (const char * identifier, bool includeProtocols = true ) const {
761
- return reinterpret_cast <const PropertyMeta*>(this ->member (identifier, MemberType::InstanceProperty, includeProtocols));
805
+ const PropertyMeta* instanceProperty (const char * identifier, Class klass, bool includeProtocols = true ) const {
806
+ auto propMeta = static_cast <const PropertyMeta*>(this ->member (identifier, MemberType::InstanceProperty, includeProtocols));
807
+ return propMeta && propMeta->isAvailableInClass (klass, /* isStatic*/ false ) ? propMeta : nullptr ;
762
808
}
763
809
764
- const PropertyMeta* instanceProperty (StringImpl* identifier, bool includeProtocols = true ) const {
765
- return reinterpret_cast <const PropertyMeta*>(this ->member (identifier, MemberType::InstanceProperty, includeProtocols));
810
+ const PropertyMeta* instanceProperty (StringImpl* identifier, Class klass, bool includeProtocols = true ) const {
811
+ auto propMeta = static_cast <const PropertyMeta*>(this ->member (identifier, MemberType::InstanceProperty, includeProtocols));
812
+ return propMeta && propMeta->isAvailableInClass (klass, /* isStatic*/ false ) ? propMeta : nullptr ;
766
813
}
767
814
768
815
// / static properties
769
- const PropertyMeta* staticProperty (const char * identifier, bool includeProtocols = true ) const {
770
- return reinterpret_cast <const PropertyMeta*>(this ->member (identifier, MemberType::StaticProperty, includeProtocols));
816
+ const PropertyMeta* staticProperty (const char * identifier, Class klass, bool includeProtocols = true ) const {
817
+ auto propMeta = static_cast <const PropertyMeta*>(this ->member (identifier, MemberType::StaticProperty, includeProtocols));
818
+ return propMeta && propMeta->isAvailableInClass (klass, /* isStatic*/ true ) ? propMeta : nullptr ;
771
819
}
772
820
773
- const PropertyMeta* staticProperty (StringImpl* identifier, bool includeProtocols = true ) const {
774
- return reinterpret_cast <const PropertyMeta*>(this ->member (identifier, MemberType::StaticProperty, includeProtocols));
821
+ const PropertyMeta* staticProperty (StringImpl* identifier, Class klass, bool includeProtocols = true ) const {
822
+ auto propMeta = static_cast <const PropertyMeta*>(this ->member (identifier, MemberType::StaticProperty, includeProtocols));
823
+ return propMeta && propMeta->isAvailableInClass (klass, /* isStatic*/ true ) ? propMeta : nullptr ;
775
824
}
776
825
777
826
// / vectors
778
- std::vector<const PropertyMeta*> instanceProperties () const {
827
+ std::vector<const PropertyMeta*> instanceProperties (Class klass ) const {
779
828
std::vector<const PropertyMeta*> properties;
780
- return this ->instanceProperties (properties);
829
+ return this ->instanceProperties (properties, klass );
781
830
}
782
831
783
- std::vector<const PropertyMeta*> instancePropertiesWithProtocols () const {
832
+ std::vector<const PropertyMeta*> instancePropertiesWithProtocols (Class klass ) const {
784
833
std::vector<const PropertyMeta*> properties;
785
- return this ->instancePropertiesWithProtocols (properties);
834
+ return this ->instancePropertiesWithProtocols (properties, klass );
786
835
}
787
836
788
- std::vector<const PropertyMeta*> instanceProperties (std::vector<const PropertyMeta*>& container) const {
837
+ std::vector<const PropertyMeta*> instanceProperties (std::vector<const PropertyMeta*>& container, Class klass ) const {
789
838
for (Array<PtrTo<PropertyMeta>>::iterator it = this ->instanceProps ->begin (); it != this ->instanceProps ->end (); it++) {
790
- container.push_back ((*it).valuePtr ());
839
+ if ((*it)->isAvailableInClass (klass, /* isStatic*/ false )) {
840
+ container.push_back ((*it).valuePtr ());
841
+ }
791
842
}
792
843
return container;
793
844
}
794
845
795
- std::vector<const PropertyMeta*> instancePropertiesWithProtocols (std::vector<const PropertyMeta*>& container) const ;
846
+ std::vector<const PropertyMeta*> instancePropertiesWithProtocols (std::vector<const PropertyMeta*>& container, Class klass ) const ;
796
847
797
- std::vector<const PropertyMeta*> staticProperties () const {
848
+ std::vector<const PropertyMeta*> staticProperties (Class klass ) const {
798
849
std::vector<const PropertyMeta*> properties;
799
- return this ->staticProperties (properties);
850
+ return this ->staticProperties (properties, klass );
800
851
}
801
852
802
- std::vector<const PropertyMeta*> staticPropertiesWithProtocols () const {
853
+ std::vector<const PropertyMeta*> staticPropertiesWithProtocols (Class klass ) const {
803
854
std::vector<const PropertyMeta*> properties;
804
- return this ->staticPropertiesWithProtocols (properties);
855
+ return this ->staticPropertiesWithProtocols (properties, klass );
805
856
}
806
857
807
- std::vector<const PropertyMeta*> staticProperties (std::vector<const PropertyMeta*>& container) const {
858
+ std::vector<const PropertyMeta*> staticProperties (std::vector<const PropertyMeta*>& container, Class klass ) const {
808
859
for (Array<PtrTo<PropertyMeta>>::iterator it = this ->staticProps ->begin (); it != this ->staticProps ->end (); it++) {
809
- container.push_back ((*it).valuePtr ());
860
+ if ((*it)->isAvailableInClass (klass, /* isStatic*/ true )) {
861
+ container.push_back ((*it).valuePtr ());
862
+ }
810
863
}
811
864
return container;
812
865
}
813
866
814
- std::vector<const PropertyMeta*> staticPropertiesWithProtocols (std::vector<const PropertyMeta*>& container) const ;
867
+ std::vector<const PropertyMeta*> staticPropertiesWithProtocols (std::vector<const PropertyMeta*>& container, Class klass ) const ;
815
868
816
- std::vector<const MethodMeta*> initializers () const {
869
+ std::vector<const MethodMeta*> initializers (Class klass ) const {
817
870
std::vector<const MethodMeta*> initializers;
818
- return this ->initializers (initializers);
871
+ return this ->initializers (initializers, klass );
819
872
}
820
873
821
- std::vector<const MethodMeta*> initializersWithProtcols ( ) const {
874
+ std::vector<const MethodMeta*> initializersWithProtocols (Class klass ) const {
822
875
std::vector<const MethodMeta*> initializers;
823
- return this ->initializersWithProtcols (initializers);
876
+ return this ->initializersWithProtocols (initializers, klass );
824
877
}
825
878
826
- std::vector<const MethodMeta*> initializers (std::vector<const MethodMeta*>& container) const ;
879
+ std::vector<const MethodMeta*> initializers (std::vector<const MethodMeta*>& container, Class klass ) const ;
827
880
828
- std::vector<const MethodMeta*> initializersWithProtcols (std::vector<const MethodMeta*>& container) const ;
881
+ std::vector<const MethodMeta*> initializersWithProtocols (std::vector<const MethodMeta*>& container, Class klass ) const ;
829
882
};
830
883
831
884
struct ProtocolMeta : BaseClassMeta {
@@ -843,9 +896,10 @@ struct InterfaceMeta : BaseClassMeta {
843
896
844
897
const InterfaceMeta* baseMeta () const {
845
898
if (this ->baseName () != nullptr ) {
846
- const Meta * baseMeta = MetaFile::instance ()->globalTable ()->findMeta (this ->baseName ());
847
- return baseMeta-> type () == MetaType::Interface ? reinterpret_cast < const InterfaceMeta*>(baseMeta) : nullptr ;
899
+ const InterfaceMeta * baseMeta = MetaFile::instance ()->globalTable ()->findInterfaceMeta (this ->baseName ());
900
+ return baseMeta;
848
901
}
902
+
849
903
return nullptr ;
850
904
}
851
905
};
0 commit comments