Commit 049f7e8dd06 for php.net

commit 049f7e8dd06840b6ec9aedbf2abe60d985c51677
Author: Gina Peter Banyard <girgias@php.net>
Date:   Fri Jul 31 17:43:31 2026 +0100

    spl: use zend_call_known_function() when possible (#22972)

    As we don't need to do function cache shenanigans on those calls.

diff --git a/ext/spl/spl_array.c b/ext/spl/spl_array.c
index 1976192e7b0..af603f3abf6 100644
--- a/ext/spl/spl_array.c
+++ b/ext/spl/spl_array.c
@@ -426,7 +426,7 @@ static zval *spl_array_read_dimension_ex(int check_inherited, zend_object *objec
 				ZVAL_UNDEF(&tmp);
 				offset = &tmp;
 			}
-			zend_call_method_with_1_params(object, object->ce, &intern->fptr_offset_get, "offsetGet", rv, offset);
+			zend_call_known_function(intern->fptr_offset_get, object, object->ce, rv, 1, offset, NULL);

 			if (!Z_ISUNDEF_P(rv)) {
 				return rv;
@@ -520,7 +520,7 @@ static void spl_array_unset_dimension_ex(int check_inherited, zend_object *objec
 	spl_hash_key key;

 	if (check_inherited && intern->fptr_offset_del) {
-		zend_call_method_with_1_params(object, object->ce, &intern->fptr_offset_del, "offsetUnset", NULL, offset);
+		zend_call_known_function(intern->fptr_offset_del, object, object->ce, NULL, 1, offset, NULL);
 		return;
 	}

@@ -575,7 +575,7 @@ static bool spl_array_has_dimension_ex(bool check_inherited, zend_object *object
 	zval rv, *value = NULL, *tmp;

 	if (check_inherited && intern->fptr_offset_has) {
-		zend_call_method_with_1_params(object, object->ce, &intern->fptr_offset_has, "offsetExists", &rv, offset);
+		zend_call_known_function(intern->fptr_offset_has, object, object->ce, &rv, 1, offset, NULL);

 		if (!zend_is_true(&rv)) {
 			zval_ptr_dtor(&rv);
@@ -1130,7 +1130,7 @@ static zend_result spl_array_object_count_elements(zend_object *object, zend_lon

 	if (intern->fptr_count) {
 		zval rv;
-		zend_call_method_with_0_params(object, intern->std.ce, &intern->fptr_count, "count", &rv);
+		zend_call_known_function(intern->fptr_count, object, object->ce, &rv, 0, NULL, NULL);
 		if (Z_TYPE(rv) != IS_UNDEF) {
 			*count = zval_get_long(&rv);
 			zval_ptr_dtor(&rv);
@@ -1811,18 +1811,11 @@ PHP_METHOD(RecursiveArrayIterator, hasChildren)
 }
 /* }}} */

-static void spl_instantiate_child_arg(zend_class_entry *pce, zval *retval, zval *arg1, zval *arg2) /* {{{ */
-{
-	object_init_ex(retval, pce);
-	zend_call_known_instance_method_with_2_params(pce->constructor, Z_OBJ_P(retval), NULL, arg1, arg2);
-}
-/* }}} */
-
 /* {{{ Create a sub iterator for the current element (same class as $this) */
 PHP_METHOD(RecursiveArrayIterator, getChildren)
 {
-	zval *object = ZEND_THIS, *entry, flags;
-	spl_array_object *intern = Z_SPLARRAY_P(object);
+	zval *entry;
+	spl_array_object *intern = Z_SPLARRAY_P(ZEND_THIS);
 	HashTable *aht = spl_array_get_hash_table(intern);

 	ZEND_PARSE_PARAMETERS_NONE();
@@ -1845,8 +1838,10 @@ PHP_METHOD(RecursiveArrayIterator, getChildren)
 		}
 	}

-	ZVAL_LONG(&flags, intern->ar_flags);
-	spl_instantiate_child_arg(Z_OBJCE_P(ZEND_THIS), return_value, entry, &flags);
+	zval params[2];
+	ZVAL_COPY_VALUE(&params[0], entry);
+	ZVAL_LONG(&params[1], intern->ar_flags);
+	object_init_with_constructor(return_value, Z_OBJCE_P(ZEND_THIS), 2, params, NULL);
 }
 /* }}} */

diff --git a/ext/spl/spl_directory.c b/ext/spl/spl_directory.c
index ccab32aec78..daad1a4908f 100644
--- a/ext/spl/spl_directory.c
+++ b/ext/spl/spl_directory.c
@@ -480,7 +480,7 @@ static spl_filesystem_object *spl_filesystem_object_create_info(zend_string *fil

 	if (ce->constructor->common.scope != spl_ce_SplFileInfo) {
 		ZVAL_STR(&arg1, file_path);
-		zend_call_method_with_1_params(Z_OBJ_P(return_value), ce, &ce->constructor, "__construct", NULL, &arg1);
+		zend_call_known_function(ce->constructor, Z_OBJ_P(return_value), ce, NULL, 1, &arg1, NULL);
 	} else {
 		spl_filesystem_info_set_filename(intern, file_path);
 	}
@@ -519,7 +519,7 @@ static spl_filesystem_object *spl_filesystem_object_create_type(int num_args, sp

 			if (ce->constructor->common.scope != spl_ce_SplFileInfo) {
 				ZVAL_STR(&arg1, source->file_name);
-				zend_call_method_with_1_params(Z_OBJ_P(return_value), ce, &ce->constructor, "__construct", NULL, &arg1);
+				zend_call_known_function(ce->constructor, Z_OBJ_P(return_value), ce, NULL, 1, &arg1, NULL);
 			} else {
 				intern->file_name = zend_string_copy(source->file_name);
 				intern->path = spl_filesystem_object_get_path(source);
diff --git a/ext/spl/spl_dllist.c b/ext/spl/spl_dllist.c
index 77e8b0d4e7d..2ef5d7a07db 100644
--- a/ext/spl/spl_dllist.c
+++ b/ext/spl/spl_dllist.c
@@ -382,7 +382,7 @@ static zend_result spl_dllist_object_count_elements(zend_object *object, zend_lo

 	if (intern->fptr_count) {
 		zval rv;
-		zend_call_method_with_0_params(object, intern->std.ce, &intern->fptr_count, "count", &rv);
+		zend_call_known_function(intern->fptr_count, object, intern->std.ce, &rv, 0, NULL, NULL);
 		if (!Z_ISUNDEF(rv)) {
 			*count = zval_get_long(&rv);
 			zval_ptr_dtor(&rv);
diff --git a/ext/spl/spl_heap.c b/ext/spl/spl_heap.c
index 1073836aa53..5a6cc33cf86 100644
--- a/ext/spl/spl_heap.c
+++ b/ext/spl/spl_heap.c
@@ -490,7 +490,7 @@ static zend_result spl_heap_object_count_elements(zend_object *object, zend_long

 	if (intern->fptr_count) {
 		zval rv;
-		zend_call_method_with_0_params(object, intern->std.ce, &intern->fptr_count, "count", &rv);
+		zend_call_known_function(intern->fptr_count, object, intern->std.ce, &rv, 0, NULL, NULL);
 		if (!Z_ISUNDEF(rv)) {
 			*count = zval_get_long(&rv);
 			zval_ptr_dtor(&rv);
diff --git a/ext/spl/spl_iterators.c b/ext/spl/spl_iterators.c
index 95fe2d7c0b5..06d344990df 100644
--- a/ext/spl/spl_iterators.c
+++ b/ext/spl/spl_iterators.c
@@ -213,7 +213,7 @@ static zend_result spl_recursive_it_valid_ex(spl_recursive_it_object *object, zv
 		level--;
 	}
 	if (object->endIteration && object->in_iteration) {
-		zend_call_method_with_0_params(Z_OBJ_P(zthis), object->ce, &object->endIteration, "endIteration", NULL);
+		zend_call_known_function(object->endIteration, Z_OBJ_P(zthis), object->ce, NULL, 0, NULL, NULL);
 	}
 	object->in_iteration = false;
 	return FAILURE;
@@ -292,7 +292,7 @@ static void spl_recursive_it_move_forward_ex(spl_recursive_it_object *object, zv
 				ZEND_FALLTHROUGH;
 			case RS_TEST:
 				if (object->callHasChildren) {
-					zend_call_method_with_0_params(Z_OBJ_P(zthis), object->ce, &object->callHasChildren, "callHasChildren", &retval);
+					zend_call_known_function(object->callHasChildren, Z_OBJ_P(zthis), object->ce, &retval, 0, NULL, NULL);
 				} else {
 					zend_class_entry *ce = object->iterators[object->level].ce;
 					zend_object *obj = Z_OBJ(object->iterators[object->level].zobject);
@@ -333,7 +333,7 @@ static void spl_recursive_it_move_forward_ex(spl_recursive_it_object *object, zv
 					}
 				}
 				if (object->nextElement) {
-					zend_call_method_with_0_params(Z_OBJ_P(zthis), object->ce, &object->nextElement, "nextelement", NULL);
+					zend_call_known_function(object->nextElement, Z_OBJ_P(zthis), object->ce, NULL, 0, NULL, NULL);
 				}
 				object->iterators[object->level].state = RS_NEXT;
 				if (EG(exception)) {
@@ -346,7 +346,7 @@ static void spl_recursive_it_move_forward_ex(spl_recursive_it_object *object, zv
 				return /* self */;
 			case RS_SELF:
 				if (object->nextElement && (object->mode == RIT_SELF_FIRST || object->mode == RIT_CHILD_FIRST)) {
-					zend_call_method_with_0_params(Z_OBJ_P(zthis), object->ce, &object->nextElement, "nextelement", NULL);
+					zend_call_known_function(object->nextElement, Z_OBJ_P(zthis), object->ce, NULL, 0, NULL, NULL);
 				}
 				if (object->mode == RIT_SELF_FIRST) {
 					object->iterators[object->level].state = RS_CHILD;
@@ -356,7 +356,7 @@ static void spl_recursive_it_move_forward_ex(spl_recursive_it_object *object, zv
 				return /* self */;
 			case RS_CHILD:
 				if (object->callGetChildren) {
-					zend_call_method_with_0_params(Z_OBJ_P(zthis), object->ce, &object->callGetChildren, "callGetChildren", &child);
+					zend_call_known_function(object->callGetChildren, Z_OBJ_P(zthis), object->ce, &child, 0, NULL, NULL);
 				} else {
 					zend_class_entry *ce = object->iterators[object->level].ce;
 					zend_object *obj = Z_OBJ(object->iterators[object->level].zobject);
@@ -408,7 +408,7 @@ static void spl_recursive_it_move_forward_ex(spl_recursive_it_object *object, zv
 					sub_iter->funcs->rewind(sub_iter);
 				}
 				if (object->beginChildren) {
-					zend_call_method_with_0_params(Z_OBJ_P(zthis), object->ce, &object->beginChildren, "beginchildren", NULL);
+					zend_call_known_function(object->beginChildren, Z_OBJ_P(zthis), object->ce, NULL, 0, NULL, NULL);
 					if (EG(exception)) {
 						if (!(object->flags & RIT_CATCH_GET_CHILD)) {
 							return;
@@ -422,7 +422,7 @@ static void spl_recursive_it_move_forward_ex(spl_recursive_it_object *object, zv
 		/* no more elements */
 		if (object->level > 0) {
 			if (object->endChildren) {
-				zend_call_method_with_0_params(Z_OBJ_P(zthis), object->ce, &object->endChildren, "endchildren", NULL);
+				zend_call_known_function(object->endChildren, Z_OBJ_P(zthis), object->ce, NULL, 0, NULL, NULL);
 				if (EG(exception)) {
 					if (!(object->flags & RIT_CATCH_GET_CHILD)) {
 						return;
@@ -466,7 +466,7 @@ static void spl_recursive_it_rewind_ex(spl_recursive_it_object *object, zval *zt
 		sub_iter->funcs->rewind(sub_iter);
 	}
 	if (!EG(exception) && object->beginIteration && !object->in_iteration) {
-		zend_call_method_with_0_params(Z_OBJ_P(zthis), object->ce, &object->beginIteration, "beginIteration", NULL);
+		zend_call_known_function(object->beginIteration, Z_OBJ_P(zthis), object->ce, NULL, 0, NULL, NULL);
 	}
 	object->in_iteration = true;
 	spl_recursive_it_move_forward_ex(object, zthis);
@@ -2824,8 +2824,7 @@ PHP_METHOD(AppendIterator, __construct)
 	}

 	intern->dit_type = DIT_AppendIterator;
-	object_init_ex(&intern->u.append.zarrayit, spl_ce_ArrayIterator);
-	zend_call_method_with_0_params(Z_OBJ(intern->u.append.zarrayit), spl_ce_ArrayIterator, &spl_ce_ArrayIterator->constructor, "__construct", NULL);
+	object_init_with_constructor(&intern->u.append.zarrayit, spl_ce_ArrayIterator, 0, NULL, NULL);
 	intern->u.append.iterator = spl_ce_ArrayIterator->get_iterator(spl_ce_ArrayIterator, &intern->u.append.zarrayit, 0);

 } /* }}} */
diff --git a/ext/spl/spl_observer.c b/ext/spl/spl_observer.c
index 613bf5384dc..adfc172af98 100644
--- a/ext/spl/spl_observer.c
+++ b/ext/spl/spl_observer.c
@@ -99,7 +99,7 @@ static zend_result spl_object_storage_get_hash(zend_hash_key *key, spl_SplObject
 		ZVAL_OBJ(&param, obj);
 		ZVAL_UNDEF(&rv);
 		spl_object_storage_get_hash_depth++;
-		zend_call_method_with_1_params(&intern->std, intern->std.ce, &intern->fptr_get_hash, "getHash", &rv, &param);
+		zend_call_known_function(intern->fptr_get_hash, &intern->std, intern->std.ce, &rv, 1, &param, NULL);
 		spl_object_storage_get_hash_depth--;
 		if (UNEXPECTED(Z_ISUNDEF(rv))) {
 			/* An exception has occurred */