Skip to content

Commit 4cee049

Browse files
committed
ZPP: Reduce code bloat for Z_PARAM_STR
This idea is based on @nielsdos previous PR to reduce codebloat: #18436 To do so we create a specialized function to handle parameters that only accept strings and not null such that we can assign the zend_string to the destination directly.
1 parent 98e0dbc commit 4cee049

File tree

6 files changed

+50
-33
lines changed

6 files changed

+50
-33
lines changed

Zend/zend_API.c

Lines changed: 15 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -755,58 +755,58 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_or_str_slow(zval *arg, zval **
755755
return true;
756756
}
757757

758-
ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest, uint32_t arg_num) /* {{{ */
758+
ZEND_API zend_string* ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, uint32_t arg_num) /* {{{ */
759759
{
760760
if (EXPECTED(Z_TYPE_P(arg) < IS_STRING)) {
761761
if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) && !zend_null_arg_deprecated("string", arg_num)) {
762-
return 0;
762+
return NULL;
763763
}
764764
convert_to_string(arg);
765-
*dest = Z_STR_P(arg);
765+
return Z_STR_P(arg);
766766
} else if (UNEXPECTED(Z_TYPE_P(arg) == IS_OBJECT)) {
767767
zend_object *zobj = Z_OBJ_P(arg);
768768
zval obj;
769769
if (zobj->handlers->cast_object(zobj, &obj, IS_STRING) == SUCCESS) {
770770
OBJ_RELEASE(zobj);
771771
ZVAL_COPY_VALUE(arg, &obj);
772-
*dest = Z_STR_P(arg);
773-
return 1;
772+
return Z_STR_P(arg);
774773
}
775-
return 0;
774+
return NULL;
776775
} else {
777-
return 0;
776+
return NULL;
778777
}
779-
return 1;
780778
}
781779
/* }}} */
782780

783-
ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num) /* {{{ */
781+
ZEND_API zend_string* ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, uint32_t arg_num) /* {{{ */
784782
{
785783
if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
786-
return 0;
784+
return NULL;
787785
}
788-
return zend_parse_arg_str_weak(arg, dest, arg_num);
786+
return zend_parse_arg_str_weak(arg, arg_num);
789787
}
790788
/* }}} */
791789

792-
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num)
790+
ZEND_API zend_string* ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, uint32_t arg_num)
793791
{
794792
if (UNEXPECTED(ZEND_FLF_ARG_USES_STRICT_TYPES())) {
795-
return 0;
793+
return NULL;
796794
}
797-
return zend_parse_arg_str_weak(arg, dest, arg_num);
795+
return zend_parse_arg_str_weak(arg, arg_num);
798796
}
799797

800798
ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_or_long_slow(zval *arg, zend_string **dest_str, zend_long *dest_long, uint32_t arg_num) /* {{{ */
801799
{
800+
zend_string *str;
802801
if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
803802
return 0;
804803
}
805804
if (zend_parse_arg_long_weak(arg, dest_long, arg_num)) {
806805
*dest_str = NULL;
807806
return 1;
808-
} else if (zend_parse_arg_str_weak(arg, dest_str, arg_num)) {
807+
} else if ((str = zend_parse_arg_str_weak(arg, arg_num)) != NULL) {
809808
*dest_long = 0;
809+
*dest_str = str;
810810
return 1;
811811
} else {
812812
return 0;

Zend/zend_API.h

Lines changed: 29 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -2088,7 +2088,13 @@ ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string
20882088
}
20892089

20902090
#define Z_PARAM_STR(dest) \
2091-
Z_PARAM_STR_EX(dest, 0, 0)
2091+
Z_PARAM_PROLOGUE(false, false); \
2092+
dest = zend_parse_arg_str_no_null(_arg, _i); \
2093+
if (UNEXPECTED(dest == NULL)) { \
2094+
_expected_type = Z_EXPECTED_STRING; \
2095+
_error_code = ZPP_ERROR_WRONG_ARG; \
2096+
break; \
2097+
}
20922098

20932099
#define Z_PARAM_STR_OR_NULL(dest) \
20942100
Z_PARAM_STR_EX(dest, 1, 0)
@@ -2183,14 +2189,14 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_slow(const zval *arg, zend_long
21832189
ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(const zval *arg, zend_long *dest, uint32_t arg_num);
21842190
ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_slow(const zval *arg, double *dest, uint32_t arg_num);
21852191
ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, double *dest, uint32_t arg_num);
2186-
ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num);
2187-
ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest, uint32_t arg_num);
2192+
ZEND_API zend_string* ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, uint32_t arg_num);
2193+
ZEND_API zend_string* ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, uint32_t arg_num);
21882194
ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_slow(zval *arg, zval **dest, uint32_t arg_num);
21892195
ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_or_str_slow(zval *arg, zval **dest, uint32_t arg_num);
21902196
ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_or_long_slow(zval *arg, zend_string **dest_str, zend_long *dest_long, uint32_t arg_num);
21912197

