@@ -132,6 +132,7 @@ PHPAPI zend_class_entry *reflection_property_hook_type_ptr;
132
132
typedef struct _property_reference {
133
133
zend_property_info * prop ;
134
134
zend_string * unmangled_name ;
135
+ void * cache_slot [3 ];
135
136
} property_reference ;
136
137
137
138
/* Struct for parameters */
@@ -1506,6 +1507,7 @@ static void reflection_property_factory(zend_class_entry *ce, zend_string *name,
1506
1507
reference = (property_reference * ) emalloc (sizeof (property_reference ));
1507
1508
reference -> prop = prop ;
1508
1509
reference -> unmangled_name = zend_string_copy (name );
1510
+ memset (reference -> cache_slot , 0 , sizeof (reference -> cache_slot ));
1509
1511
intern -> ptr = reference ;
1510
1512
intern -> ref_type = REF_TYPE_PROPERTY ;
1511
1513
intern -> ce = ce ;
@@ -5638,6 +5640,7 @@ ZEND_METHOD(ReflectionProperty, __construct)
5638
5640
reference = (property_reference * ) emalloc (sizeof (property_reference ));
5639
5641
reference -> prop = dynam_prop ? NULL : property_info ;
5640
5642
reference -> unmangled_name = zend_string_copy (name );
5643
+ memset (reference -> cache_slot , 0 , sizeof (reference -> cache_slot ));
5641
5644
intern -> ptr = reference ;
5642
5645
intern -> ref_type = REF_TYPE_PROPERTY ;
5643
5646
intern -> ce = ce ;
@@ -5789,9 +5792,10 @@ ZEND_METHOD(ReflectionProperty, getValue)
5789
5792
zval * object = NULL ;
5790
5793
zval * member_p = NULL ;
5791
5794
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 ();
5795
5799
5796
5800
GET_REFLECTION_OBJECT_PTR (ref );
5797
5801
@@ -5814,7 +5818,23 @@ ZEND_METHOD(ReflectionProperty, getValue)
5814
5818
RETURN_THROWS ();
5815
5819
}
5816
5820
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
+
5818
5838
if (member_p != & rv ) {
5819
5839
RETURN_COPY_DEREF (member_p );
5820
5840
} else {
@@ -5868,7 +5888,10 @@ ZEND_METHOD(ReflectionProperty, setValue)
5868
5888
Z_PARAM_ZVAL (value )
5869
5889
ZEND_PARSE_PARAMETERS_END ();
5870
5890
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 ;
5872
5895
}
5873
5896
}
5874
5897
/* }}} */
@@ -5892,9 +5915,9 @@ ZEND_METHOD(ReflectionProperty, getRawValue)
5892
5915
property_reference * ref ;
5893
5916
zval * object ;
5894
5917
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 ();
5898
5921
5899
5922
GET_REFLECTION_OBJECT_PTR (ref );
5900
5923
@@ -5903,6 +5926,17 @@ ZEND_METHOD(ReflectionProperty, getRawValue)
5903
5926
RETURN_THROWS ();
5904
5927
}
5905
5928
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
+
5906
5940
zend_property_info * prop = reflection_property_get_effective_prop (ref ,
5907
5941
intern -> ce , Z_OBJ_P (object ));
5908
5942
@@ -5913,7 +5947,12 @@ ZEND_METHOD(ReflectionProperty, getRawValue)
5913
5947
5914
5948
if (!prop || !prop -> hooks || !prop -> hooks [ZEND_PROPERTY_HOOK_GET ]) {
5915
5949
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 ;
5917
5956
5918
5957
if (member_p != & rv ) {
5919
5958
RETURN_COPY_DEREF (member_p );
@@ -5930,11 +5969,14 @@ ZEND_METHOD(ReflectionProperty, getRawValue)
5930
5969
}
5931
5970
5932
5971
static 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 ,
5934
5973
zend_object * object , zval * value )
5935
5974
{
5936
5975
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 ;
5938
5980
} else {
5939
5981
zend_function * func = zend_get_property_hook_trampoline (prop , ZEND_PROPERTY_HOOK_SET , unmangled_name );
5940
5982
zend_call_known_instance_method_with_1_params (func , object , NULL , value );
@@ -5950,9 +5992,10 @@ ZEND_METHOD(ReflectionProperty, setRawValue)
5950
5992
5951
5993
GET_REFLECTION_OBJECT_PTR (ref );
5952
5994
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 ();
5956
5999
5957
6000
zend_property_info * prop = reflection_property_get_effective_prop (ref ,
5958
6001
intern -> ce , Z_OBJ_P (object ));
@@ -5962,7 +6005,8 @@ ZEND_METHOD(ReflectionProperty, setRawValue)
5962
6005
RETURN_THROWS ();
5963
6006
}
5964
6007
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 );
5966
6010
}
5967
6011
5968
6012
static zend_result reflection_property_check_lazy_compatible (
@@ -6041,8 +6085,8 @@ ZEND_METHOD(ReflectionProperty, setRawValueWithoutLazyInitialization)
6041
6085
/* Do not trigger initialization */
6042
6086
Z_PROP_FLAG_P (var_ptr ) &= ~IS_PROP_LAZY ;
6043
6087
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 );
6046
6090
6047
6091
/* Mark property as lazy again if an exception prevented update */
6048
6092
if (EG (exception ) && prop_was_lazy && Z_TYPE_P (var_ptr ) == IS_UNDEF
@@ -6138,9 +6182,10 @@ ZEND_METHOD(ReflectionProperty, isInitialized)
6138
6182
zval * object = NULL ;
6139
6183
zval * member_p = NULL ;
6140
6184
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 ();
6144
6189
6145
6190
GET_REFLECTION_OBJECT_PTR (ref );
6146
6191
@@ -6165,9 +6210,19 @@ ZEND_METHOD(ReflectionProperty, isInitialized)
6165
6210
RETURN_THROWS ();
6166
6211
}
6167
6212
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
+
6168
6222
old_scope = EG (fake_scope );
6169
6223
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 );
6171
6226
EG (fake_scope ) = old_scope ;
6172
6227
6173
6228
RETVAL_BOOL (retval );
0 commit comments