@@ -29,26 +29,45 @@ typedef enum {
2929} pm_result ;
3030
3131pm_result zend_pattern_match_ex (zval * zv , zend_ast * pattern );
32+ static zend_class_entry * get_class_from_fetch_type (uint32_t fetch_type );
3233
3334static pm_result match_type (zval * zv , zend_ast * type_ast )
3435{
3536 zend_ast * class_name_ast = type_ast -> child [0 ];
37+ uint32_t fetch_type ;
38+
3639 if (class_name_ast ) {
3740 if (Z_TYPE_P (zv ) != IS_OBJECT ) {
3841 return PM_MISMATCH ;
3942 }
4043
41- zend_object * obj = Z_OBJ_P (zv );
4244 zend_string * class_name = zend_ast_get_str (class_name_ast );
43- if (!zend_string_equals_ci (obj -> ce -> name , class_name )) {
44- zend_class_entry * expected_class = zend_lookup_class_ex (class_name , NULL , ZEND_FETCH_CLASS_NO_AUTOLOAD );
45- if (!expected_class || !instanceof_function (Z_OBJ_P (zv )-> ce , expected_class )) {
46- return PM_MISMATCH ;
45+ fetch_type = zend_get_class_fetch_type (class_name );
46+
47+ zend_class_entry * expected_class = NULL ;
48+ if (fetch_type == ZEND_FETCH_CLASS_DEFAULT ) {
49+ zend_object * obj = Z_OBJ_P (zv );
50+ if (zend_string_equals_ci (obj -> ce -> name , class_name )) {
51+ return PM_MATCH ;
4752 }
53+ expected_class = zend_lookup_class_ex (class_name , NULL , ZEND_FETCH_CLASS_NO_AUTOLOAD );
54+ } else {
55+ non_default_fetch_type :
56+ expected_class = get_class_from_fetch_type (fetch_type );
57+ if (!expected_class ) {
58+ return PM_ERROR ;
59+ }
60+ }
61+ if (!expected_class || !instanceof_function (Z_OBJ_P (zv )-> ce , expected_class )) {
62+ return PM_MISMATCH ;
4863 }
4964 } else {
5065 zend_type type = ZEND_TYPE_INIT_MASK (type_ast -> attr );
5166 if (!ZEND_TYPE_CONTAINS_CODE (type , Z_TYPE_P (zv ))) {
67+ if (ZEND_TYPE_CONTAINS_CODE (type , IS_STATIC )) {
68+ fetch_type = ZEND_FETCH_CLASS_STATIC ;
69+ goto non_default_fetch_type ;
70+ }
5271 return PM_MISMATCH ;
5372 }
5473 }
@@ -105,25 +124,9 @@ static pm_result match_object(zval *zv, zend_ast *pattern)
105124 }
106125
107126 zend_object * obj = Z_OBJ_P (zv );
108- zend_ast * class_name_ast = pattern -> child [0 ];
109-
110- if (class_name_ast ) {
111- zend_string * class_name = zend_ast_get_str (class_name_ast );
112- if (!zend_string_equals_ci (obj -> ce -> name , class_name )) {
113- zend_class_entry * expected_class = zend_lookup_class_ex (class_name , NULL , ZEND_FETCH_CLASS_NO_AUTOLOAD );
114- if (!expected_class || !instanceof_function (Z_OBJ_P (zv )-> ce , expected_class )) {
115- return PM_MISMATCH ;
116- }
117- }
118- } else {
119- uint32_t fetch_type = pattern -> attr ;
120- zend_class_entry * scope = get_class_from_fetch_type (fetch_type );
121- if (EG (exception )) {
122- return PM_ERROR ;
123- }
124- if (!instanceof_function (Z_OBJ_P (zv )-> ce , scope )) {
125- return PM_MISMATCH ;
126- }
127+ pm_result type_result = match_type (zv , pattern -> child [0 ]);
128+ if (type_result != PM_MATCH ) {
129+ return type_result ;
127130 }
128131
129132 zend_ast_list * elements = zend_ast_get_list (pattern -> child [1 ]);
@@ -165,11 +168,6 @@ static pm_result match_range(zval *zv, zend_ast *pattern)
165168
166169static pm_result match_binding (zval * zv , zend_ast * pattern )
167170{
168- zend_ast * sub_pattern = pattern -> child [1 ];
169- if (sub_pattern && !zend_pattern_match_ex (zv , sub_pattern )) {
170- return PM_MISMATCH ;
171- }
172-
173171 zend_pm_context * context = EG (pm_context );
174172 zend_pm_bindings * bindings = context -> bindings ;
175173 if (!bindings ) {
0 commit comments