Skip to content

Commit d0dbf72

Browse files
committed
Initialize iterator_funcs_ptr upfront
Same as we do for the IteratorAggregate case, initialize the Iterator methods upfront. This is preparation for an upcoming change to automatically determine whether get_iterator can be reused in a child class, in the same way we already do for IteratorAggregate.
1 parent 51cf97d commit d0dbf72

File tree

3 files changed

+29
-21
lines changed

3 files changed

+29
-21
lines changed

Zend/zend_interfaces.c

Lines changed: 23 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -124,10 +124,9 @@ ZEND_API int zend_user_it_valid(zend_object_iterator *_iter)
124124
zend_user_iterator *iter = (zend_user_iterator*)_iter;
125125
zval *object = &iter->it.data;
126126
zval more;
127-
bool result;
128127

129-
zend_call_method_with_0_params(Z_OBJ_P(object), iter->ce, &iter->ce->iterator_funcs_ptr->zf_valid, "valid", &more);
130-
result = i_zend_is_true(&more);
128+
zend_call_known_instance_method_with_0_params(iter->ce->iterator_funcs_ptr->zf_valid, Z_OBJ_P(object), &more);
129+
bool result = i_zend_is_true(&more);
131130
zval_ptr_dtor(&more);
132131
return result ? SUCCESS : FAILURE;
133132
}
@@ -142,7 +141,7 @@ ZEND_API zval *zend_user_it_get_current_data(zend_object_iterator *_iter)
142141
zval *object = &iter->it.data;
143142

144143
if (Z_ISUNDEF(iter->value)) {
145-
zend_call_method_with_0_params(Z_OBJ_P(object), iter->ce, &iter->ce->iterator_funcs_ptr->zf_current, "current", &iter->value);
144+
zend_call_known_instance_method_with_0_params(iter->ce->iterator_funcs_ptr->zf_current, Z_OBJ_P(object), &iter->value);
146145
}
147146
return &iter->value;
148147
}
@@ -153,7 +152,7 @@ ZEND_API void zend_user_it_get_current_key(zend_object_iterator *_iter, zval *ke
153152
{
154153
zend_user_iterator *iter = (zend_user_iterator*)_iter;
155154
zval *object = &iter->it.data;
156-
zend_call_method_with_0_params(Z_OBJ_P(object), iter->ce, &iter->ce->iterator_funcs_ptr->zf_key, "key", key);
155+
zend_call_known_instance_method_with_0_params(iter->ce->iterator_funcs_ptr->zf_key, Z_OBJ_P(object), key);
157156
if (UNEXPECTED(Z_ISREF_P(key))) {
158157
zend_unwrap_reference(key);
159158
}
@@ -167,7 +166,7 @@ ZEND_API void zend_user_it_move_forward(zend_object_iterator *_iter)
167166
zval *object = &iter->it.data;
168167

169168
zend_user_it_invalidate_current(_iter);
170-
zend_call_method_with_0_params(Z_OBJ_P(object), iter->ce, &iter->ce->iterator_funcs_ptr->zf_next, "next", NULL);
169+
zend_call_known_instance_method_with_0_params(iter->ce->iterator_funcs_ptr->zf_next, Z_OBJ_P(object), NULL);
171170
}
172171
/* }}} */
173172

@@ -178,7 +177,7 @@ ZEND_API void zend_user_it_rewind(zend_object_iterator *_iter)
178177
zval *object = &iter->it.data;
179178

180179
zend_user_it_invalidate_current(_iter);
181-
zend_call_method_with_0_params(Z_OBJ_P(object), iter->ce, &iter->ce->iterator_funcs_ptr->zf_rewind, "rewind", NULL);
180+
zend_call_known_instance_method_with_0_params(iter->ce->iterator_funcs_ptr->zf_rewind, Z_OBJ_P(object), NULL);
182181
}
183182
/* }}} */
184183

@@ -317,6 +316,16 @@ static int zend_implement_iterator(zend_class_entry *interface, zend_class_entry
317316
ZSTR_VAL(class_type->name));
318317
}
319318

