29
29
#include "spl_exceptions.h"
30
30
#include "ext/json/php_json.h" /* For php_json_serializable_ce */
31
31
32
- static zend_object_handlers spl_handler_SplFixedArray ;
32
+ static zend_object_handlers spl_handler_SplFixedArray_base , spl_handler_SplFixedArray_proxied ;
33
33
PHPAPI zend_class_entry * spl_ce_SplFixedArray ;
34
34
35
35
/* 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)
38
38
39
39
typedef struct _spl_fixedarray {
40
40
zend_long size ;
@@ -302,6 +302,8 @@ static zend_object *spl_fixedarray_object_new_ex(zend_class_entry *class_type, z
302
302
ZEND_ASSERT (parent );
303
303
304
304
if (UNEXPECTED (inherited )) {
305
+ intern -> std .handlers = & spl_handler_SplFixedArray_proxied ;
306
+
305
307
/* Find count() method */
306
308
zend_function * fptr_count = zend_hash_find_ptr (& class_type -> function_table , ZSTR_KNOWN (ZEND_STR_COUNT ));
307
309
if (fptr_count -> common .scope == parent ) {
@@ -395,11 +397,22 @@ static zval *spl_fixedarray_object_read_dimension_helper(spl_fixedarray_object *
395
397
}
396
398
}
397
399
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
+ }
399
412
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 )
401
414
{
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 )) {
403
416
return & EG (uninitialized_zval );
404
417
}
405
418
@@ -445,7 +458,13 @@ static void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_object *
445
458
}
446
459
}
447
460
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 )
449
468
{
450
469
if (HAS_FIXEDARRAY_ARRAYACCESS_OVERRIDE (object , zf_offsetset )) {
451
470
zval tmp ;
@@ -458,8 +477,7 @@ static void spl_fixedarray_object_write_dimension(zend_object *object, zval *off
458
477
return ;
459
478
}
460
479
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 );
463
481
}
464
482
465
483
static 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 *
478
496
}
479
497
}
480
498
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 )
482
506
{
483
507
if (UNEXPECTED (HAS_FIXEDARRAY_ARRAYACCESS_OVERRIDE (object , zf_offsetunset ))) {
484
508
zend_call_known_instance_method_with_1_params (object -> ce -> arrayaccess_funcs_ptr -> zf_offsetunset , object , NULL , offset );
485
509
return ;
486
510
}
487
511
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 );
490
513
}
491
514
492
515
static 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
507
530
return Z_TYPE (intern -> array .elements [index ]) != IS_NULL ;
508
531
}
509
532
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 )
511
540
{
512
541
if (HAS_FIXEDARRAY_ARRAYACCESS_OVERRIDE (object , zf_offsetexists )) {
513
542
zval rv ;
@@ -518,9 +547,7 @@ static int spl_fixedarray_object_has_dimension(zend_object *object, zval *offset
518
547
return result ;
519
548
}
520
549
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 );
524
551
}
525
552
526
553
static zend_result spl_fixedarray_object_count_elements (zend_object * object , zend_long * count )
@@ -973,21 +1000,28 @@ PHP_MINIT_FUNCTION(spl_fixedarray)
973
1000
spl_ce_SplFixedArray = register_class_SplFixedArray (
974
1001
zend_ce_aggregate , zend_ce_arrayaccess , zend_ce_countable , php_json_serializable_ce );
975
1002
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 ;
977
1004
spl_ce_SplFixedArray -> get_iterator = spl_fixedarray_get_iterator ;
978
1005
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 ;
991
1025
992
1026
return SUCCESS ;
993
1027
}
0 commit comments