@@ -175,9 +175,9 @@ ZEND_API HashTable *zend_std_get_debug_info(zval *object, int *is_temp) /* {{{ *
175
175
}
176
176
/* }}} */
177
177
178
- static void zend_std_call_getter (zval * object , zval * member , zval * retval ) /* {{{ */
178
+ static void zend_std_call_getter (zend_object * zobj , zval * member , zval * retval ) /* {{{ */
179
179
{
180
- zend_class_entry * ce = Z_OBJCE_P ( object ) ;
180
+ zend_class_entry * ce = zobj -> ce ;
181
181
zend_class_entry * orig_fake_scope = EG (fake_scope );
182
182
zend_fcall_info fci ;
183
183
zend_fcall_info_cache fcic ;
@@ -191,7 +191,7 @@ static void zend_std_call_getter(zval *object, zval *member, zval *retval) /* {{
191
191
*/
192
192
193
193
fci .size = sizeof (fci );
194
- fci .object = Z_OBJ_P ( object ) ;
194
+ fci .object = zobj ;
195
195
fci .retval = retval ;
196
196
fci .param_count = 1 ;
197
197
fci .params = member ;
@@ -200,17 +200,17 @@ static void zend_std_call_getter(zval *object, zval *member, zval *retval) /* {{
200
200
201
201
fcic .function_handler = ce -> __get ;
202
202
fcic .called_scope = ce ;
203
- fcic .object = Z_OBJ_P ( object ) ;
203
+ fcic .object = zobj ;
204
204
205
205
zend_call_function (& fci , & fcic );
206
206
207
207
EG (fake_scope ) = orig_fake_scope ;
208
208
}
209
209
/* }}} */
210
210
211
- static void zend_std_call_setter (zval * object , zval * member , zval * value ) /* {{{ */
211
+ static void zend_std_call_setter (zend_object * zobj , zval * member , zval * value ) /* {{{ */
212
212
{
213
- zend_class_entry * ce = Z_OBJCE_P ( object ) ;
213
+ zend_class_entry * ce = zobj -> ce ;
214
214
zend_class_entry * orig_fake_scope = EG (fake_scope );
215
215
zend_fcall_info fci ;
216
216
zend_fcall_info_cache fcic ;
@@ -228,7 +228,7 @@ static void zend_std_call_setter(zval *object, zval *member, zval *value) /* {{{
228
228
ZVAL_UNDEF (& ret );
229
229
230
230
fci .size = sizeof (fci );
231
- fci .object = Z_OBJ_P ( object ) ;
231
+ fci .object = zobj ;
232
232
fci .retval = & ret ;
233
233
fci .param_count = 2 ;
234
234
fci .params = args ;
@@ -237,7 +237,7 @@ static void zend_std_call_setter(zval *object, zval *member, zval *value) /* {{{
237
237
238
238
fcic .function_handler = ce -> __set ;
239
239
fcic .called_scope = ce ;
240
- fcic .object = Z_OBJ_P ( object ) ;
240
+ fcic .object = zobj ;
241
241
242
242
zend_call_function (& fci , & fcic );
243
243
zval_ptr_dtor (& ret );
@@ -246,9 +246,9 @@ static void zend_std_call_setter(zval *object, zval *member, zval *value) /* {{{
246
246
}
247
247
/* }}} */
248
248
249
- static void zend_std_call_unsetter (zval * object , zval * member ) /* {{{ */
249
+ static void zend_std_call_unsetter (zend_object * zobj , zval * member ) /* {{{ */
250
250
{
251
- zend_class_entry * ce = Z_OBJCE_P ( object ) ;
251
+ zend_class_entry * ce = zobj -> ce ;
252
252
zend_class_entry * orig_fake_scope = EG (fake_scope );
253
253
zend_fcall_info fci ;
254
254
zend_fcall_info_cache fcic ;
@@ -263,7 +263,7 @@ static void zend_std_call_unsetter(zval *object, zval *member) /* {{{ */
263
263
ZVAL_UNDEF (& ret );
264
264
265
265
fci .size = sizeof (fci );
266
- fci .object = Z_OBJ_P ( object ) ;
266
+ fci .object = zobj ;
267
267
fci .retval = & ret ;
268
268
fci .param_count = 1 ;
269
269
fci .params = member ;
@@ -272,7 +272,7 @@ static void zend_std_call_unsetter(zval *object, zval *member) /* {{{ */
272
272
273
273
fcic .function_handler = ce -> __unset ;
274
274
fcic .called_scope = ce ;
275
- fcic .object = Z_OBJ_P ( object ) ;
275
+ fcic .object = zobj ;
276
276
277
277
zend_call_function (& fci , & fcic );
278
278
zval_ptr_dtor (& ret );
@@ -281,9 +281,9 @@ static void zend_std_call_unsetter(zval *object, zval *member) /* {{{ */
281
281
}
282
282
/* }}} */
283
283
284
- static void zend_std_call_issetter (zval * object , zval * member , zval * retval ) /* {{{ */
284
+ static void zend_std_call_issetter (zend_object * zobj , zval * member , zval * retval ) /* {{{ */
285
285
{
286
- zend_class_entry * ce = Z_OBJCE_P ( object ) ;
286
+ zend_class_entry * ce = zobj -> ce ;
287
287
zend_class_entry * orig_fake_scope = EG (fake_scope );
288
288
zend_fcall_info fci ;
289
289
zend_fcall_info_cache fcic ;
@@ -297,7 +297,7 @@ static void zend_std_call_issetter(zval *object, zval *member, zval *retval) /*
297
297
*/
298
298
299
299
fci .size = sizeof (fci );
300
- fci .object = Z_OBJ_P ( object ) ;
300
+ fci .object = zobj ;
301
301
fci .retval = retval ;
302
302
fci .param_count = 1 ;
303
303
fci .params = member ;
@@ -306,7 +306,7 @@ static void zend_std_call_issetter(zval *object, zval *member, zval *retval) /*
306
306
307
307
fcic .function_handler = ce -> __isset ;
308
308
fcic .called_scope = ce ;
309
- fcic .object = Z_OBJ_P ( object ) ;
309
+ fcic .object = zobj ;
310
310
311
311
zend_call_function (& fci , & fcic );
312
312
@@ -607,7 +607,7 @@ ZEND_API uint32_t *zend_get_property_guard(zend_object *zobj, zend_string *membe
607
607
ZEND_API zval * zend_std_read_property (zval * object , zval * member , int type , void * * cache_slot , zval * rv ) /* {{{ */
608
608
{
609
609
zend_object * zobj ;
610
- zval tmp_member , tmp_object ;
610
+ zval tmp_member ;
611
611
zval * retval ;
612
612
uintptr_t property_offset ;
613
613
uint32_t * guard = NULL ;
@@ -666,8 +666,6 @@ ZEND_API zval *zend_std_read_property(zval *object, zval *member, int type, void
666
666
goto exit ;
667
667
}
668
668
669
- ZVAL_UNDEF (& tmp_object );
670
-
671
669
/* magic isset */
672
670
if ((type == BP_VAR_IS ) && zobj -> ce -> __isset ) {
673
671
zval tmp_result ;
@@ -678,36 +676,38 @@ ZEND_API zval *zend_std_read_property(zval *object, zval *member, int type, void
678
676
ZVAL_COPY (& tmp_member , member );
679
677
member = & tmp_member ;
680
678
}
681
- ZVAL_COPY ( & tmp_object , object );
679
+ GC_ADDREF ( zobj );
682
680
ZVAL_UNDEF (& tmp_result );
683
681
684
682
* guard |= IN_ISSET ;
685
- zend_std_call_issetter (& tmp_object , member , & tmp_result );
683
+ zend_std_call_issetter (zobj , member , & tmp_result );
686
684
* guard &= ~IN_ISSET ;
687
685
688
686
if (!zend_is_true (& tmp_result )) {
689
687
retval = & EG (uninitialized_zval );
690
- zval_ptr_dtor ( & tmp_object );
688
+ OBJ_RELEASE ( zobj );
691
689
zval_ptr_dtor (& tmp_result );
692
690
goto exit ;
693
691
}
694
692
695
693
zval_ptr_dtor (& tmp_result );
694
+ if (zobj -> ce -> __get && !((* guard ) & IN_GET )) {
695
+ goto call_getter ;
696
+ }
697
+ OBJ_RELEASE (zobj );
698
+ } else if (zobj -> ce -> __get && !((* guard ) & IN_GET )) {
699
+ goto call_getter_addref ;
696
700
}
697
- }
698
-
699
- /* magic get */
700
- if (zobj -> ce -> __get ) {
701
- if (guard == NULL ) {
702
- guard = zend_get_property_guard (zobj , Z_STR_P (member ));
703
- }
701
+ } else if (zobj -> ce -> __get ) {
702
+ /* magic get */
703
+ guard = zend_get_property_guard (zobj , Z_STR_P (member ));
704
704
if (!((* guard ) & IN_GET )) {
705
705
/* have getter - try with it! */
706
- if ( Z_TYPE ( tmp_object ) == IS_UNDEF ) {
707
- ZVAL_COPY ( & tmp_object , object );
708
- }
706
+ call_getter_addref :
707
+ GC_ADDREF ( zobj );
708
+ call_getter :
709
709
* guard |= IN_GET ; /* prevent circular getting */
710
- zend_std_call_getter (& tmp_object , member , rv );
710
+ zend_std_call_getter (zobj , member , rv );
711
711
* guard &= ~IN_GET ;
712
712
713
713
if (Z_TYPE_P (rv ) != IS_UNDEF ) {
@@ -721,18 +721,15 @@ ZEND_API zval *zend_std_read_property(zval *object, zval *member, int type, void
721
721
} else {
722
722
retval = & EG (uninitialized_zval );
723
723
}
724
- zval_ptr_dtor ( & tmp_object );
724
+ OBJ_RELEASE ( zobj );
725
725
goto exit ;
726
726
} else if (Z_STRVAL_P (member )[0 ] == '\0' && Z_STRLEN_P (member ) != 0 ) {
727
- zval_ptr_dtor (& tmp_object );
728
727
zend_throw_error (NULL , "Cannot access property started with '\\0'" );
729
728
retval = & EG (uninitialized_zval );
730
729
goto exit ;
731
730
}
732
731
}
733
732
734
- zval_ptr_dtor (& tmp_object );
735
-
736
733
if ((type != BP_VAR_IS )) {
737
734
zend_error (E_NOTICE ,"Undefined property: %s::$%s" , ZSTR_VAL (zobj -> ce -> name ), Z_STRVAL_P (member ));
738
735
}
@@ -793,13 +790,11 @@ ZEND_API void zend_std_write_property(zval *object, zval *member, zval *value, v
793
790
uint32_t * guard = zend_get_property_guard (zobj , Z_STR_P (member ));
794
791
795
792
if (!((* guard ) & IN_SET )) {
796
- zval tmp_object ;
797
-
798
- ZVAL_COPY (& tmp_object , object );
793
+ GC_ADDREF (zobj );
799
794
(* guard ) |= IN_SET ; /* prevent circular setting */
800
- zend_std_call_setter (& tmp_object , member , value );
795
+ zend_std_call_setter (zobj , member , value );
801
796
(* guard ) &= ~IN_SET ;
802
- zval_ptr_dtor ( & tmp_object );
797
+ OBJ_RELEASE ( zobj );
803
798
} else if (EXPECTED (!IS_WRONG_PROPERTY_OFFSET (property_offset ))) {
804
799
goto write_std_property ;
805
800
} else {
@@ -1052,14 +1047,10 @@ ZEND_API void zend_std_unset_property(zval *object, zval *member, void **cache_s
1052
1047
if (zobj -> ce -> __unset ) {
1053
1048
uint32_t * guard = zend_get_property_guard (zobj , Z_STR_P (member ));
1054
1049
if (!((* guard ) & IN_UNSET )) {
1055
- zval tmp_object ;
1056
-
1057
1050
/* have unseter - try with it! */
1058
- ZVAL_COPY (& tmp_object , object );
1059
1051
(* guard ) |= IN_UNSET ; /* prevent circular unsetting */
1060
- zend_std_call_unsetter (& tmp_object , member );
1052
+ zend_std_call_unsetter (zobj , member );
1061
1053
(* guard ) &= ~IN_UNSET ;
1062
- zval_ptr_dtor (& tmp_object );
1063
1054
} else {
1064
1055
if (Z_STRVAL_P (member )[0 ] == '\0' && Z_STRLEN_P (member ) != 0 ) {
1065
1056
zend_throw_error (NULL , "Cannot access property started with '\\0'" );
@@ -1276,7 +1267,7 @@ ZEND_API zend_function *zend_std_get_method(zend_object **obj_ptr, zend_string *
1276
1267
/* Ensure that we haven't overridden a private function and end up calling
1277
1268
* the overriding public function...
1278
1269
*/
1279
-
1270
+
1280
1271
scope = zend_get_executed_scope ();
1281
1272
if (fbc -> op_array .fn_flags & ZEND_ACC_CHANGED ) {
1282
1273
if (scope && is_derived_class (fbc -> common .scope , scope )) {
@@ -1693,23 +1684,22 @@ ZEND_API int zend_std_has_property(zval *object, zval *member, int has_set_exist
1693
1684
1694
1685
if (!((* guard ) & IN_ISSET )) {
1695
1686
zval rv ;
1696
- zval tmp_object ;
1697
1687
1698
1688
/* have issetter - try with it! */
1699
1689
if (Z_TYPE (tmp_member ) == IS_UNDEF ) {
1700
1690
ZVAL_COPY (& tmp_member , member );
1701
1691
member = & tmp_member ;
1702
1692
}
1703
- ZVAL_COPY ( & tmp_object , object );
1693
+ GC_ADDREF ( zobj );
1704
1694
(* guard ) |= IN_ISSET ; /* prevent circular getting */
1705
- zend_std_call_issetter (& tmp_object , member , & rv );
1695
+ zend_std_call_issetter (zobj , member , & rv );
1706
1696
if (Z_TYPE (rv ) != IS_UNDEF ) {
1707
1697
result = zend_is_true (& rv );
1708
1698
zval_ptr_dtor (& rv );
1709
1699
if (has_set_exists && result ) {
1710
1700
if (EXPECTED (!EG (exception )) && zobj -> ce -> __get && !((* guard ) & IN_GET )) {
1711
1701
(* guard ) |= IN_GET ;
1712
- zend_std_call_getter (& tmp_object , member , & rv );
1702
+ zend_std_call_getter (zobj , member , & rv );
1713
1703
(* guard ) &= ~IN_GET ;
1714
1704
if (Z_TYPE (rv ) != IS_UNDEF ) {
1715
1705
result = i_zend_is_true (& rv );
@@ -1723,7 +1713,7 @@ ZEND_API int zend_std_has_property(zval *object, zval *member, int has_set_exist
1723
1713
}
1724
1714
}
1725
1715
(* guard ) &= ~IN_ISSET ;
1726
- zval_ptr_dtor ( & tmp_object );
1716
+ OBJ_RELEASE ( zobj );
1727
1717
}
1728
1718
}
1729
1719
0 commit comments