Created
February 18, 2019 12:33
-
-
Save dstogov/db4d092eff324167c36394bdc26ac5b9 to your computer and use it in GitHub Desktop.
This file contains bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
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..c86aee1082 100644 | |
--- a/Zend/zend_interfaces.c | |
+++ b/Zend/zend_interfaces.c | |
@@ -381,7 +381,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); | |
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment