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 ;
@@ -290,6 +290,8 @@ static zend_object *spl_fixedarray_object_new_ex(zend_class_entry *class_type, z
290290 }
291291
292292 if (UNEXPECTED (class_type != spl_ce_SplFixedArray )) {
293+ intern -> std .handlers = & spl_handler_SplFixedArray_proxied ;
294+
293295 /* Find count() method */
294296 zend_function * fptr_count = zend_hash_find_ptr (& class_type -> function_table , ZSTR_KNOWN (ZEND_STR_COUNT ));
295297 if (fptr_count -> common .scope == spl_ce_SplFixedArray ) {
@@ -383,11 +385,22 @@ static zval *spl_fixedarray_object_read_dimension_helper(spl_fixedarray_object *
383385 }
384386}
385387
386- static int spl_fixedarray_object_has_dimension (zend_object * object , zval * offset , int check_empty );
388+ static int spl_fixedarray_object_has_dimension_proxied (zend_object * object , zval * offset , int check_empty );
389+ static int spl_fixedarray_object_has_dimension_base (zend_object * object , zval * offset , int check_empty );
390+
391+ static zval * spl_fixedarray_object_read_dimension_base (zend_object * object , zval * offset , int type , zval * rv )
392+ {
393+ if (type == BP_VAR_IS && !spl_fixedarray_object_has_dimension_base (object , offset , 0 )) {
394+ return & EG (uninitialized_zval );
395+ }
396+
397+ spl_fixedarray_object * intern = spl_fixed_array_from_obj (object );
398+ return spl_fixedarray_object_read_dimension_helper (intern , offset );
399+ }
387400
388- static zval * spl_fixedarray_object_read_dimension (zend_object * object , zval * offset , int type , zval * rv )
401+ static zval * spl_fixedarray_object_read_dimension_proxied (zend_object * object , zval * offset , int type , zval * rv )
389402{
390- if (type == BP_VAR_IS && !spl_fixedarray_object_has_dimension (object , offset , 0 )) {
403+ if (type == BP_VAR_IS && !spl_fixedarray_object_has_dimension_proxied (object , offset , 0 )) {
391404 return & EG (uninitialized_zval );
392405 }
393406
@@ -433,7 +446,13 @@ static void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_object *
433446 }
434447}
435448
436- static void spl_fixedarray_object_write_dimension (zend_object * object , zval * offset , zval * value )
449+ static void spl_fixedarray_object_write_dimension_base (zend_object * object , zval * offset , zval * value )
450+ {
451+ spl_fixedarray_object * intern = spl_fixed_array_from_obj (object );
452+ spl_fixedarray_object_write_dimension_helper (intern , offset , value );
453+ }
454+
455+ static void spl_fixedarray_object_write_dimension_proxied (zend_object * object , zval * offset , zval * value )
437456{
438457 if (HAS_FIXEDARRAY_ARRAYACCESS_OVERRIDE (object , zf_offsetset )) {
439458 zval tmp ;
@@ -446,8 +465,7 @@ static void spl_fixedarray_object_write_dimension(zend_object *object, zval *off
446465 return ;
447466 }
448467
449- spl_fixedarray_object * intern = spl_fixed_array_from_obj (object );
450- spl_fixedarray_object_write_dimension_helper (intern , offset , value );
468+ spl_fixedarray_object_write_dimension_base (object , offset , value );
451469}
452470
453471static void spl_fixedarray_object_unset_dimension_helper (spl_fixedarray_object * intern , zval * offset )
@@ -466,15 +484,20 @@ static void spl_fixedarray_object_unset_dimension_helper(spl_fixedarray_object *
466484 }
467485}
468486
469- static void spl_fixedarray_object_unset_dimension (zend_object * object , zval * offset )
487+ static void spl_fixedarray_object_unset_dimension_base (zend_object * object , zval * offset )
488+ {
489+ spl_fixedarray_object * intern = spl_fixed_array_from_obj (object );
490+ spl_fixedarray_object_unset_dimension_helper (intern , offset );
491+ }
492+
493+ static void spl_fixedarray_object_unset_dimension_proxied (zend_object * object , zval * offset )
470494{
471495 if (UNEXPECTED (HAS_FIXEDARRAY_ARRAYACCESS_OVERRIDE (object , zf_offsetunset ))) {
472496 zend_call_known_instance_method_with_1_params (object -> ce -> arrayaccess_funcs_ptr -> zf_offsetunset , object , NULL , offset );
473497 return ;
474498 }
475499
476- spl_fixedarray_object * intern = spl_fixed_array_from_obj (object );
477- spl_fixedarray_object_unset_dimension_helper (intern , offset );
500+ spl_fixedarray_object_unset_dimension_base (object , offset );
478501}
479502
480503static bool spl_fixedarray_object_has_dimension_helper (spl_fixedarray_object * intern , zval * offset , bool check_empty )
@@ -495,7 +518,13 @@ static bool spl_fixedarray_object_has_dimension_helper(spl_fixedarray_object *in
495518 return Z_TYPE (intern -> array .elements [index ]) != IS_NULL ;
496519}
497520
498- static int spl_fixedarray_object_has_dimension (zend_object * object , zval * offset , int check_empty )
521+ static int spl_fixedarray_object_has_dimension_base (zend_object * object , zval * offset , int check_empty )
522+ {
523+ spl_fixedarray_object * intern = spl_fixed_array_from_obj (object );
524+ return spl_fixedarray_object_has_dimension_helper (intern , offset , check_empty );
525+ }
526+
527+ static int spl_fixedarray_object_has_dimension_proxied (zend_object * object , zval * offset , int check_empty )
499528{
500529 if (HAS_FIXEDARRAY_ARRAYACCESS_OVERRIDE (object , zf_offsetexists )) {
501530 zval rv ;
@@ -506,9 +535,7 @@ static int spl_fixedarray_object_has_dimension(zend_object *object, zval *offset
506535 return result ;
507536 }
508537
509- spl_fixedarray_object * intern = spl_fixed_array_from_obj (object );
510-
511- return spl_fixedarray_object_has_dimension_helper (intern , offset , check_empty );
538+ return spl_fixedarray_object_has_dimension_base (object , offset , check_empty );
512539}
513540
514541static zend_result spl_fixedarray_object_count_elements (zend_object * object , zend_long * count )
@@ -961,21 +988,28 @@ PHP_MINIT_FUNCTION(spl_fixedarray)
961988 spl_ce_SplFixedArray = register_class_SplFixedArray (
962989 zend_ce_aggregate , zend_ce_arrayaccess , zend_ce_countable , php_json_serializable_ce );
963990 spl_ce_SplFixedArray -> create_object = spl_fixedarray_new ;
964- spl_ce_SplFixedArray -> default_object_handlers = & spl_handler_SplFixedArray ;
991+ spl_ce_SplFixedArray -> default_object_handlers = & spl_handler_SplFixedArray_base ;
965992 spl_ce_SplFixedArray -> get_iterator = spl_fixedarray_get_iterator ;
966993
967- memcpy (& spl_handler_SplFixedArray , & std_object_handlers , sizeof (zend_object_handlers ));
968-
969- spl_handler_SplFixedArray .offset = XtOffsetOf (spl_fixedarray_object , std );
970- spl_handler_SplFixedArray .clone_obj = spl_fixedarray_object_clone ;
971- spl_handler_SplFixedArray .read_dimension = spl_fixedarray_object_read_dimension ;
972- spl_handler_SplFixedArray .write_dimension = spl_fixedarray_object_write_dimension ;
973- spl_handler_SplFixedArray .unset_dimension = spl_fixedarray_object_unset_dimension ;
974- spl_handler_SplFixedArray .has_dimension = spl_fixedarray_object_has_dimension ;
975- spl_handler_SplFixedArray .count_elements = spl_fixedarray_object_count_elements ;
976- spl_handler_SplFixedArray .get_properties_for = spl_fixedarray_object_get_properties_for ;
977- spl_handler_SplFixedArray .get_gc = spl_fixedarray_object_get_gc ;
978- spl_handler_SplFixedArray .free_obj = spl_fixedarray_object_free_storage ;
994+ memcpy (& spl_handler_SplFixedArray_base , & std_object_handlers , sizeof (zend_object_handlers ));
995+
996+ spl_handler_SplFixedArray_base .offset = XtOffsetOf (spl_fixedarray_object , std );
997+ spl_handler_SplFixedArray_base .clone_obj = spl_fixedarray_object_clone ;
998+ spl_handler_SplFixedArray_base .read_dimension = spl_fixedarray_object_read_dimension_base ;
999+ spl_handler_SplFixedArray_base .write_dimension = spl_fixedarray_object_write_dimension_base ;
1000+ spl_handler_SplFixedArray_base .unset_dimension = spl_fixedarray_object_unset_dimension_base ;
1001+ spl_handler_SplFixedArray_base .has_dimension = spl_fixedarray_object_has_dimension_base ;
1002+ spl_handler_SplFixedArray_base .count_elements = spl_fixedarray_object_count_elements ;
1003+ spl_handler_SplFixedArray_base .get_properties_for = spl_fixedarray_object_get_properties_for ;
1004+ spl_handler_SplFixedArray_base .get_gc = spl_fixedarray_object_get_gc ;
1005+ spl_handler_SplFixedArray_base .free_obj = spl_fixedarray_object_free_storage ;
1006+
1007+ memcpy (& spl_handler_SplFixedArray_proxied , & spl_handler_SplFixedArray_base , sizeof (zend_object_handlers ));
1008+
1009+ spl_handler_SplFixedArray_proxied .read_dimension = spl_fixedarray_object_read_dimension_proxied ;
1010+ spl_handler_SplFixedArray_proxied .write_dimension = spl_fixedarray_object_write_dimension_proxied ;
1011+ spl_handler_SplFixedArray_proxied .unset_dimension = spl_fixedarray_object_unset_dimension_proxied ;
1012+ spl_handler_SplFixedArray_proxied .has_dimension = spl_fixedarray_object_has_dimension_proxied ;
9791013
9801014 return SUCCESS ;
9811015}
0 commit comments