@@ -838,18 +838,15 @@ static zend_class_entry *resolve_single_class_type(zend_string *name, zend_class
838838 }
839839}
840840
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 (
843842 zend_property_info * info , zend_type * type ) {
844- zend_class_entry * ce ;
845- zend_string * name = NULL ;
846-
847843 if (UNEXPECTED (!ZEND_TYPE_HAS_NAME (* type ))) {
844+ ZEND_ASSERT (ZEND_TYPE_HAS_CE (* type ));
848845 return ZEND_TYPE_CE (* type );
849846 }
850847
851- name = ZEND_TYPE_NAME (* type );
852-
848+ zend_string * name = ZEND_TYPE_NAME (* type );
849+ zend_class_entry * ce ;
853850 if (ZSTR_HAS_CE_CACHE (name )) {
854851 ce = ZSTR_GET_CE_CACHE (name );
855852 if (!ce ) {
@@ -867,50 +864,28 @@ static zend_always_inline zend_class_entry* zend_resolve_ce(
867864
868865static bool zend_check_and_resolve_property_class_type (
869866 zend_property_info * info , zend_class_entry * object_ce ) {
870- zend_class_entry * ce ;
871867 if (ZEND_TYPE_HAS_LIST (info -> type )) {
872868 zend_type * list_type ;
873-
874869 if (ZEND_TYPE_IS_INTERSECTION (info -> type )) {
875870 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 )) {
885873 return false;
886874 }
887875 } ZEND_TYPE_LIST_FOREACH_END ();
888876 return true;
889877 } else {
890878 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 )) {
899881 return true;
900882 }
901883 } ZEND_TYPE_LIST_FOREACH_END ();
902884 return false;
903885 }
904886 } 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 );
914889 }
915890}
916891
@@ -983,39 +958,38 @@ static zend_always_inline bool zend_value_instanceof_static(zval *zv) {
983958# define HAVE_CACHE_SLOT 1
984959#endif
985960
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 )
987963{
988- zend_class_entry * ce ;
989-
990964 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 );
1007974 if (UNEXPECTED (!ce )) {
975+ /* Cannot resolve */
1008976 return NULL ;
1009977 }
1010978 }
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 ;
1013984 }
1014985 }
986+ if (HAVE_CACHE_SLOT ) {
987+ * cache_slot = (void * ) ce ;
988+ }
1015989 return ce ;
1016990}
1017991
1018- ZEND_API bool zend_check_type_slow (
992+ static zend_always_inline bool zend_check_type_slow (
1019993 zend_type * type , zval * arg , zend_reference * ref , void * * cache_slot ,
1020994 bool is_return_type , bool is_internal )
1021995{
@@ -1027,16 +1001,9 @@ ZEND_API bool zend_check_type_slow(
10271001 if (ZEND_TYPE_IS_INTERSECTION (* type )) {
10281002 ZEND_TYPE_LIST_FOREACH (ZEND_TYPE_LIST (* type ), list_type ) {
10291003 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 */
10371004 /* If type is not an instance of one of the types taking part in the
10381005 * 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 )) {
10401007 return false;
10411008 }
10421009 if (HAVE_CACHE_SLOT ) {
@@ -1047,7 +1014,6 @@ ZEND_API bool zend_check_type_slow(
10471014 } else {
10481015 ZEND_TYPE_LIST_FOREACH (ZEND_TYPE_LIST (* type ), list_type ) {
10491016 ce = zend_fetch_ce_from_cache_slot (cache_slot , list_type );
1050- /* Perform actual type check if we have a CE */
10511017 /* Instance of a single type part of a union is sufficient to pass the type check */
10521018 if (ce && instanceof_function (Z_OBJCE_P (arg ), ce )) {
10531019 return true;
@@ -1115,6 +1081,13 @@ static zend_always_inline bool zend_check_type(
11151081 return zend_check_type_slow (type , arg , ref , cache_slot , is_return_type , is_internal );
11161082}
11171083
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+
11181091static zend_always_inline bool zend_verify_recv_arg_type (zend_function * zf , uint32_t arg_num , zval * arg , void * * cache_slot )
11191092{
11201093 zend_arg_info * cur_arg_info ;
0 commit comments