@@ -132,6 +132,7 @@ PHPAPI zend_class_entry *reflection_property_hook_type_ptr;
132132typedef struct _property_reference {
133133 zend_property_info * prop ;
134134 zend_string * unmangled_name ;
135+ void * cache_slot [3 ];
135136} property_reference ;
136137
137138/* Struct for parameters */
@@ -1506,6 +1507,7 @@ static void reflection_property_factory(zend_class_entry *ce, zend_string *name,
15061507 reference = (property_reference * ) emalloc (sizeof (property_reference ));
15071508 reference -> prop = prop ;
15081509 reference -> unmangled_name = zend_string_copy (name );
1510+ memset (reference -> cache_slot , 0 , sizeof (reference -> cache_slot ));
15091511 intern -> ptr = reference ;
15101512 intern -> ref_type = REF_TYPE_PROPERTY ;
15111513 intern -> ce = ce ;
@@ -5638,6 +5640,7 @@ ZEND_METHOD(ReflectionProperty, __construct)
56385640 reference = (property_reference * ) emalloc (sizeof (property_reference ));
56395641 reference -> prop = dynam_prop ? NULL : property_info ;
56405642 reference -> unmangled_name = zend_string_copy (name );
5643+ memset (reference -> cache_slot , 0 , sizeof (reference -> cache_slot ));
56415644 intern -> ptr = reference ;
56425645 intern -> ref_type = REF_TYPE_PROPERTY ;
56435646 intern -> ce = ce ;
@@ -5789,9 +5792,10 @@ ZEND_METHOD(ReflectionProperty, getValue)
57895792 zval * object = NULL ;
57905793 zval * member_p = NULL ;
57915794
5792- if (zend_parse_parameters (ZEND_NUM_ARGS (), "|o!" , & object ) == FAILURE ) {
5793- RETURN_THROWS ();
5794- }
5795+ ZEND_PARSE_PARAMETERS_START (0 , 1 )
5796+ Z_PARAM_OPTIONAL
5797+ Z_PARAM_OBJECT_EX (object , 1 , 0 )
5798+ ZEND_PARSE_PARAMETERS_END ();
57955799
57965800 GET_REFLECTION_OBJECT_PTR (ref );
57975801
@@ -5814,7 +5818,23 @@ ZEND_METHOD(ReflectionProperty, getValue)
58145818 RETURN_THROWS ();
58155819 }
58165820
5817- member_p = zend_read_property_ex (intern -> ce , Z_OBJ_P (object ), ref -> unmangled_name , 0 , & rv );
5821+ if (ref -> cache_slot [0 ] == Z_OBJCE_P (object )) {
5822+ uintptr_t prop_offset = (uintptr_t ) ref -> cache_slot [1 ];
5823+
5824+ if (EXPECTED (IS_VALID_PROPERTY_OFFSET (prop_offset ))) {
5825+ zval * retval = OBJ_PROP (Z_OBJ_P (object ), prop_offset );
5826+ if (EXPECTED (!Z_ISUNDEF_P (retval ))) {
5827+ RETURN_COPY_DEREF (retval );
5828+ }
5829+ }
5830+ }
5831+
5832+ zend_class_entry * old_scope = EG (fake_scope );
5833+ EG (fake_scope ) = intern -> ce ;
5834+ member_p = Z_OBJ_P (object )-> handlers -> read_property (Z_OBJ_P (object ),
5835+ ref -> unmangled_name , BP_VAR_R , ref -> cache_slot , & rv );
5836+ EG (fake_scope ) = old_scope ;
5837+
58185838 if (member_p != & rv ) {
58195839 RETURN_COPY_DEREF (member_p );
58205840 } else {
@@ -5868,7 +5888,10 @@ ZEND_METHOD(ReflectionProperty, setValue)
58685888 Z_PARAM_ZVAL (value )
58695889 ZEND_PARSE_PARAMETERS_END ();
58705890
5871- zend_update_property_ex (intern -> ce , object , ref -> unmangled_name , value );
5891+ zend_class_entry * old_scope = EG (fake_scope );
5892+ EG (fake_scope ) = intern -> ce ;
5893+ object -> handlers -> write_property (object , ref -> unmangled_name , value , ref -> cache_slot );
5894+ EG (fake_scope ) = old_scope ;
58725895 }
58735896}
58745897/* }}} */
@@ -5892,9 +5915,9 @@ ZEND_METHOD(ReflectionProperty, getRawValue)
58925915 property_reference * ref ;
58935916 zval * object ;
58945917
5895- if ( zend_parse_parameters ( ZEND_NUM_ARGS (), "o" , & object ) == FAILURE ) {
5896- RETURN_THROWS ();
5897- }
5918+ ZEND_PARSE_PARAMETERS_START ( 1 , 1 )
5919+ Z_PARAM_OBJECT ( object )
5920+ ZEND_PARSE_PARAMETERS_END ();
58985921
58995922 GET_REFLECTION_OBJECT_PTR (ref );
59005923
@@ -5903,6 +5926,17 @@ ZEND_METHOD(ReflectionProperty, getRawValue)
59035926 RETURN_THROWS ();
59045927 }
59055928
5929+ if (ref -> cache_slot [0 ] == Z_OBJCE_P (object )) {
5930+ uintptr_t prop_offset = (uintptr_t ) ref -> cache_slot [1 ];
5931+
5932+ if (EXPECTED (IS_VALID_PROPERTY_OFFSET (prop_offset ))) {
5933+ zval * retval = OBJ_PROP (Z_OBJ_P (object ), prop_offset );
5934+ if (EXPECTED (!Z_ISUNDEF_P (retval ))) {
5935+ RETURN_COPY_DEREF (retval );
5936+ }
5937+ }
5938+ }
5939+
59065940 zend_property_info * prop = reflection_property_get_effective_prop (ref ,
59075941 intern -> ce , Z_OBJ_P (object ));
59085942
@@ -5913,7 +5947,12 @@ ZEND_METHOD(ReflectionProperty, getRawValue)
59135947
59145948 if (!prop || !prop -> hooks || !prop -> hooks [ZEND_PROPERTY_HOOK_GET ]) {
59155949 zval rv ;
5916- zval * member_p = zend_read_property_ex (intern -> ce , Z_OBJ_P (object ), ref -> unmangled_name , 0 , & rv );
5950+ zend_class_entry * old_scope = EG (fake_scope );
5951+ EG (fake_scope ) = intern -> ce ;
5952+ zval * member_p = Z_OBJ_P (object )-> handlers -> read_property (
5953+ Z_OBJ_P (object ), ref -> unmangled_name , BP_VAR_R ,
5954+ ref -> cache_slot , & rv );
5955+ EG (fake_scope ) = old_scope ;
59175956
59185957 if (member_p != & rv ) {
59195958 RETURN_COPY_DEREF (member_p );
@@ -5930,11 +5969,14 @@ ZEND_METHOD(ReflectionProperty, getRawValue)
59305969}
59315970
59325971static void reflection_property_set_raw_value (zend_property_info * prop ,
5933- zend_string * unmangled_name , reflection_object * intern ,
5972+ zend_string * unmangled_name , void * cache_slot [ 3 ], reflection_object * intern ,
59345973 zend_object * object , zval * value )
59355974{
59365975 if (!prop || !prop -> hooks || !prop -> hooks [ZEND_PROPERTY_HOOK_SET ]) {
5937- zend_update_property_ex (intern -> ce , object , unmangled_name , value );
5976+ zend_class_entry * old_scope = EG (fake_scope );
5977+ EG (fake_scope ) = intern -> ce ;
5978+ object -> handlers -> write_property (object , unmangled_name , value , cache_slot );
5979+ EG (fake_scope ) = old_scope ;
59385980 } else {
59395981 zend_function * func = zend_get_property_hook_trampoline (prop , ZEND_PROPERTY_HOOK_SET , unmangled_name );
59405982 zend_call_known_instance_method_with_1_params (func , object , NULL , value );
@@ -5950,9 +5992,10 @@ ZEND_METHOD(ReflectionProperty, setRawValue)
59505992
59515993 GET_REFLECTION_OBJECT_PTR (ref );
59525994
5953- if (zend_parse_parameters (ZEND_NUM_ARGS (), "oz" , & object , & value ) == FAILURE ) {
5954- RETURN_THROWS ();
5955- }
5995+ ZEND_PARSE_PARAMETERS_START (2 , 2 ) {
5996+ Z_PARAM_OBJECT (object )
5997+ Z_PARAM_ZVAL (value )
5998+ } ZEND_PARSE_PARAMETERS_END ();
59565999
59576000 zend_property_info * prop = reflection_property_get_effective_prop (ref ,
59586001 intern -> ce , Z_OBJ_P (object ));
@@ -5962,7 +6005,8 @@ ZEND_METHOD(ReflectionProperty, setRawValue)
59626005 RETURN_THROWS ();
59636006 }
59646007
5965- reflection_property_set_raw_value (prop , ref -> unmangled_name , intern , Z_OBJ_P (object ), value );
6008+ reflection_property_set_raw_value (prop , ref -> unmangled_name ,
6009+ ref -> cache_slot , intern , Z_OBJ_P (object ), value );
59666010}
59676011
59686012static zend_result reflection_property_check_lazy_compatible (
@@ -6041,8 +6085,8 @@ ZEND_METHOD(ReflectionProperty, setRawValueWithoutLazyInitialization)
60416085 /* Do not trigger initialization */
60426086 Z_PROP_FLAG_P (var_ptr ) &= ~IS_PROP_LAZY ;
60436087
6044- reflection_property_set_raw_value (prop , ref -> unmangled_name , intern , object ,
6045- value );
6088+ reflection_property_set_raw_value (prop , ref -> unmangled_name ,
6089+ ref -> cache_slot , intern , object , value );
60466090
60476091 /* Mark property as lazy again if an exception prevented update */
60486092 if (EG (exception ) && prop_was_lazy && Z_TYPE_P (var_ptr ) == IS_UNDEF
@@ -6138,9 +6182,10 @@ ZEND_METHOD(ReflectionProperty, isInitialized)
61386182 zval * object = NULL ;
61396183 zval * member_p = NULL ;
61406184
6141- if (zend_parse_parameters (ZEND_NUM_ARGS (), "|o!" , & object ) == FAILURE ) {
6142- RETURN_THROWS ();
6143- }
6185+ ZEND_PARSE_PARAMETERS_START (0 , 1 )
6186+ Z_PARAM_OPTIONAL
6187+ Z_PARAM_OBJECT_EX (object , 1 , 0 )
6188+ ZEND_PARSE_PARAMETERS_END ();
61446189
61456190 GET_REFLECTION_OBJECT_PTR (ref );
61466191
@@ -6165,9 +6210,19 @@ ZEND_METHOD(ReflectionProperty, isInitialized)
61656210 RETURN_THROWS ();
61666211 }
61676212
6213+ if (ref -> cache_slot [0 ] == Z_OBJCE_P (object )) {
6214+ uintptr_t prop_offset = (uintptr_t ) ref -> cache_slot [1 ];
6215+
6216+ if (EXPECTED (IS_VALID_PROPERTY_OFFSET (prop_offset ))) {
6217+ zval * value = OBJ_PROP (Z_OBJ_P (object ), prop_offset );
6218+ RETURN_BOOL (!Z_ISUNDEF_P (value ));
6219+ }
6220+ }
6221+
61686222 old_scope = EG (fake_scope );
61696223 EG (fake_scope ) = intern -> ce ;
6170- retval = Z_OBJ_HT_P (object )-> has_property (Z_OBJ_P (object ), ref -> unmangled_name , ZEND_PROPERTY_EXISTS , NULL );
6224+ retval = Z_OBJ_HT_P (object )-> has_property (Z_OBJ_P (object ),
6225+ ref -> unmangled_name , ZEND_PROPERTY_EXISTS , ref -> cache_slot );
61716226 EG (fake_scope ) = old_scope ;
61726227
61736228 RETVAL_BOOL (retval );
0 commit comments