summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Zend/zend_compile.h3
-rw-r--r--Zend/zend_interfaces.c16
-rw-r--r--ext/spl/spl_array.c4
3 files changed, 20 insertions, 3 deletions
diff --git a/Zend/zend_compile.h b/Zend/zend_compile.h
index a80838666b..dfb04ab732 100644
--- a/Zend/zend_compile.h
+++ b/Zend/zend_compile.h
@@ -263,6 +263,9 @@ typedef struct _zend_oparray_context {
/* Whether all property types are resolved to CEs | | | */
#define ZEND_ACC_PROPERTY_TYPES_RESOLVED (1 << 16) /* X | | | */
/* | | | */
+/* Children must reuse parent get_iterator() | | | */
+#define ZEND_ACC_REUSE_GET_ITERATOR (1 << 17) /* X | | | */
+/* | | | */
/* Function Flags (unused: 28...30) | | | */
/* ============== | | | */
/* | | | */
diff --git a/Zend/zend_interfaces.c b/Zend/zend_interfaces.c
index e5b6251d17..fe4c9ed9a3 100644
--- a/Zend/zend_interfaces.c
+++ b/Zend/zend_interfaces.c
@@ -340,7 +340,13 @@ static int zend_implement_aggregate(zend_class_entry *interface, zend_class_entr
}
}
}
- class_type->get_iterator = zend_user_it_get_new_iterator;
+ if (class_type->parent
+ && (class_type->parent->ce_flags & ZEND_ACC_REUSE_GET_ITERATOR)) {
+ class_type->get_iterator = class_type->parent->get_iterator;
+ class_type->ce_flags |= ZEND_ACC_REUSE_GET_ITERATOR;
+ } else {
+ class_type->get_iterator = zend_user_it_get_new_iterator;
+ }
funcs_ptr = class_type->iterator_funcs_ptr;
if (class_type->type == ZEND_INTERNAL_CLASS) {
if (!funcs_ptr) {
@@ -381,7 +387,13 @@ static int zend_implement_iterator(zend_class_entry *interface, zend_class_entry
return FAILURE;
}
}
- class_type->get_iterator = zend_user_it_get_iterator;
+ if (class_type->parent
+ && (class_type->parent->ce_flags & ZEND_ACC_REUSE_GET_ITERATOR)) {
+ class_type->get_iterator = class_type->parent->get_iterator;
+ class_type->ce_flags |= ZEND_ACC_REUSE_GET_ITERATOR;
+ } else {
+ class_type->get_iterator = zend_user_it_get_iterator;
+ }
funcs_ptr = class_type->iterator_funcs_ptr;
if (class_type->type == ZEND_INTERNAL_CLASS) {
if (!funcs_ptr) {
diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
index 1198885505..ab488726df 100644
--- a/ext/spl/spl_array.c
+++ b/ext/spl/spl_array.c
@@ -206,7 +206,6 @@ static zend_object *spl_array_object_new_ex(zend_class_entry *class_type, zval *
while (parent) {
if (parent == spl_ce_ArrayIterator || parent == spl_ce_RecursiveArrayIterator) {
intern->std.handlers = &spl_handler_ArrayIterator;
- class_type->get_iterator = spl_array_get_iterator;
break;
} else if (parent == spl_ce_ArrayObject) {
intern->std.handlers = &spl_handler_ArrayObject;
@@ -1969,6 +1968,8 @@ PHP_MINIT_FUNCTION(spl_array)
REGISTER_SPL_IMPLEMENTS(ArrayIterator, Countable);
memcpy(&spl_handler_ArrayIterator, &spl_handler_ArrayObject, sizeof(zend_object_handlers));
spl_ce_ArrayIterator->get_iterator = spl_array_get_iterator;
+ spl_ce_ArrayIterator->ce_flags |= ZEND_ACC_REUSE_GET_ITERATOR;
+
REGISTER_SPL_CLASS_CONST_LONG(ArrayObject, "STD_PROP_LIST", SPL_ARRAY_STD_PROP_LIST);
REGISTER_SPL_CLASS_CONST_LONG(ArrayObject, "ARRAY_AS_PROPS", SPL_ARRAY_ARRAY_AS_PROPS);
@@ -1979,6 +1980,7 @@ PHP_MINIT_FUNCTION(spl_array)
REGISTER_SPL_SUB_CLASS_EX(RecursiveArrayIterator, ArrayIterator, spl_array_object_new, spl_funcs_RecursiveArrayIterator);
REGISTER_SPL_IMPLEMENTS(RecursiveArrayIterator, RecursiveIterator);
spl_ce_RecursiveArrayIterator->get_iterator = spl_array_get_iterator;
+ spl_ce_RecursiveArrayIterator->ce_flags |= ZEND_ACC_REUSE_GET_ITERATOR;
REGISTER_SPL_CLASS_CONST_LONG(RecursiveArrayIterator, "CHILD_ARRAYS_ONLY", SPL_ARRAY_CHILD_ARRAYS_ONLY);