@@ -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 ;
@@ -5643,6 +5645,7 @@ ZEND_METHOD(ReflectionProperty, __construct)
5643
5645
reference = (property_reference * ) emalloc (sizeof (property_reference ));
5644
5646
reference -> prop = dynam_prop ? NULL : property_info ;
5645
5647
reference -> unmangled_name = zend_string_copy (name );
5648
+ memset (reference -> cache_slot , 0 , sizeof (reference -> cache_slot ));
5646
5649
intern -> ptr = reference ;
5647
5650
intern -> ref_type = REF_TYPE_PROPERTY ;
5648
5651
intern -> ce = ce ;
@@ -5794,9 +5797,10 @@ ZEND_METHOD(ReflectionProperty, getValue)
5794
5797
zval * object = NULL ;
5795
5798
zval * member_p = NULL ;
5796
5799
5797
- if (zend_parse_parameters (ZEND_NUM_ARGS (), "|o!" , & object ) == FAILURE ) {
5798
- RETURN_THROWS ();
5799
- }
5800
+ ZEND_PARSE_PARAMETERS_START (0 , 1 )
5801
+ Z_PARAM_OPTIONAL
5802
+ Z_PARAM_OBJECT_EX (object , 1 , 0 )
5803
+ ZEND_PARSE_PARAMETERS_END ();
5800
5804
5801
5805
GET_REFLECTION_OBJECT_PTR (ref );
5802
5806
@@ -5813,13 +5817,29 @@ ZEND_METHOD(ReflectionProperty, getValue)
5813
5817
RETURN_THROWS ();
5814
5818
}
5815
5819
5816
- /* TODO: Should this always use intern->ce? */
5817
- if (!instanceof_function (Z_OBJCE_P (object ), ref -> prop ? ref -> prop -> ce : intern -> ce )) {
5818
- _DO_THROW ("Given object is not an instance of the class this property was declared in" );
5819
- RETURN_THROWS ();
5820
+ if (ref -> cache_slot [0 ] == Z_OBJCE_P (object )) {
5821
+ uintptr_t prop_offset = (uintptr_t ) ref -> cache_slot [1 ];
5822
+
5823
+ if (EXPECTED (IS_VALID_PROPERTY_OFFSET (prop_offset ))) {
5824
+ zval * retval = OBJ_PROP (Z_OBJ_P (object ), prop_offset );
5825
+ if (EXPECTED (Z_TYPE_INFO_P (retval ) != IS_UNDEF )) {
5826
+ RETURN_COPY_DEREF (retval );
5827
+ }
5828
+ }
5829
+ } else {
5830
+ /* TODO: Should this always use intern->ce? */
5831
+ if (!instanceof_function (Z_OBJCE_P (object ), ref -> prop ? ref -> prop -> ce : intern -> ce )) {
5832
+ _DO_THROW ("Given object is not an instance of the class this property was declared in" );
5833
+ RETURN_THROWS ();
5834
+ }
5820
5835
}
5821
5836
5822
- member_p = zend_read_property_ex (intern -> ce , Z_OBJ_P (object ), ref -> unmangled_name , 0 , & rv );
5837
+ zend_class_entry * old_scope = EG (fake_scope );
5838
+ EG (fake_scope ) = intern -> ce ;
5839
+ member_p = Z_OBJ_P (object )-> handlers -> read_property (Z_OBJ_P (object ),
5840
+ ref -> unmangled_name , BP_VAR_R , ref -> cache_slot , & rv );
5841
+ EG (fake_scope ) = old_scope ;
5842
+
5823
5843
if (member_p != & rv ) {
5824
5844
RETURN_COPY_DEREF (member_p );
5825
5845
} else {
@@ -5873,7 +5893,10 @@ ZEND_METHOD(ReflectionProperty, setValue)
5873
5893
Z_PARAM_ZVAL (value )
5874
5894
ZEND_PARSE_PARAMETERS_END ();
5875
5895
5876
- zend_update_property_ex (intern -> ce , object , ref -> unmangled_name , value );
5896
+ zend_class_entry * old_scope = EG (fake_scope );
5897
+ EG (fake_scope ) = intern -> ce ;
5898
+ object -> handlers -> write_property (object , ref -> unmangled_name , value , ref -> cache_slot );
5899
+ EG (fake_scope ) = old_scope ;
5877
5900
}
5878
5901
}
5879
5902
/* }}} */
@@ -5884,25 +5907,41 @@ ZEND_METHOD(ReflectionProperty, getRawValue)
5884
5907
property_reference * ref ;
5885
5908
zval * object ;
5886
5909
5887
- if ( zend_parse_parameters ( ZEND_NUM_ARGS (), "o" , & object ) == FAILURE ) {
5888
- RETURN_THROWS ();
5889
- }
5910
+ ZEND_PARSE_PARAMETERS_START ( 1 , 1 )
5911
+ Z_PARAM_OBJECT ( object )
5912
+ ZEND_PARSE_PARAMETERS_END ();
5890
5913
5891
5914
GET_REFLECTION_OBJECT_PTR (ref );
5892
5915
5893
- if (prop_get_flags (ref ) & ZEND_ACC_STATIC ) {
5894
- _DO_THROW ("May not use getRawValue on static properties" );
5895
- RETURN_THROWS ();
5896
- }
5916
+ if (ref -> cache_slot [0 ] == Z_OBJCE_P (object )) {
5917
+ uintptr_t prop_offset = (uintptr_t ) ref -> cache_slot [1 ];
5897
5918
5898
- if (!instanceof_function (Z_OBJCE_P (object ), intern -> ce )) {
5899
- _DO_THROW ("Given object is not an instance of the class this property was declared in" );
5900
- RETURN_THROWS ();
5919
+ if (EXPECTED (IS_VALID_PROPERTY_OFFSET (prop_offset ))) {
5920
+ zval * retval = OBJ_PROP (Z_OBJ_P (object ), prop_offset );
5921
+ if (EXPECTED (Z_TYPE_INFO_P (retval ) != IS_UNDEF )) {
5922
+ RETURN_COPY_DEREF (retval );
5923
+ }
5924
+ }
5925
+ } else {
5926
+ if (prop_get_flags (ref ) & ZEND_ACC_STATIC ) {
5927
+ _DO_THROW ("May not use getRawValue on static properties" );
5928
+ RETURN_THROWS ();
5929
+ }
5930
+
5931
+ if (!instanceof_function (Z_OBJCE_P (object ), intern -> ce )) {
5932
+ _DO_THROW ("Given object is not an instance of the class this property was declared in" );
5933
+ RETURN_THROWS ();
5934
+ }
5901
5935
}
5902
5936
5903
5937
if (!ref -> prop || !ref -> prop -> hooks || !ref -> prop -> hooks [ZEND_PROPERTY_HOOK_GET ]) {
5904
5938
zval rv ;
5905
- zval * member_p = zend_read_property_ex (intern -> ce , Z_OBJ_P (object ), ref -> unmangled_name , 0 , & rv );
5939
+ zend_class_entry * old_scope = EG (fake_scope );
5940
+ EG (fake_scope ) = intern -> ce ;
5941
+ zval * member_p = Z_OBJ_P (object )-> handlers -> read_property (
5942
+ Z_OBJ_P (object ), ref -> unmangled_name , BP_VAR_R ,
5943
+ ref -> cache_slot , & rv );
5944
+ EG (fake_scope ) = old_scope ;
5906
5945
5907
5946
if (member_p != & rv ) {
5908
5947
RETURN_COPY_DEREF (member_p );
@@ -5921,7 +5960,10 @@ ZEND_METHOD(ReflectionProperty, getRawValue)
5921
5960
static void reflection_property_set_raw_value (property_reference * ref , reflection_object * intern , zend_object * object , zval * value )
5922
5961
{
5923
5962
if (!ref -> prop || !ref -> prop -> hooks || !ref -> prop -> hooks [ZEND_PROPERTY_HOOK_SET ]) {
5924
- zend_update_property_ex (intern -> ce , object , ref -> unmangled_name , value );
5963
+ zend_class_entry * old_scope = EG (fake_scope );
5964
+ EG (fake_scope ) = intern -> ce ;
5965
+ object -> handlers -> write_property (object , ref -> unmangled_name , value , ref -> cache_slot );
5966
+ EG (fake_scope ) = old_scope ;
5925
5967
} else {
5926
5968
zend_function * func = zend_get_property_hook_trampoline (ref -> prop , ZEND_PROPERTY_HOOK_SET , ref -> unmangled_name );
5927
5969
zend_call_known_instance_method_with_1_params (func , object , NULL , value );
@@ -5942,9 +5984,10 @@ ZEND_METHOD(ReflectionProperty, setRawValue)
5942
5984
RETURN_THROWS ();
5943
5985
}
5944
5986
5945
- if (zend_parse_parameters (ZEND_NUM_ARGS (), "oz" , & object , & value ) == FAILURE ) {
5946
- RETURN_THROWS ();
5947
- }
5987
+ ZEND_PARSE_PARAMETERS_START (2 , 2 ) {
5988
+ Z_PARAM_OBJECT (object )
5989
+ Z_PARAM_ZVAL (value )
5990
+ } ZEND_PARSE_PARAMETERS_END ();
5948
5991
5949
5992
reflection_property_set_raw_value (ref , intern , Z_OBJ_P (object ), value );
5950
5993
}
@@ -6116,9 +6159,10 @@ ZEND_METHOD(ReflectionProperty, isInitialized)
6116
6159
zval * object = NULL ;
6117
6160
zval * member_p = NULL ;
6118
6161
6119
- if (zend_parse_parameters (ZEND_NUM_ARGS (), "|o!" , & object ) == FAILURE ) {
6120
- RETURN_THROWS ();
6121
- }
6162
+ ZEND_PARSE_PARAMETERS_START (0 , 1 )
6163
+ Z_PARAM_OPTIONAL
6164
+ Z_PARAM_OBJECT_EX (object , 1 , 0 )
6165
+ ZEND_PARSE_PARAMETERS_END ();
6122
6166
6123
6167
GET_REFLECTION_OBJECT_PTR (ref );
6124
6168
@@ -6137,15 +6181,25 @@ ZEND_METHOD(ReflectionProperty, isInitialized)
6137
6181
RETURN_THROWS ();
6138
6182
}
6139
6183
6140
- /* TODO: Should this always use intern->ce? */
6141
- if (!instanceof_function (Z_OBJCE_P (object ), ref -> prop ? ref -> prop -> ce : intern -> ce )) {
6142
- _DO_THROW ("Given object is not an instance of the class this property was declared in" );
6143
- RETURN_THROWS ();
6184
+ if (ref -> cache_slot [0 ] == Z_OBJCE_P (object )) {
6185
+ uintptr_t prop_offset = (uintptr_t ) ref -> cache_slot [1 ];
6186
+
6187
+ if (EXPECTED (IS_VALID_PROPERTY_OFFSET (prop_offset ))) {
6188
+ zval * value = OBJ_PROP (Z_OBJ_P (object ), prop_offset );
6189
+ RETURN_BOOL (Z_TYPE_INFO_P (value ) != IS_UNDEF );
6190
+ }
6191
+ } else {
6192
+ /* TODO: Should this always use intern->ce? */
6193
+ if (!instanceof_function (Z_OBJCE_P (object ), ref -> prop ? ref -> prop -> ce : intern -> ce )) {
6194
+ _DO_THROW ("Given object is not an instance of the class this property was declared in" );
6195
+ RETURN_THROWS ();
6196
+ }
6144
6197
}
6145
6198
6146
6199
old_scope = EG (fake_scope );
6147
6200
EG (fake_scope ) = intern -> ce ;
6148
- retval = Z_OBJ_HT_P (object )-> has_property (Z_OBJ_P (object ), ref -> unmangled_name , ZEND_PROPERTY_EXISTS , NULL );
6201
+ retval = Z_OBJ_HT_P (object )-> has_property (Z_OBJ_P (object ),
6202
+ ref -> unmangled_name , ZEND_PROPERTY_EXISTS , ref -> cache_slot );
6149
6203
EG (fake_scope ) = old_scope ;
6150
6204
6151
6205
RETVAL_BOOL (retval );
0 commit comments