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