Skip to content

Commit b868751

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

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;
@@ -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

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

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

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

Comments
 (0)