2929#include "spl_exceptions.h"
3030#include "ext/json/php_json.h" /* For php_json_serializable_ce */
3131
32- static zend_object_handlers spl_handler_SplFixedArray ;
32+ static zend_object_handlers spl_handler_SplFixedArray_base , spl_handler_SplFixedArray_proxied ;
3333PHPAPI zend_class_entry * spl_ce_SplFixedArray ;
3434
3535/* Check if the object is an instance of a subclass of SplFixedArray that overrides method's implementation.
36- * Expect subclassing SplFixedArray to be rare and check that first . */
37- #define HAS_FIXEDARRAY_ARRAYACCESS_OVERRIDE (object , method ) UNEXPECTED((object)->ce != spl_ce_SplFixedArray && (object)->ce ->arrayaccess_funcs_ptr->method->common.scope != spl_ce_SplFixedArray)
36+ * This is only done if we know for sure the instance is a subclass of SplFixedArray . */
37+ #define HAS_FIXEDARRAY_ARRAYACCESS_OVERRIDE (object , method ) UNEXPECTED((object)->ce->arrayaccess_funcs_ptr->method->common.scope != spl_ce_SplFixedArray)
3838
3939typedef struct _spl_fixedarray {
4040 zend_long size ;
@@ -302,6 +302,8 @@ static zend_object *spl_fixedarray_object_new_ex(zend_class_entry *class_type, z
302302 ZEND_ASSERT (parent );
303303
304304 if (UNEXPECTED (inherited )) {
305+ intern -> std .handlers = & spl_handler_SplFixedArray_proxied ;
306+
305307 /* Find count() method */
306308 zend_function * fptr_count = zend_hash_find_ptr (& class_type -> function_table , ZSTR_KNOWN (ZEND_STR_COUNT ));
307309 if (fptr_count -> common .scope == parent ) {
@@ -395,11 +397,22 @@ static zval *spl_fixedarray_object_read_dimension_helper(spl_fixedarray_object *
395397 }
396398}
397399
398- static int spl_fixedarray_object_has_dimension (zend_object * object , zval * offset , int check_empty );
400+ static int spl_fixedarray_object_has_dimension_proxied (zend_object * object , zval * offset , int check_empty );
401+ static int spl_fixedarray_object_has_dimension_base (zend_object * object , zval * offset , int check_empty );
402+
403+ static zval * spl_fixedarray_object_read_dimension_base (zend_object * object , zval * offset , int type , zval * rv )
404+ {
405+ if (type == BP_VAR_IS && !spl_fixedarray_object_has_dimension_base (object , offset , 0 )) {
406+ return & EG (uninitialized_zval );
407+ }
408+
409+ spl_fixedarray_object * intern = spl_fixed_array_from_obj (object );
410+ return spl_fixedarray_object_read_dimension_helper (intern , offset );
411+ }
399412
400- static zval * spl_fixedarray_object_read_dimension (zend_object * object , zval * offset , int type , zval * rv )
413+ static zval * spl_fixedarray_object_read_dimension_proxied (zend_object * object , zval * offset , int type , zval * rv )
401414{
402- if (type == BP_VAR_IS && !spl_fixedarray_object_has_dimension (object , offset , 0 )) {
415+ if (type == BP_VAR_IS && !spl_fixedarray_object_has_dimension_proxied (object , offset , 0 )) {
403416 return & EG (uninitialized_zval );
404417 }
405418
@@ -445,7 +458,13 @@ static void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_object *
445458 }
446459}
447460
448- static void spl_fixedarray_object_write_dimension (zend_object * object , zval * offset , zval * value )
461+ static void spl_fixedarray_object_write_dimension_base (zend_object * object , zval * offset , zval * value )
462+ {
463+ spl_fixedarray_object * intern = spl_fixed_array_from_obj (object );
464+ spl_fixedarray_object_write_dimension_helper (intern , offset , value );
465+ }
466+
467+ static void spl_fixedarray_object_write_dimension_proxied (zend_object * object , zval * offset , zval * value )
449468{
450469 if (HAS_FIXEDARRAY_ARRAYACCESS_OVERRIDE (object , zf_offsetset )) {
451470 zval tmp ;
@@ -458,8 +477,7 @@ static void spl_fixedarray_object_write_dimension(zend_object *object, zval *off
458477 return ;
459478 }
460479
461- spl_fixedarray_object * intern = spl_fixed_array_from_obj (object );
462- spl_fixedarray_object_write_dimension_helper (intern , offset , value );
480+ spl_fixedarray_object_write_dimension_base (object , offset , value );
463481}
464482
465483static void spl_fixedarray_object_unset_dimension_helper (spl_fixedarray_object * intern , zval * offset )
@@ -478,15 +496,20 @@ static void spl_fixedarray_object_unset_dimension_helper(spl_fixedarray_object *
478496 }
479497}
480498
481- static void spl_fixedarray_object_unset_dimension (zend_object * object , zval * offset )
499+ static void spl_fixedarray_object_unset_dimension_base (zend_object * object , zval * offset )
500+ {
501+ spl_fixedarray_object * intern = spl_fixed_array_from_obj (object );
502+ spl_fixedarray_object_unset_dimension_helper (intern , offset );
503+ }
504+
505+ static void spl_fixedarray_object_unset_dimension_proxied (zend_object * object , zval * offset )
482506{
483507 if (UNEXPECTED (HAS_FIXEDARRAY_ARRAYACCESS_OVERRIDE (object , zf_offsetunset ))) {
484508 zend_call_known_instance_method_with_1_params (object -> ce -> arrayaccess_funcs_ptr -> zf_offsetunset , object , NULL , offset );
485509 return ;
486510 }
487511
488- spl_fixedarray_object * intern = spl_fixed_array_from_obj (object );
489- spl_fixedarray_object_unset_dimension_helper (intern , offset );
512+ spl_fixedarray_object_unset_dimension_base (object , offset );
490513}
491514
492515static bool spl_fixedarray_object_has_dimension_helper (spl_fixedarray_object * intern , zval * offset , bool check_empty )
@@ -507,7 +530,13 @@ static bool spl_fixedarray_object_has_dimension_helper(spl_fixedarray_object *in
507530 return Z_TYPE (intern -> array .elements [index ]) != IS_NULL ;
508531}
509532
510- static int spl_fixedarray_object_has_dimension (zend_object * object , zval * offset , int check_empty )
533+ static int spl_fixedarray_object_has_dimension_base (zend_object * object , zval * offset , int check_empty )
534+ {
535+ spl_fixedarray_object * intern = spl_fixed_array_from_obj (object );
536+ return spl_fixedarray_object_has_dimension_helper (intern , offset , check_empty );
537+ }
538+
539+ static int spl_fixedarray_object_has_dimension_proxied (zend_object * object , zval * offset , int check_empty )
511540{
512541 if (HAS_FIXEDARRAY_ARRAYACCESS_OVERRIDE (object , zf_offsetexists )) {
513542 zval rv ;
@@ -518,9 +547,7 @@ static int spl_fixedarray_object_has_dimension(zend_object *object, zval *offset
518547 return result ;
519548 }
520549
521- spl_fixedarray_object * intern = spl_fixed_array_from_obj (object );
522-
523- return spl_fixedarray_object_has_dimension_helper (intern , offset , check_empty );
550+ return spl_fixedarray_object_has_dimension_base (object , offset , check_empty );
524551}
525552
526553static zend_result spl_fixedarray_object_count_elements (zend_object * object , zend_long * count )
@@ -973,21 +1000,28 @@ PHP_MINIT_FUNCTION(spl_fixedarray)
9731000 spl_ce_SplFixedArray = register_class_SplFixedArray (
9741001 zend_ce_aggregate , zend_ce_arrayaccess , zend_ce_countable , php_json_serializable_ce );
9751002 spl_ce_SplFixedArray -> create_object = spl_fixedarray_new ;
976- spl_ce_SplFixedArray -> default_object_handlers = & spl_handler_SplFixedArray ;
1003+ spl_ce_SplFixedArray -> default_object_handlers = & spl_handler_SplFixedArray_base ;
9771004 spl_ce_SplFixedArray -> get_iterator = spl_fixedarray_get_iterator ;
9781005
979- memcpy (& spl_handler_SplFixedArray , & std_object_handlers , sizeof (zend_object_handlers ));
980-
981- spl_handler_SplFixedArray .offset = XtOffsetOf (spl_fixedarray_object , std );
982- spl_handler_SplFixedArray .clone_obj = spl_fixedarray_object_clone ;
983- spl_handler_SplFixedArray .read_dimension = spl_fixedarray_object_read_dimension ;
984- spl_handler_SplFixedArray .write_dimension = spl_fixedarray_object_write_dimension ;
985- spl_handler_SplFixedArray .unset_dimension = spl_fixedarray_object_unset_dimension ;
986- spl_handler_SplFixedArray .has_dimension = spl_fixedarray_object_has_dimension ;
987- spl_handler_SplFixedArray .count_elements = spl_fixedarray_object_count_elements ;
988- spl_handler_SplFixedArray .get_properties_for = spl_fixedarray_object_get_properties_for ;
989- spl_handler_SplFixedArray .get_gc = spl_fixedarray_object_get_gc ;
990- spl_handler_SplFixedArray .free_obj = spl_fixedarray_object_free_storage ;
1006+ memcpy (& spl_handler_SplFixedArray_base , & std_object_handlers , sizeof (zend_object_handlers ));
1007+
1008+ spl_handler_SplFixedArray_base .offset = XtOffsetOf (spl_fixedarray_object , std );
1009+ spl_handler_SplFixedArray_base .clone_obj = spl_fixedarray_object_clone ;
1010+ spl_handler_SplFixedArray_base .read_dimension = spl_fixedarray_object_read_dimension_base ;
1011+ spl_handler_SplFixedArray_base .write_dimension = spl_fixedarray_object_write_dimension_base ;
1012+ spl_handler_SplFixedArray_base .unset_dimension = spl_fixedarray_object_unset_dimension_base ;
1013+ spl_handler_SplFixedArray_base .has_dimension = spl_fixedarray_object_has_dimension_base ;
1014+ spl_handler_SplFixedArray_base .count_elements = spl_fixedarray_object_count_elements ;
1015+ spl_handler_SplFixedArray_base .get_properties_for = spl_fixedarray_object_get_properties_for ;
1016+ spl_handler_SplFixedArray_base .get_gc = spl_fixedarray_object_get_gc ;
1017+ spl_handler_SplFixedArray_base .free_obj = spl_fixedarray_object_free_storage ;
1018+
1019+ memcpy (& spl_handler_SplFixedArray_proxied , & spl_handler_SplFixedArray_base , sizeof (zend_object_handlers ));
1020+
1021+ spl_handler_SplFixedArray_proxied .read_dimension = spl_fixedarray_object_read_dimension_proxied ;
1022+ spl_handler_SplFixedArray_proxied .write_dimension = spl_fixedarray_object_write_dimension_proxied ;
1023+ spl_handler_SplFixedArray_proxied .unset_dimension = spl_fixedarray_object_unset_dimension_proxied ;
1024+ spl_handler_SplFixedArray_proxied .has_dimension = spl_fixedarray_object_has_dimension_proxied ;
9911025
9921026 return SUCCESS ;
9931027}
0 commit comments