Skip to content

Commit 53b0823

Browse files
committed
Separate out proxied handlers
This avoids checks if we know upfront that the instances are not inherited.
1 parent e483cbc commit 53b0823

File tree

1 file changed

+63
-29
lines changed

1 file changed

+63
-29
lines changed

Diff for: ext/spl/spl_fixedarray.c

+63-29
Original file line numberDiff line numberDiff line change
@@ -29,12 +29,12 @@
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;
3333
PHPAPI 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

3939
typedef 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

465483
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 *
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

492515
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
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

526553
static 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

Comments
 (0)