@@ -684,22 +684,6 @@ static ZEND_COLD void zend_throw_no_prop_backing_value_access(zend_string *class
684
684
ZSTR_VAL (class_name ), ZSTR_VAL (prop_name ));
685
685
}
686
686
687
- static bool zend_call_get_hook (
688
- const zend_property_info * prop_info , zend_string * prop_name ,
689
- zend_function * get , zend_object * zobj , zval * rv )
690
- {
691
- if (!zend_should_call_hook (prop_info , zobj )) {
692
- if (UNEXPECTED (prop_info -> flags & ZEND_ACC_VIRTUAL )) {
693
- zend_throw_no_prop_backing_value_access (zobj -> ce -> name , prop_name , /* is_read */ true);
694
- }
695
- return false;
696
- }
697
-
698
- zend_call_known_instance_method_with_0_params (get , zobj , rv );
699
-
700
- return true;
701
- }
702
-
703
687
ZEND_API zval * zend_std_read_property (zend_object * zobj , zend_string * name , int type , void * * cache_slot , zval * rv ) /* {{{ */
704
688
{
705
689
zval * retval ;
@@ -808,8 +792,9 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int
808
792
809
793
zend_class_entry * ce = zobj -> ce ;
810
794
811
- if (!zend_call_get_hook (prop_info , name , get , zobj , rv )) {
812
- if (EG (exception )) {
795
+ if (!zend_should_call_hook (prop_info , zobj )) {
796
+ if (UNEXPECTED (prop_info -> flags & ZEND_ACC_VIRTUAL )) {
797
+ zend_throw_no_prop_backing_value_access (zobj -> ce -> name , name , /* is_read */ true);
813
798
return & EG (uninitialized_zval );
814
799
}
815
800
@@ -826,12 +811,18 @@ ZEND_API zval *zend_std_read_property(zend_object *zobj, zend_string *name, int
826
811
goto try_again ;
827
812
}
828
813
829
- if ( EXPECTED ( cache_slot
814
+ bool cache_simple_get = cache_slot
830
815
&& zend_execute_ex == execute_ex
831
816
&& zobj -> ce -> default_object_handlers -> read_property == zend_std_read_property
832
817
&& !zobj -> ce -> create_object
833
818
&& !zend_is_in_hook (prop_info )
834
- && !(prop_info -> hooks [ZEND_PROPERTY_HOOK_GET ]-> common .fn_flags & ZEND_ACC_RETURN_REFERENCE ))) {
819
+ && !(prop_info -> hooks [ZEND_PROPERTY_HOOK_GET ]-> common .fn_flags & ZEND_ACC_RETURN_REFERENCE );
820
+
821
+ zend_call_known_instance_method_with_0_params (get , zobj , rv );
822
+
823
+ /* Only cache simple get after calling the hook to provide better error
824
+ * messages for accidentally recursive hooks. */
825
+ if (EXPECTED (cache_simple_get )) {
835
826
ZEND_SET_PROPERTY_HOOK_SIMPLE_GET (cache_slot );
836
827
}
837
828
@@ -2229,14 +2220,17 @@ ZEND_API int zend_std_has_property(zend_object *zobj, zend_string *name, int has
2229
2220
}
2230
2221
2231
2222
zval rv ;
2232
- if (!zend_call_get_hook (prop_info , name , get , zobj , & rv )) {
2233
- if (EG (exception )) {
2223
+ if (!zend_should_call_hook (prop_info , zobj )) {
2224
+ if (UNEXPECTED (prop_info -> flags & ZEND_ACC_VIRTUAL )) {
2225
+ zend_throw_no_prop_backing_value_access (zobj -> ce -> name , name , /* is_read */ true);
2234
2226
return 0 ;
2235
2227
}
2236
2228
property_offset = prop_info -> offset ;
2237
2229
goto try_again ;
2238
2230
}
2239
2231
2232
+ zend_call_known_instance_method_with_0_params (get , zobj , & rv );
2233
+
2240
2234
if (has_set_exists == ZEND_PROPERTY_NOT_EMPTY ) {
2241
2235
result = zend_is_true (& rv );
2242
2236
} else {
0 commit comments