21922198
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num);
2193-
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num);
2199+
ZEND_API zend_string* ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, uint32_t arg_num);
21942200
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_long_slow(const zval *arg, zend_long *dest, uint32_t arg_num);
21952201

21962202
static zend_always_inline bool zend_parse_arg_bool_ex(const zval *arg, bool *dest, bool *is_null, bool check_null, uint32_t arg_num, bool frameless)
@@ -2292,10 +2298,16 @@ static zend_always_inline bool zend_parse_arg_str_ex(zval *arg, zend_string **de
22922298
} else if (check_null && Z_TYPE_P(arg) == IS_NULL) {
22932299
*dest = NULL;
22942300
} else {
2301+
zend_string *str;
22952302
if (frameless) {
2296-
return zend_flf_parse_arg_str_slow(arg, dest, arg_num);
2303+
str = zend_flf_parse_arg_str_slow(arg, arg_num);
22972304
} else {
2298-
return zend_parse_arg_str_slow(arg, dest, arg_num);
2305+
str = zend_parse_arg_str_slow(arg, arg_num);
2306+
}
2307+
if (str) {
2308+
*dest = str;
2309+
} else {
2310+
return 0;
22992311
}
23002312
}
23012313
return 1;
@@ -2306,6 +2318,15 @@ static zend_always_inline bool zend_parse_arg_str(zval *arg, zend_string **dest,
23062318
return zend_parse_arg_str_ex(arg, dest, check_null, arg_num, /* frameless */ false);
23072319
}
23082320

2321+
static zend_always_inline zend_string *zend_parse_arg_str_no_null(zval *arg, uint32_t arg_num)
2322+
{
2323+
if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
2324+
return Z_STR_P(arg);
2325+
} else {
2326+
return zend_parse_arg_str_slow(arg, arg_num);
2327+
}
2328+
}
2329+
23092330
static zend_always_inline bool zend_parse_arg_string(zval *arg, char **dest, size_t *dest_len, bool check_null, uint32_t arg_num)
23102331
{
23112332
zend_string *str;
@@ -2529,7 +2550,8 @@ static zend_always_inline bool zend_parse_arg_array_ht_or_str(
25292550
*dest_str = NULL;
25302551
} else {
25312552
*dest_ht = NULL;
2532-
return zend_parse_arg_str_slow(arg, dest_str, arg_num);
2553+
*dest_str = zend_parse_arg_str_slow(arg, arg_num);
2554+
return *dest_str != NULL;
25332555
}
25342556
return 1;
25352557
}

Zend/zend_execute.c

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -734,7 +734,6 @@ static bool zend_verify_weak_scalar_type_hint(uint32_t type_mask, zval *arg)
734734
{
735735
zend_long lval;
736736
double dval;
737-
zend_string *str;
738737
bool bval;
739738

740739
/* Type preference order: int -> float -> string -> bool */
@@ -766,7 +765,7 @@ static bool zend_verify_weak_scalar_type_hint(uint32_t type_mask, zval *arg)
766765
ZVAL_DOUBLE(arg, dval);
767766
return 1;
768767
}
769-
if ((type_mask & MAY_BE_STRING) && zend_parse_arg_str_weak(arg, &str, 0)) {
768+
if ((type_mask & MAY_BE_STRING) && zend_parse_arg_str_weak(arg, 0)) {
770769
/* on success "arg" is converted to IS_STRING */
771770
return 1;
772771
}

Zend/zend_frameless_function.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -65,7 +65,7 @@
6565
dest_ht = NULL; \
6666
ZVAL_COPY(&str_tmp, arg ## arg_num); \
6767
arg ## arg_num = &str_tmp; \
68-
if (!zend_flf_parse_arg_str_slow(arg ## arg_num, &dest_str, arg_num)) { \
68+
if (!(dest_str = zend_flf_parse_arg_str_slow(arg ## arg_num, arg_num))) { \
6969
zend_wrong_parameter_type_error(arg_num, Z_EXPECTED_ARRAY_OR_STRING, arg ## arg_num); \
7070
goto flf_clean; \
7171
} \

Zend/zend_vm_def.h

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8763,7 +8763,6 @@ ZEND_VM_COLD_CONST_HANDLER(121, ZEND_STRLEN, CONST|TMPVAR|CV, ANY)
87638763
strict = EX_USES_STRICT_TYPES();
87648764
do {
87658765
if (EXPECTED(!strict)) {
8766-
zend_string *str;
87678766
zval tmp;
87688767

87698768
if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) {
@@ -8777,7 +8776,7 @@ ZEND_VM_COLD_CONST_HANDLER(121, ZEND_STRLEN, CONST|TMPVAR|CV, ANY)
87778776
}
87788777

87798778
ZVAL_COPY(&tmp, value);
8780-
if (zend_parse_arg_str_weak(&tmp, &str, 1)) {
8779+
if (zend_string *str = zend_parse_arg_str_weak(&tmp, 1)) {
87818780
ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
87828781
zval_ptr_dtor(&tmp);
87838782
break;

Zend/zend_vm_execute.h

Lines changed: 3 additions & 6 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

0 commit comments

Comments
 (0)