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 ;
@@ -290,6 +290,8 @@ static zend_object *spl_fixedarray_object_new_ex(zend_class_entry *class_type, z
290
290
}
291
291
292
292
if (UNEXPECTED (class_type != spl_ce_SplFixedArray )) {
293
+ intern -> std .handlers = & spl_handler_SplFixedArray_proxied ;
294
+
293
295
/* Find count() method */
294
296
zend_function * fptr_count = zend_hash_find_ptr (& class_type -> function_table , ZSTR_KNOWN (ZEND_STR_COUNT ));
295
297
if (fptr_count -> common .scope == spl_ce_SplFixedArray ) {
@@ -383,11 +385,22 @@ static zval *spl_fixedarray_object_read_dimension_helper(spl_fixedarray_object *
383
385
}
384
386
}
385
387
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
+ }
387
400
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 )
389
402
{
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 )) {
391
404
return & EG (uninitialized_zval );
392
405
}
393
406
@@ -433,7 +446,13 @@ static void spl_fixedarray_object_write_dimension_helper(spl_fixedarray_object *
433
446
}
434
447
}
435
448
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 )
437
456
{
438
457
if (HAS_FIXEDARRAY_ARRAYACCESS_OVERRIDE (object , zf_offsetset )) {
439
458
zval tmp ;
@@ -446,8 +465,7 @@ static void spl_fixedarray_object_write_dimension(zend_object *object, zval *off
446
465
return ;
447
466
}
448
467
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 );
451
469
}
452
470
453
471
static 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 *
466
484
}
467
485
}
468
486
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 )
470
494
{
471
495
if (UNEXPECTED (HAS_FIXEDARRAY_ARRAYACCESS_OVERRIDE (object , zf_offsetunset ))) {
472
496
zend_call_known_instance_method_with_1_params (object -> ce -> arrayaccess_funcs_ptr -> zf_offsetunset , object , NULL , offset );
473
497
return ;
474
498
}
475
499
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 );
478
501
}
479
502
480
503
static 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
495
518
return Z_TYPE (intern -> array .elements [index ]) != IS_NULL ;
496
519
}
497
520
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 )
499
528
{
500
529
if (HAS_FIXEDARRAY_ARRAYACCESS_OVERRIDE (object , zf_offsetexists )) {
501
530
zval rv ;
@@ -506,9 +535,7 @@ static int spl_fixedarray_object_has_dimension(zend_object *object, zval *offset
506
535
return result ;
507
536
}
508
537
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 );
512
539
}
513
540
514
541
static zend_result spl_fixedarray_object_count_elements (zend_object * object , zend_long * count )
@@ -961,21 +988,28 @@ PHP_MINIT_FUNCTION(spl_fixedarray)
961
988
spl_ce_SplFixedArray = register_class_SplFixedArray (
962
989
zend_ce_aggregate , zend_ce_arrayaccess , zend_ce_countable , php_json_serializable_ce );
963
990
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 ;
965
992
spl_ce_SplFixedArray -> get_iterator = spl_fixedarray_get_iterator ;
966
993
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 ;
979
1013
980
1014
return SUCCESS ;
981
1015
}
0 commit comments