319+
zend_function *zf_rewind = zend_hash_str_find_ptr(
320+
&class_type->function_table, "rewind", sizeof("rewind") - 1);
321+
zend_function *zf_valid = zend_hash_str_find_ptr(
322+
&class_type->function_table, "valid", sizeof("valid") - 1);
323+
zend_function *zf_key = zend_hash_str_find_ptr(
324+
&class_type->function_table, "key", sizeof("key") - 1);
325+
zend_function *zf_current = zend_hash_str_find_ptr(
326+
&class_type->function_table, "current", sizeof("current") - 1);
327+
zend_function *zf_next = zend_hash_str_find_ptr(
328+
&class_type->function_table, "next", sizeof("next") - 1);
320329
if (class_type->get_iterator && class_type->get_iterator != zend_user_it_get_iterator) {
321330
if (!class_type->parent || class_type->parent->get_iterator != class_type->get_iterator) {
322331
/* get_iterator was explicitly assigned for an internal class. */
@@ -337,9 +346,15 @@ static int zend_implement_iterator(zend_class_entry *interface, zend_class_entry
337346
zend_class_iterator_funcs *funcs_ptr = class_type->type == ZEND_INTERNAL_CLASS
338347
? pemalloc(sizeof(zend_class_iterator_funcs), 1)
339348
: zend_arena_alloc(&CG(arena), sizeof(zend_class_iterator_funcs));
340-
memset(funcs_ptr, 0, sizeof(zend_class_iterator_funcs));
341349
class_type->iterator_funcs_ptr = funcs_ptr;
342350

351+
memset(funcs_ptr, 0, sizeof(zend_class_iterator_funcs));
352+
funcs_ptr->zf_rewind = zf_rewind;
353+
funcs_ptr->zf_valid = zf_valid;
354+
funcs_ptr->zf_key = zf_key;
355+
funcs_ptr->zf_current = zf_current;
356+
funcs_ptr->zf_next = zf_next;
357+
343358
return SUCCESS;
344359
}
345360
/* }}} */

ext/spl/spl_array.c

Lines changed: 0 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -234,13 +234,6 @@ static zend_object *spl_array_object_new_ex(zend_class_entry *class_type, zend_o
234234
if (intern->std.handlers == &spl_handler_ArrayIterator) {
235235
zend_class_iterator_funcs *funcs_ptr = class_type->iterator_funcs_ptr;
236236

237-
if (!funcs_ptr->zf_current) {
238-
funcs_ptr->zf_rewind = zend_hash_str_find_ptr(&class_type->function_table, "rewind", sizeof("rewind") - 1);
239-
funcs_ptr->zf_valid = zend_hash_str_find_ptr(&class_type->function_table, "valid", sizeof("valid") - 1);
240-
funcs_ptr->zf_key = zend_hash_str_find_ptr(&class_type->function_table, "key", sizeof("key") - 1);
241-
funcs_ptr->zf_current = zend_hash_str_find_ptr(&class_type->function_table, "current", sizeof("current") - 1);
242-
funcs_ptr->zf_next = zend_hash_str_find_ptr(&class_type->function_table, "next", sizeof("next") - 1);
243-
}
244237
if (inherited) {
245238
if (funcs_ptr->zf_rewind->common.scope != parent) intern->ar_flags |= SPL_ARRAY_OVERLOADED_REWIND;
246239
if (funcs_ptr->zf_valid->common.scope != parent) intern->ar_flags |= SPL_ARRAY_OVERLOADED_VALID;

ext/spl/spl_observer.c

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1017,7 +1017,7 @@ PHP_METHOD(MultipleIterator, rewind)
10171017
zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
10181018
while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) {
10191019
zend_object *it = element->obj;
1020-
zend_call_method_with_0_params(it, it->ce, &it->ce->iterator_funcs_ptr->zf_rewind, "rewind", NULL);
1020+
zend_call_known_instance_method_with_0_params(it->ce->iterator_funcs_ptr->zf_rewind, it, NULL);
10211021
zend_hash_move_forward_ex(&intern->storage, &intern->pos);
10221022
}
10231023
}
@@ -1038,7 +1038,7 @@ PHP_METHOD(MultipleIterator, next)
10381038
zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
10391039
while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) {
10401040
zend_object *it = element->obj;
1041-
zend_call_method_with_0_params(it, it->ce, &it->ce->iterator_funcs_ptr->zf_next, "next", NULL);
1041+
zend_call_known_instance_method_with_0_params(it->ce->iterator_funcs_ptr->zf_next, it, NULL);
10421042
zend_hash_move_forward_ex(&intern->storage, &intern->pos);
10431043
}
10441044
}
@@ -1067,7 +1067,7 @@ PHP_METHOD(MultipleIterator, valid)
10671067
zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
10681068
while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) {
10691069
zend_object *it = element->obj;
1070-
zend_call_method_with_0_params(it, it->ce, &it->ce->iterator_funcs_ptr->zf_valid, "valid", &retval);
1070+
zend_call_known_instance_method_with_0_params(it->ce->iterator_funcs_ptr->zf_valid, it, &retval);
10711071

10721072
if (!Z_ISUNDEF(retval)) {
10731073
valid = (Z_TYPE(retval) == IS_TRUE);
@@ -1105,7 +1105,7 @@ static void spl_multiple_iterator_get_all(spl_SplObjectStorage *intern, int get_
11051105
zend_hash_internal_pointer_reset_ex(&intern->storage, &intern->pos);
11061106
while ((element = zend_hash_get_current_data_ptr_ex(&intern->storage, &intern->pos)) != NULL && !EG(exception)) {
11071107
zend_object *it = element->obj;
1108-
zend_call_method_with_0_params(it, it->ce, &it->ce->iterator_funcs_ptr->zf_valid, "valid", &retval);
1108+
zend_call_known_instance_method_with_0_params(it->ce->iterator_funcs_ptr->zf_valid, it, &retval);
11091109

11101110
if (!Z_ISUNDEF(retval)) {
11111111
valid = Z_TYPE(retval) == IS_TRUE;
@@ -1116,9 +1116,9 @@ static void spl_multiple_iterator_get_all(spl_SplObjectStorage *intern, int get_
11161116

11171117
if (valid) {
11181118
if (SPL_MULTIPLE_ITERATOR_GET_ALL_CURRENT == get_type) {
1119-
zend_call_method_with_0_params(it, it->ce, &it->ce->iterator_funcs_ptr->zf_current, "current", &retval);
1119+
zend_call_known_instance_method_with_0_params(it->ce->iterator_funcs_ptr->zf_current, it, &retval);
11201120
} else {
1121-
zend_call_method_with_0_params(it, it->ce, &it->ce->iterator_funcs_ptr->zf_key, "key", &retval);
1121+
zend_call_known_instance_method_with_0_params(it->ce->iterator_funcs_ptr->zf_key, it, &retval);
11221122
}
11231123
if (Z_ISUNDEF(retval)) {
11241124
zend_throw_exception(spl_ce_RuntimeException, "Failed to call sub iterator method", 0);

0 commit comments

Comments
 (0)