@@ -836,8 +836,39 @@ static zend_class_entry *resolve_single_class_type(zend_string *name, zend_class
836
836
}
837
837
}
838
838
839
- // TODO Handle complex types when added
840
- // TODO Update to handle union and intersection in the same loop
839
+ // TODO better name
840
+ static zend_always_inline zend_class_entry * zend_resolve_ce (
841
+ zend_property_info * info , zend_type * type ) {
842
+ zend_class_entry * ce ;
843
+ if (UNEXPECTED (ZEND_TYPE_HAS_NAME (* type ))) {
844
+ zend_string * name = ZEND_TYPE_NAME (* type );
845
+
846
+ if (ZSTR_HAS_CE_CACHE (name )) {
847
+ ce = ZSTR_GET_CE_CACHE (name );
848
+ if (!ce ) {
849
+ ce = zend_lookup_class_ex (name , NULL , ZEND_FETCH_CLASS_NO_AUTOLOAD );
850
+ if (UNEXPECTED (!ce )) {
851
+ /* Cannot resolve */
852
+ return NULL ;
853
+ }
854
+ }
855
+ } else {
856
+ ce = resolve_single_class_type (name , info -> ce );
857
+ if (!ce ) {
858
+ /* Cannot resolve */
859
+ return NULL ;
860
+ }
861
+ if (!(info -> ce -> ce_flags & ZEND_ACC_IMMUTABLE )) {
862
+ zend_string_release (name );
863
+ ZEND_TYPE_SET_CE (* type , ce );
864
+ }
865
+ }
866
+ } else {
867
+ ce = ZEND_TYPE_CE (* type );
868
+ }
869
+ return ce ;
870
+ }
871
+
841
872
static bool zend_check_and_resolve_property_class_type (
842
873
zend_property_info * info , zend_class_entry * object_ce ) {
843
874
zend_class_entry * ce ;
@@ -846,62 +877,27 @@ static bool zend_check_and_resolve_property_class_type(
846
877
847
878
if (ZEND_TYPE_IS_INTERSECTION (info -> type )) {
848
879
ZEND_TYPE_LIST_FOREACH (ZEND_TYPE_LIST (info -> type ), list_type ) {
849
- if (ZEND_TYPE_HAS_NAME (* list_type )) {
850
- zend_string * name = ZEND_TYPE_NAME (* list_type );
851
-
852
- if (ZSTR_HAS_CE_CACHE (name )) {
853
- ce = ZSTR_GET_CE_CACHE (name );
854
- if (!ce ) {
855
- ce = zend_lookup_class_ex (name , NULL , ZEND_FETCH_CLASS_NO_AUTOLOAD );
856
- if (UNEXPECTED (!ce )) {
857
- /* Cannot resolve */
858
- return false;
859
- }
860
- }
861
- } else {
862
- ce = resolve_single_class_type (name , info -> ce );
863
- if (!ce ) {
864
- /* Cannot resolve */
865
- return false;
866
- }
867
- if (!(info -> ce -> ce_flags & ZEND_ACC_IMMUTABLE )) {
868
- zend_string_release (name );
869
- ZEND_TYPE_SET_CE (* list_type , ce );
870
- }
871
- }
872
- } else {
873
- ce = ZEND_TYPE_CE (* list_type );
880
+ ce = zend_resolve_ce (info , list_type );
881
+
882
+ /* If we cannot resolve the CE we cannot check if it satisfies
883
+ * the type constraint, fail. */
884
+ if (ce == NULL ) {
885
+ return false;
874
886
}
887
+
875
888
if (!instanceof_function (object_ce , ce )) {
876
889
return false;
877
890
}
878
891
} ZEND_TYPE_LIST_FOREACH_END ();
879
892
return true;
880
893
} else {
881
894
ZEND_TYPE_LIST_FOREACH (ZEND_TYPE_LIST (info -> type ), list_type ) {
882
- if (ZEND_TYPE_HAS_NAME (* list_type )) {
883
- zend_string * name = ZEND_TYPE_NAME (* list_type );
884
-
885
- if (ZSTR_HAS_CE_CACHE (name )) {
886
- ce = ZSTR_GET_CE_CACHE (name );
887
- if (!ce ) {
888
- ce = zend_lookup_class_ex (name , NULL , ZEND_FETCH_CLASS_NO_AUTOLOAD );
889
- if (UNEXPECTED (!ce )) {
890
- continue ;
891
- }
892
- }
893
- } else {
894
- ce = resolve_single_class_type (name , info -> ce );
895
- if (!ce ) {
896
- continue ;
897
- }
898
- if (!(info -> ce -> ce_flags & ZEND_ACC_IMMUTABLE )) {
899
- zend_string_release (name );
900
- ZEND_TYPE_SET_CE (* list_type , ce );
901
- }
902
- }
903
- } else {
904
- ce = ZEND_TYPE_CE (* list_type );
895
+ ce = zend_resolve_ce (info , list_type );
896
+
897
+ /* If we cannot resolve the CE we cannot check if it satisfies
898
+ * the type constraint, check the next one. */
899
+ if (ce == NULL ) {
900
+ continue ;
905
901
}
906
902
if (instanceof_function (object_ce , ce )) {
907
903
return true;
@@ -910,30 +906,14 @@ static bool zend_check_and_resolve_property_class_type(
910
906
return false;
911
907
}
912
908
} else {
913
- if (UNEXPECTED (ZEND_TYPE_HAS_NAME (info -> type ))) {
914
- zend_string * name = ZEND_TYPE_NAME (info -> type );
915
-
916
- if (ZSTR_HAS_CE_CACHE (name )) {
917
- ce = ZSTR_GET_CE_CACHE (name );
918
- if (!ce ) {
919
- ce = zend_lookup_class_ex (name , NULL , ZEND_FETCH_CLASS_NO_AUTOLOAD );
920
- if (UNEXPECTED (!ce )) {
921
- return 0 ;
922
- }
923
- }
924
- } else {
925
- ce = resolve_single_class_type (name , info -> ce );
926
- if (UNEXPECTED (!ce )) {
927
- return 0 ;
928
- }
929
- if (!(info -> ce -> ce_flags & ZEND_ACC_IMMUTABLE )) {
930
- zend_string_release (name );
931
- ZEND_TYPE_SET_CE (info -> type , ce );
932
- }
933
- }
934
- } else {
935
- ce = ZEND_TYPE_CE (info -> type );
909
+ ce = zend_resolve_ce (info , & info -> type );
910
+
911
+ /* If we cannot resolve the CE we cannot check if it satisfies
912
+ * the type constraint, fail. */
913
+ if (ce == NULL ) {
914
+ return false;
936
915
}
916
+
937
917
return instanceof_function (object_ce , ce );
938
918
}
939
919
}
@@ -999,16 +979,6 @@ ZEND_API bool zend_value_instanceof_static(zval *zv) {
999
979
return instanceof_function (Z_OBJCE_P (zv ), called_scope );
1000
980
}
1001
981
1002
- /* The cache_slot may only be NULL in debug builds, where arginfo verification of
1003
- * internal functions is enabled. Avoid unnecessary checks in release builds. */
1004
- #if ZEND_DEBUG
1005
- # define HAVE_CACHE_SLOT (cache_slot != NULL)
1006
- #else
1007
- # define HAVE_CACHE_SLOT 1
1008
- #endif
1009
-
1010
- // TODO Handle complex types when added
1011
- // TODO Update to handle union and intersection in the same loop
1012
982
static zend_always_inline bool zend_check_type_slow (
1013
983
zend_type * type , zval * arg , zend_reference * ref , void * * cache_slot , zend_class_entry * scope ,
1014
984
bool is_return_type , bool is_internal )
@@ -1020,28 +990,11 @@ static zend_always_inline bool zend_check_type_slow(
1020
990
zend_type * list_type ;
1021
991
if (ZEND_TYPE_IS_INTERSECTION (* type )) {
1022
992
ZEND_TYPE_LIST_FOREACH (ZEND_TYPE_LIST (* type ), list_type ) {
1023
- if (HAVE_CACHE_SLOT && * cache_slot ) {
1024
- ce = * cache_slot ;
1025
- } else {
1026
- zend_string * name = ZEND_TYPE_NAME (* list_type );
1027
-
1028
- if (ZSTR_HAS_CE_CACHE (name )) {
1029
- ce = ZSTR_GET_CE_CACHE (name );
1030
- if (!ce ) {
1031
- ce = zend_lookup_class_ex (name , NULL , ZEND_FETCH_CLASS_NO_AUTOLOAD );
1032
- if (!ce ) {
1033
- /* Cannot resolve */
1034
- return false;
1035
- }
1036
- }
1037
- } else {
1038
- ce = zend_fetch_class (name ,
1039
- ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT );
1040
- if (!ce ) {
1041
- /* Cannot resolve */
1042
- return false;
1043
- }
1044
- }
993
+ ce = zend_fetch_ce_from_cache_slot (cache_slot , list_type );
994
+ /* If we cannot resolve the CE we cannot check if it satisfies
995
+ * the type constraint, fail. */
996
+ if (ce == NULL ) {
997
+ return false;
1045
998
}
1046
999
1047
1000
/* Perform actual type check */
@@ -1057,32 +1010,14 @@ static zend_always_inline bool zend_check_type_slow(
1057
1010
return true;
1058
1011
} else {
1059
1012
ZEND_TYPE_LIST_FOREACH (ZEND_TYPE_LIST (* type ), list_type ) {
1060
- if (HAVE_CACHE_SLOT && * cache_slot ) {
1061
- ce = * cache_slot ;
1062
- } else {
1063
- zend_string * name = ZEND_TYPE_NAME (* list_type );
1064
-
1065
- if (ZSTR_HAS_CE_CACHE (name )) {
1066
- ce = ZSTR_GET_CE_CACHE (name );
1067
- if (!ce ) {
1068
- ce = zend_lookup_class_ex (name , NULL , ZEND_FETCH_CLASS_NO_AUTOLOAD );
1069
- if (!ce ) {
1070
- if (HAVE_CACHE_SLOT ) {
1071
- cache_slot ++ ;
1072
- }
1073
- continue ;
1074
- }
1075
- }
1076
- } else {
1077
- ce = zend_fetch_class (name ,
1078
- ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT );
1079
- if (!ce ) {
1080
- if (HAVE_CACHE_SLOT ) {
1081
- cache_slot ++ ;
1082
- }
1083
- continue ;
1084
- }
1013
+ ce = zend_fetch_ce_from_cache_slot (cache_slot , list_type );
1014
+ /* If we cannot resolve the CE we cannot check if it satisfies
1015
+ * the type constraint, check the next one. */
1016
+ if (ce == NULL ) {
1017
+ if (HAVE_CACHE_SLOT ) {
1018
+ cache_slot ++ ;
1085
1019
}
1020
+ continue ;
1086
1021
}
1087
1022
1088
1023
/* Perform actual type check */
@@ -1096,30 +1031,13 @@ static zend_always_inline bool zend_check_type_slow(
1096
1031
} ZEND_TYPE_LIST_FOREACH_END ();
1097
1032
}
1098
1033
} else {
1099
- if (EXPECTED (HAVE_CACHE_SLOT && * cache_slot )) {
1100
- ce = (zend_class_entry * ) * cache_slot ;
1101
- } else {
1102
- zend_string * name = ZEND_TYPE_NAME (* type );
1103
-
1104
- if (ZSTR_HAS_CE_CACHE (name )) {
1105
- ce = ZSTR_GET_CE_CACHE (name );
1106
- if (!ce ) {
1107
- ce = zend_lookup_class_ex (name , NULL , ZEND_FETCH_CLASS_NO_AUTOLOAD );
1108
- if (UNEXPECTED (!ce )) {
1109
- goto builtin_types ;
1110
- }
1111
- }
1112
- } else {
1113
- ce = zend_fetch_class (name ,
1114
- ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT );
1115
- if (UNEXPECTED (!ce )) {
1116
- goto builtin_types ;
1117
- }
1118
- }
1119
- if (HAVE_CACHE_SLOT ) {
1120
- * cache_slot = (void * ) ce ;
1121
- }
1034
+ ce = zend_fetch_ce_from_cache_slot (cache_slot , type );
1035
+ /* If we cannot resolve the CE we cannot check if it satisfies
1036
+ * the type constraint, check if a standard type satisfies it. */
1037
+ if (ce == NULL ) {
1038
+ goto builtin_types ;
1122
1039
}
1040
+
1123
1041
if (instanceof_function (Z_OBJCE_P (arg ), ce )) {
1124
1042
return 1 ;
1125
1043
}
0 commit comments