Skip to content

ZPP: Reduce code bloat for Z_PARAM_STR #19359

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Draft
wants to merge 1 commit into
base: master
Choose a base branch
from
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
30 changes: 15 additions & 15 deletions Zend/zend_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -755,58 +755,58 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_or_str_slow(zval *arg, zval **
return true;
}

ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest, uint32_t arg_num) /* {{{ */
ZEND_API zend_string* ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, uint32_t arg_num) /* {{{ */
{
if (EXPECTED(Z_TYPE_P(arg) < IS_STRING)) {
if (UNEXPECTED(Z_TYPE_P(arg) == IS_NULL) && !zend_null_arg_deprecated("string", arg_num)) {
return 0;
return NULL;
}
convert_to_string(arg);
*dest = Z_STR_P(arg);
return Z_STR_P(arg);
} else if (UNEXPECTED(Z_TYPE_P(arg) == IS_OBJECT)) {
zend_object *zobj = Z_OBJ_P(arg);
zval obj;
if (zobj->handlers->cast_object(zobj, &obj, IS_STRING) == SUCCESS) {
OBJ_RELEASE(zobj);
ZVAL_COPY_VALUE(arg, &obj);
*dest = Z_STR_P(arg);
return 1;
return Z_STR_P(arg);
}
return 0;
return NULL;
} else {
return 0;
return NULL;
}
return 1;
}
/* }}} */

ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num) /* {{{ */
ZEND_API zend_string* ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, uint32_t arg_num) /* {{{ */
{
if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
return 0;
return NULL;
}
return zend_parse_arg_str_weak(arg, dest, arg_num);
return zend_parse_arg_str_weak(arg, arg_num);
}
/* }}} */

ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num)
ZEND_API zend_string* ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, uint32_t arg_num)
{
if (UNEXPECTED(ZEND_FLF_ARG_USES_STRICT_TYPES())) {
return 0;
return NULL;
}
return zend_parse_arg_str_weak(arg, dest, arg_num);
return zend_parse_arg_str_weak(arg, arg_num);
}

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) /* {{{ */
{
zend_string *str;
if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) {
return 0;
}
if (zend_parse_arg_long_weak(arg, dest_long, arg_num)) {
*dest_str = NULL;
return 1;
} else if (zend_parse_arg_str_weak(arg, dest_str, arg_num)) {
} else if ((str = zend_parse_arg_str_weak(arg, arg_num)) != NULL) {
*dest_long = 0;
*dest_str = str;
return 1;
} else {
return 0;
Expand Down
36 changes: 29 additions & 7 deletions Zend/zend_API.h
Original file line number Diff line number Diff line change
Expand Up @@ -2088,7 +2088,13 @@ ZEND_API ZEND_COLD void zend_class_redeclaration_error_ex(int type, zend_string
}

#define Z_PARAM_STR(dest) \
Z_PARAM_STR_EX(dest, 0, 0)
Z_PARAM_PROLOGUE(false, false); \
dest = zend_parse_arg_str_no_null(_arg, _i); \
if (UNEXPECTED(dest == NULL)) { \
_expected_type = Z_EXPECTED_STRING; \
_error_code = ZPP_ERROR_WRONG_ARG; \
break; \
}

#define Z_PARAM_STR_OR_NULL(dest) \
Z_PARAM_STR_EX(dest, 1, 0)
Expand Down Expand Up @@ -2183,14 +2189,14 @@ ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_slow(const zval *arg, zend_long
ZEND_API bool ZEND_FASTCALL zend_parse_arg_long_weak(const zval *arg, zend_long *dest, uint32_t arg_num);
ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_slow(const zval *arg, double *dest, uint32_t arg_num);
ZEND_API bool ZEND_FASTCALL zend_parse_arg_double_weak(const zval *arg, double *dest, uint32_t arg_num);
ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num);
ZEND_API bool ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest, uint32_t arg_num);
ZEND_API zend_string* ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, uint32_t arg_num);
ZEND_API zend_string* ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, uint32_t arg_num);
ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_slow(zval *arg, zval **dest, uint32_t arg_num);
ZEND_API bool ZEND_FASTCALL zend_parse_arg_number_or_str_slow(zval *arg, zval **dest, uint32_t arg_num);
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);

ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_bool_slow(const zval *arg, bool *dest, uint32_t arg_num);
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, zend_string **dest, uint32_t arg_num);
ZEND_API zend_string* ZEND_FASTCALL zend_flf_parse_arg_str_slow(zval *arg, uint32_t arg_num);
ZEND_API bool ZEND_FASTCALL zend_flf_parse_arg_long_slow(const zval *arg, zend_long *dest, uint32_t arg_num);

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)
Expand Down Expand Up @@ -2292,10 +2298,16 @@ static zend_always_inline bool zend_parse_arg_str_ex(zval *arg, zend_string **de
} else if (check_null && Z_TYPE_P(arg) == IS_NULL) {
*dest = NULL;
} else {
zend_string *str;
if (frameless) {
return zend_flf_parse_arg_str_slow(arg, dest, arg_num);
str = zend_flf_parse_arg_str_slow(arg, arg_num);
} else {
return zend_parse_arg_str_slow(arg, dest, arg_num);
str = zend_parse_arg_str_slow(arg, arg_num);
}
if (str) {
*dest = str;
} else {
return 0;
}
}
return 1;
Expand All @@ -2306,6 +2318,15 @@ static zend_always_inline bool zend_parse_arg_str(zval *arg, zend_string **dest,
return zend_parse_arg_str_ex(arg, dest, check_null, arg_num, /* frameless */ false);
}

