[php-src] master: Make strtolower()/strtoupper() frameless

Ondrej Mirtes via Ilija Tovilo <[email protected]>
Newsgroups gmane.comp.php.cvs.general
Message-ID <[email protected]>
Author: Ondrej Mirtes (ondrejmirtes)
Committer: Ilija Tovilo (iluuu1994)
Date: 2026-08-12T15:56:24+02:00

Commit: https://github.com/php/php-src/commit/89a17252a495202895a219ff93c1a08d3acee863
Raw diff: https://github.com/php/php-src/commit/89a17252a495202895a219ff93c1a08d3acee863.diff

Make strtolower()/strtoupper() frameless

Both are single-argument wrappers around zend_string_tolower/upper;
static analyzers and general string handling call them at very high
frequency. The frameless call convention removes the call frame setup
and argument copying.

Co-authored-by: Markus Staab <[email protected]>
Closes GH-23084

Changed paths:
  M  ext/standard/basic_functions.stub.php
  M  ext/standard/basic_functions_arginfo.h
  M  ext/standard/basic_functions_decl.h
  M  ext/standard/string.c


Diff:

diff --git a/ext/standard/basic_functions.stub.php b/ext/standard/basic_functions.stub.php
index 9f52df10e1d3..c87e22433400 100644
--- a/ext/standard/basic_functions.stub.php
+++ b/ext/standard/basic_functions.stub.php
@@ -2368,10 +2368,16 @@ function join(string|array $separator, ?array $array = null): string {}
  */
 function strtok(string $string, ?string $token = null): string|false {}
 
-/** @compile-time-eval */
+/**
+ * @compile-time-eval
+ * @frameless-function {"arity": 1}
+ */
 function strtoupper(string $string): string {}
 
-/** @compile-time-eval */
+/**
+ * @compile-time-eval
+ * @frameless-function {"arity": 1}
+ */
 function strtolower(string $string): string {}
 
 function str_increment(string $string): string {}
diff --git a/ext/standard/basic_functions_arginfo.h b/ext/standard/basic_functions_arginfo.h
index 0155187f1616..ab8c57d4e8d9 100644
--- a/ext/standard/basic_functions_arginfo.h
+++ b/ext/standard/basic_functions_arginfo.h
@@ -1,5 +1,5 @@
 /* This is a generated file, edit basic_functions.stub.php instead.
- * Stub hash: 8f5682d85611126ee12182af46cb2905a0bd0e57
+ * Stub hash: cf2ea35cd867f7091ee1fcf83bbfb543b51e5786
  * Has decl header: yes */
 
 ZEND_BEGIN_ARG_WITH_RETURN_TYPE_INFO_EX(arginfo_set_time_limit, 0, 1, _IS_BOOL, 0)
@@ -2246,6 +2246,18 @@ static const zend_frameless_function_info frameless_function_infos_implode[] = {
 	{ 0 },
 };
 
