@@ -838,18 +838,15 @@ static zend_class_entry *resolve_single_class_type(zend_string *name, zend_class
838
838
}
839
839
}
840
840
841
- // TODO better name
842
- static zend_always_inline zend_class_entry * zend_resolve_ce (
841
+ static zend_always_inline zend_class_entry * zend_ce_from_type (
843
842
zend_property_info * info , zend_type * type ) {
844
- zend_class_entry * ce ;
845
- zend_string * name = NULL ;
846
-
847
843
if (UNEXPECTED (!ZEND_TYPE_HAS_NAME (* type ))) {
844
+ ZEND_ASSERT (ZEND_TYPE_HAS_CE (* type ));
848
845
return ZEND_TYPE_CE (* type );
849
846
}
850
847
851
- name = ZEND_TYPE_NAME (* type );
852
-
848
+ zend_string * name = ZEND_TYPE_NAME (* type );
849
+ zend_class_entry * ce ;
853
850
if (ZSTR_HAS_CE_CACHE (name )) {
854
851
ce = ZSTR_GET_CE_CACHE (name );
855
852
if (!ce ) {
@@ -867,50 +864,28 @@ static zend_always_inline zend_class_entry* zend_resolve_ce(
867
864
868
865
static bool zend_check_and_resolve_property_class_type (
869
866
zend_property_info * info , zend_class_entry * object_ce ) {
870
- zend_class_entry * ce ;
871
867
if (ZEND_TYPE_HAS_LIST (info -> type )) {
872
868
zend_type * list_type ;
873
-
874
869
if (ZEND_TYPE_IS_INTERSECTION (info -> type )) {
875
870
ZEND_TYPE_LIST_FOREACH (ZEND_TYPE_LIST (info -> type ), list_type ) {
876
- ce = zend_resolve_ce (info , list_type );
877
-
878
- /* If we cannot resolve the CE we cannot check if it satisfies
879
- * the type constraint, fail. */
880
- if (ce == NULL ) {
881
- return false;
882
- }
883
-
884
- if (!instanceof_function (object_ce , ce )) {
871
+ zend_class_entry * ce = zend_ce_from_type (info , list_type );
872
+ if (!ce || !instanceof_function (object_ce , ce )) {
885
873
return false;
886
874
}
887
875
} ZEND_TYPE_LIST_FOREACH_END ();
888
876
return true;
889
877
} else {
890
878
ZEND_TYPE_LIST_FOREACH (ZEND_TYPE_LIST (info -> type ), 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, check the next one. */
895
- if (ce == NULL ) {
896
- continue ;
897
- }
898
- if (instanceof_function (object_ce , ce )) {
879
+ zend_class_entry * ce = zend_ce_from_type (info , list_type );
880
+ if (ce && instanceof_function (object_ce , ce )) {
899
881
return true;
900
882
}
901
883
} ZEND_TYPE_LIST_FOREACH_END ();
902
884
return false;
903
885
}
904
886
} else {
905
- ce = zend_resolve_ce (info , & info -> type );
906
-
907
- /* If we cannot resolve the CE we cannot check if it satisfies
908
- * the type constraint, fail. */
909
- if (ce == NULL ) {
910
- return false;
911
- }
912
-
913
- return instanceof_function (object_ce , ce );
887
+ zend_class_entry * ce = zend_ce_from_type (info , & info -> type );
888
+ return ce && instanceof_function (object_ce , ce );
914
889
}
915
890
}
916
891
@@ -983,39 +958,38 @@ static zend_always_inline bool zend_value_instanceof_static(zval *zv) {
983
958
# define HAVE_CACHE_SLOT 1
984
959
#endif
985
960
986
- static zend_always_inline zend_class_entry * zend_fetch_ce_from_cache_slot (void * * cache_slot , zend_type * type )
961
+ static zend_always_inline zend_class_entry * zend_fetch_ce_from_cache_slot (
962
+ void * * cache_slot , zend_type * type )
987
963
{
988
- zend_class_entry * ce ;
989
-
990
964
if (EXPECTED (HAVE_CACHE_SLOT && * cache_slot )) {
991
- ce = (zend_class_entry * ) * cache_slot ;
992
- } else {
993
- zend_string * name = ZEND_TYPE_NAME (* type );
994
-
995
- if (ZSTR_HAS_CE_CACHE (name )) {
996
- ce = ZSTR_GET_CE_CACHE (name );
997
- if (!ce ) {
998
- ce = zend_lookup_class_ex (name , NULL , ZEND_FETCH_CLASS_NO_AUTOLOAD );
999
- if (UNEXPECTED (!ce )) {
1000
- /* Cannot resolve */
1001
- return NULL ;
1002
- }
1003
- }
1004
- } else {
1005
- ce = zend_fetch_class (name ,
1006
- ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT );
965
+ return (zend_class_entry * ) * cache_slot ;
966
+ }
967
+
968
+ zend_string * name = ZEND_TYPE_NAME (* type );
969
+ zend_class_entry * ce ;
970
+ if (ZSTR_HAS_CE_CACHE (name )) {
971
+ ce = ZSTR_GET_CE_CACHE (name );
972
+ if (!ce ) {
973
+ ce = zend_lookup_class_ex (name , NULL , ZEND_FETCH_CLASS_NO_AUTOLOAD );
1007
974
if (UNEXPECTED (!ce )) {
975
+ /* Cannot resolve */
1008
976
return NULL ;
1009
977
}
1010
978
}
1011
- if (HAVE_CACHE_SLOT ) {
1012
- * cache_slot = (void * ) ce ;
979
+ } else {
980
+ ce = zend_fetch_class (name ,
981
+ ZEND_FETCH_CLASS_AUTO | ZEND_FETCH_CLASS_NO_AUTOLOAD | ZEND_FETCH_CLASS_SILENT );
982
+ if (UNEXPECTED (!ce )) {
983
+ return NULL ;
1013
984
}
1014
985
}
986
+ if (HAVE_CACHE_SLOT ) {
987
+ * cache_slot = (void * ) ce ;
988
+ }
1015
989
return ce ;
1016
990
}
1017
991
1018
- ZEND_API bool zend_check_type_slow (
992
+ static zend_always_inline bool zend_check_type_slow (
1019
993
zend_type * type , zval * arg , zend_reference * ref , void * * cache_slot ,
1020
994
bool is_return_type , bool is_internal )
1021
995
{
@@ -1027,16 +1001,9 @@ ZEND_API bool zend_check_type_slow(
1027
1001
if (ZEND_TYPE_IS_INTERSECTION (* type )) {
1028
1002
ZEND_TYPE_LIST_FOREACH (ZEND_TYPE_LIST (* type ), list_type ) {
1029
1003
ce = zend_fetch_ce_from_cache_slot (cache_slot , list_type );
1030
- /* If we cannot resolve the CE we cannot check if it satisfies
1031
- * the type constraint, fail. */
1032
- if (ce == NULL ) {
1033
- return false;
1034
- }
1035
-
1036
- /* Perform actual type check */
1037
1004
/* If type is not an instance of one of the types taking part in the
1038
1005
* intersection it cannot be a valid instance of the whole intersection type. */
1039
- if (!instanceof_function (Z_OBJCE_P (arg ), ce )) {
1006
+ if (!ce || ! instanceof_function (Z_OBJCE_P (arg ), ce )) {
1040
1007
return false;
1041
1008
}
1042
1009
if (HAVE_CACHE_SLOT ) {
@@ -1047,7 +1014,6 @@ ZEND_API bool zend_check_type_slow(
1047
1014
} else {
1048
1015
ZEND_TYPE_LIST_FOREACH (ZEND_TYPE_LIST (* type ), list_type ) {
1049
1016
ce = zend_fetch_ce_from_cache_slot (cache_slot , list_type );
1050
- /* Perform actual type check if we have a CE */
1051
1017
/* Instance of a single type part of a union is sufficient to pass the type check */
1052
1018
if (ce && instanceof_function (Z_OBJCE_P (arg ), ce )) {
1053
1019
return true;
@@ -1115,6 +1081,13 @@ static zend_always_inline bool zend_check_type(
1115
1081
return zend_check_type_slow (type , arg , ref , cache_slot , is_return_type , is_internal );
1116
1082
}
1117
1083
1084
+ ZEND_API bool zend_check_user_type_slow (
1085
+ zend_type * type , zval * arg , zend_reference * ref , void * * cache_slot , bool is_return_type )
1086
+ {
1087
+ return zend_check_type_slow (
1088
+ type , arg , ref , cache_slot , is_return_type , /* is_internal */ false);
1089
+ }
1090
+
1118
1091
static zend_always_inline bool zend_verify_recv_arg_type (zend_function * zf , uint32_t arg_num , zval * arg , void * * cache_slot )
1119
1092
{
1120
1093
zend_arg_info * cur_arg_info ;
0 commit comments