static zend_always_inline zend_string *zend_parse_arg_str_no_null(zval *arg, uint32_t arg_num)
{
if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) {
return Z_STR_P(arg);
} else {
return zend_parse_arg_str_slow(arg, arg_num);
}
}

Comment on lines +2321 to +2329
Copy link
Member

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

While I agree with getting rid of the dest param for the _slow functions, does this particular extra function actually change anything? Please check the asm; given that it's force inlined it ought to be equivalent to zend_parse_arg_str_ex.

static zend_always_inline bool zend_parse_arg_string(zval *arg, char **dest, size_t *dest_len, bool check_null, uint32_t arg_num)
{
zend_string *str;
Expand Down Expand Up @@ -2529,7 +2550,8 @@ static zend_always_inline bool zend_parse_arg_array_ht_or_str(
*dest_str = NULL;
} else {
*dest_ht = NULL;
return zend_parse_arg_str_slow(arg, dest_str, arg_num);
*dest_str = zend_parse_arg_str_slow(arg, arg_num);
return *dest_str != NULL;
}
return 1;
}
Expand Down
3 changes: 1 addition & 2 deletions Zend/zend_execute.c
Original file line number Diff line number Diff line change
Expand Up @@ -734,7 +734,6 @@ static bool zend_verify_weak_scalar_type_hint(uint32_t type_mask, zval *arg)
{
zend_long lval;
double dval;
zend_string *str;
bool bval;

/* Type preference order: int -> float -> string -> bool */
Expand Down Expand Up @@ -766,7 +765,7 @@ static bool zend_verify_weak_scalar_type_hint(uint32_t type_mask, zval *arg)
ZVAL_DOUBLE(arg, dval);
return 1;
}
if ((type_mask & MAY_BE_STRING) && zend_parse_arg_str_weak(arg, &str, 0)) {
if ((type_mask & MAY_BE_STRING) && zend_parse_arg_str_weak(arg, 0)) {
/* on success "arg" is converted to IS_STRING */
return 1;
}
Expand Down
2 changes: 1 addition & 1 deletion Zend/zend_frameless_function.h
Original file line number Diff line number Diff line change
Expand Up @@ -65,7 +65,7 @@
dest_ht = NULL; \
ZVAL_COPY(&str_tmp, arg ## arg_num); \
arg ## arg_num = &str_tmp; \
if (!zend_flf_parse_arg_str_slow(arg ## arg_num, &dest_str, arg_num)) { \
if (!(dest_str = zend_flf_parse_arg_str_slow(arg ## arg_num, arg_num))) { \
zend_wrong_parameter_type_error(arg_num, Z_EXPECTED_ARRAY_OR_STRING, arg ## arg_num); \
goto flf_clean; \
} \
Expand Down
4 changes: 2 additions & 2 deletions Zend/zend_vm_def.h
Original file line number Diff line number Diff line change
Expand Up @@ -8763,8 +8763,8 @@ ZEND_VM_COLD_CONST_HANDLER(121, ZEND_STRLEN, CONST|TMPVAR|CV, ANY)
strict = EX_USES_STRICT_TYPES();
do {
if (EXPECTED(!strict)) {
zend_string *str;
zval tmp;
zend_string *str;

if (UNEXPECTED(Z_TYPE_P(value) == IS_NULL)) {
zend_error(E_DEPRECATED,
Expand All @@ -8777,7 +8777,7 @@ ZEND_VM_COLD_CONST_HANDLER(121, ZEND_STRLEN, CONST|TMPVAR|CV, ANY)
}

ZVAL_COPY(&tmp, value);
if (zend_parse_arg_str_weak(&tmp, &str, 1)) {
if ((str = zend_parse_arg_str_weak(&tmp, 1)) != NULL) {
ZVAL_LONG(EX_VAR(opline->result.var), ZSTR_LEN(str));
zval_ptr_dtor(&tmp);
break;
Expand Down
12 changes: 6 additions & 6 deletions Zend/zend_vm_execute.h

Some generated files are not rendered by default. Learn more about how customized files appear on GitHub.