+ZEND_FRAMELESS_FUNCTION(strtoupper, 1);
+static const zend_frameless_function_info frameless_function_infos_strtoupper[] = {
+	{ ZEND_FRAMELESS_FUNCTION_NAME(strtoupper, 1), 1 },
+	{ 0 },
+};
+
+ZEND_FRAMELESS_FUNCTION(strtolower, 1);
+static const zend_frameless_function_info frameless_function_infos_strtolower[] = {
+	{ ZEND_FRAMELESS_FUNCTION_NAME(strtolower, 1), 1 },
+	{ 0 },
+};
+
 ZEND_FRAMELESS_FUNCTION(dirname, 1);
 ZEND_FRAMELESS_FUNCTION(dirname, 2);
 static const zend_frameless_function_info frameless_function_infos_dirname[] = {
@@ -3168,8 +3180,8 @@ static const zend_function_entry ext_functions[] = {
 	ZEND_RAW_FENTRY("implode", zif_implode, arginfo_implode, ZEND_ACC_COMPILE_TIME_EVAL, frameless_function_infos_implode, NULL)
 	ZEND_RAW_FENTRY("join", zif_implode, arginfo_join, 0, NULL, NULL)
 	ZEND_FE(strtok, arginfo_strtok)
-	ZEND_RAW_FENTRY("strtoupper", zif_strtoupper, arginfo_strtoupper, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL)
-	ZEND_RAW_FENTRY("strtolower", zif_strtolower, arginfo_strtolower, ZEND_ACC_COMPILE_TIME_EVAL, NULL, NULL)
+	ZEND_RAW_FENTRY("strtoupper", zif_strtoupper, arginfo_strtoupper, ZEND_ACC_COMPILE_TIME_EVAL, frameless_function_infos_strtoupper, NULL)
+	ZEND_RAW_FENTRY("strtolower", zif_strtolower, arginfo_strtolower, ZEND_ACC_COMPILE_TIME_EVAL, frameless_function_infos_strtolower, NULL)
 	ZEND_FE(str_increment, arginfo_str_increment)
 	ZEND_FE(str_decrement, arginfo_str_decrement)
 	ZEND_FE(basename, arginfo_basename)
diff --git a/ext/standard/basic_functions_decl.h b/ext/standard/basic_functions_decl.h
index 40e4c918ba60..02203be0df41 100644
--- a/ext/standard/basic_functions_decl.h
+++ b/ext/standard/basic_functions_decl.h
@@ -1,8 +1,8 @@
 /* This is a generated file, edit basic_functions.stub.php instead.
- * Stub hash: 8f5682d85611126ee12182af46cb2905a0bd0e57 */
+ * Stub hash: cf2ea35cd867f7091ee1fcf83bbfb543b51e5786 */
 
-#ifndef ZEND_BASIC_FUNCTIONS_DECL_8f5682d85611126ee12182af46cb2905a0bd0e57_H
-#define ZEND_BASIC_FUNCTIONS_DECL_8f5682d85611126ee12182af46cb2905a0bd0e57_H
+#ifndef ZEND_BASIC_FUNCTIONS_DECL_cf2ea35cd867f7091ee1fcf83bbfb543b51e5786_H
+#define ZEND_BASIC_FUNCTIONS_DECL_cf2ea35cd867f7091ee1fcf83bbfb543b51e5786_H
 
 typedef enum zend_enum_SortDirection {
 	ZEND_ENUM_SortDirection_Ascending = 1,
@@ -20,4 +20,4 @@ typedef enum zend_enum_RoundingMode {
 	ZEND_ENUM_RoundingMode_PositiveInfinity = 8,
 } zend_enum_RoundingMode;
 
-#endif /* ZEND_BASIC_FUNCTIONS_DECL_8f5682d85611126ee12182af46cb2905a0bd0e57_H */
+#endif /* ZEND_BASIC_FUNCTIONS_DECL_cf2ea35cd867f7091ee1fcf83bbfb543b51e5786_H */
diff --git a/ext/standard/string.c b/ext/standard/string.c
index 91c930515b78..e5307a4f2d4b 100644
--- a/ext/standard/string.c
+++ b/ext/standard/string.c
@@ -1192,6 +1192,19 @@ PHP_FUNCTION(strtoupper)
 }
 /* }}} */
 
+ZEND_FRAMELESS_FUNCTION(strtoupper, 1)
+{
+	zval str_tmp;
+	zend_string *str;
+
+	Z_FLF_PARAM_STR(1, str, str_tmp);
+
+	RETVAL_STR(zend_string_toupper(str));
+
+flf_clean:
+	Z_FLF_PARAM_FREE_STR(1, str_tmp);
+}
+
 /* {{{ Makes a string lowercase */
 PHP_FUNCTION(strtolower)
 {
@@ -1205,6 +1218,19 @@ PHP_FUNCTION(strtolower)
 }
 /* }}} */
 
+ZEND_FRAMELESS_FUNCTION(strtolower, 1)
+{
+	zval str_tmp;
+	zend_string *str;
+
+	Z_FLF_PARAM_STR(1, str, str_tmp);
+
+	RETVAL_STR(zend_string_tolower(str));
+
+flf_clean:
+	Z_FLF_PARAM_FREE_STR(1, str_tmp);
+}
+
 PHP_FUNCTION(str_increment)
 {
 	zend_string *str;
lmpx.com only provides a reader for public news (NNTP) servers. It is not affiliated with the servers or forums shown here and is not responsible for the content of articles, which is written by their respective authors.