From 35f9b90bb839a49c67b594b23694140d04dbb270 Mon Sep 17 00:00:00 2001 From: Dmitry Stogov Date: Fri, 20 Mar 2015 23:18:52 +0300 Subject: [PATCH] ZPP changed to lazely check for "strict/weak" only if it's really necessary. Cleanup. --- Zend/zend_API.c | 346 +++++++++++++++++++++++++++++------------ Zend/zend_API.h | 178 +++++++-------------- Zend/zend_execute.c | 12 +- Zend/zend_vm_def.h | 26 +--- Zend/zend_vm_execute.h | 78 +++------- 5 files changed, 332 insertions(+), 308 deletions(-) diff --git a/Zend/zend_API.c b/Zend/zend_API.c index c626a8ddd7..91247bbecc 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -150,21 +150,11 @@ ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array) / /* }}} */ ZEND_API void zend_wrong_param_count(void) /* {{{ */ -{ - if (ZEND_ARG_USES_STRICT_TYPES()) { - zend_wrong_param_count_ex(1); - } else { - zend_wrong_param_count_ex(0); - } -} -/* }}} */ - -ZEND_API void zend_wrong_param_count_ex(zend_bool strict) /* {{{ */ { const char *space; const char *class_name = get_active_class_name(&space); - zend_internal_type_error(strict, "Wrong parameter count for %s%s%s()", class_name, space, get_active_function_name()); + zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "Wrong parameter count for %s%s%s()", class_name, space, get_active_function_name()); } /* }}} */ @@ -205,51 +195,13 @@ ZEND_API char *zend_zval_type_name(const zval *arg) /* {{{ */ } /* }}} */ -ZEND_API int parse_arg_object_to_str(zval *arg, zend_string **str, int type) /* {{{ */ -{ - if (Z_OBJ_HANDLER_P(arg, cast_object)) { - zval obj; - if (Z_OBJ_HANDLER_P(arg, cast_object)(arg, &obj, type) == SUCCESS) { - zval_ptr_dtor(arg); - ZVAL_COPY_VALUE(arg, &obj); - *str = Z_STR_P(arg); - return SUCCESS; - } - } - /* Standard PHP objects */ - if (Z_OBJ_HT_P(arg) == &std_object_handlers || !Z_OBJ_HANDLER_P(arg, cast_object)) { - SEPARATE_ZVAL_NOREF(arg); - if (zend_std_cast_object_tostring(arg, arg, type) == SUCCESS) { - *str = Z_STR_P(arg); - return SUCCESS; - } - } - if (!Z_OBJ_HANDLER_P(arg, cast_object) && Z_OBJ_HANDLER_P(arg, get)) { - zval rv; - zval *z = Z_OBJ_HANDLER_P(arg, get)(arg, &rv); - Z_ADDREF_P(z); - if(Z_TYPE_P(z) != IS_OBJECT) { - zval_dtor(arg); - ZVAL_NULL(arg); - if (!zend_make_printable_zval(z, arg)) { - ZVAL_ZVAL(arg, z, 1, 1); - } - *str = Z_STR_P(arg); - return SUCCESS; - } - zval_ptr_dtor(z); - } - return FAILURE; -} -/* }}} */ - #ifdef FAST_ZPP -ZEND_API void zend_wrong_paramers_count_error(int num_args, int min_num_args, int max_num_args, zend_bool strict) /* {{{ */ +ZEND_API void ZEND_FASTCALL zend_wrong_paramers_count_error(int num_args, int min_num_args, int max_num_args) /* {{{ */ { zend_function *active_function = EG(current_execute_data)->func; const char *class_name = active_function->common.scope ? active_function->common.scope->name->val : ""; - zend_internal_type_error(strict, "%s%s%s() expects %s %d parameter%s, %d given", + zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects %s %d parameter%s, %d given", class_name, \ class_name[0] ? "::" : "", \ active_function->common.function_name->val, @@ -260,7 +212,7 @@ ZEND_API void zend_wrong_paramers_count_error(int num_args, int min_num_args, in } /* }}} */ -ZEND_API void zend_wrong_paramer_type_error(int num, zend_expected_type expected_type, zval *arg, zend_bool strict) /* {{{ */ +ZEND_API void ZEND_FASTCALL zend_wrong_paramer_type_error(int num, zend_expected_type expected_type, zval *arg) /* {{{ */ { const char *space; const char *class_name = get_active_class_name(&space); @@ -269,28 +221,28 @@ ZEND_API void zend_wrong_paramer_type_error(int num, zend_expected_type expected NULL }; - zend_internal_type_error(strict, "%s%s%s() expects parameter %d to be %s, %s given", + zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be %s, %s given", class_name, space, get_active_function_name(), num, expected_error[expected_type], zend_zval_type_name(arg)); } /* }}} */ -ZEND_API void zend_wrong_paramer_class_error(int num, char *name, zval *arg, zend_bool strict) /* {{{ */ +ZEND_API void ZEND_FASTCALL zend_wrong_paramer_class_error(int num, char *name, zval *arg) /* {{{ */ { const char *space; const char *class_name = get_active_class_name(&space); - zend_internal_type_error(strict, "%s%s%s() expects parameter %d to be %s, %s given", + zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be %s, %s given", class_name, space, get_active_function_name(), num, name, zend_zval_type_name(arg)); } /* }}} */ -ZEND_API void zend_wrong_callback_error(int severity, int num, char *error, zend_bool strict) /* {{{ */ +ZEND_API void ZEND_FASTCALL zend_wrong_callback_error(int severity, int num, char *error) /* {{{ */ { const char *space; const char *class_name = get_active_class_name(&space); if (severity == E_WARNING) { - zend_internal_type_error(strict, "%s%s%s() expects parameter %d to be a valid callback, %s", + zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be a valid callback, %s", class_name, space, get_active_function_name(), num, error); } else { zend_error(severity, "%s%s%s() expects parameter %d to be a valid callback, %s", @@ -300,7 +252,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error, zend } /* }}} */ -ZEND_API int zend_parse_arg_class(zval *arg, zend_class_entry **pce, int num, int check_null, zend_bool strict) /* {{{ */ +ZEND_API int ZEND_FASTCALL zend_parse_arg_class(zval *arg, zend_class_entry **pce, int num, int check_null) /* {{{ */ { zend_class_entry *ce_base = *pce; @@ -315,7 +267,7 @@ ZEND_API int zend_parse_arg_class(zval *arg, zend_class_entry **pce, int num, in const char *space; const char *class_name = get_active_class_name(&space); - zend_internal_type_error(strict, "%s%s%s() expects parameter %d to be a class name derived from %s, '%s' given", + zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be a class name derived from %s, '%s' given", class_name, space, get_active_function_name(), num, ce_base->name->val, Z_STRVAL_P(arg)); *pce = NULL; @@ -326,7 +278,7 @@ ZEND_API int zend_parse_arg_class(zval *arg, zend_class_entry **pce, int num, in const char *space; const char *class_name = get_active_class_name(&space); - zend_internal_type_error(strict, "%s%s%s() expects parameter %d to be a valid class name, '%s' given", + zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be a valid class name, '%s' given", class_name, space, get_active_function_name(), num, Z_STRVAL_P(arg)); return 0; @@ -336,7 +288,219 @@ ZEND_API int zend_parse_arg_class(zval *arg, zend_class_entry **pce, int num, in /* }}} */ #endif -static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, const char **spec, char **error, int *severity, zend_bool strict) /* {{{ */ +ZEND_API int ZEND_FASTCALL zend_parse_arg_bool_weak(zval *arg, zend_bool *dest) /* {{{ */ +{ + if (EXPECTED(Z_TYPE_P(arg) <= IS_STRING)) { + *dest = zend_is_true(arg); + } else { + return 0; + } + return 1; +} +/* }}} */ + +ZEND_API int ZEND_FASTCALL zend_parse_arg_bool_slow(zval *arg, zend_bool *dest) /* {{{ */ +{ + if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) { + return 0; + } + return zend_parse_arg_bool_weak(arg, dest); +} +/* }}} */ + +ZEND_API int ZEND_FASTCALL zend_parse_arg_long_weak(zval *arg, zend_long *dest) /* {{{ */ +{ + if (EXPECTED(Z_TYPE_P(arg) == IS_DOUBLE)) { + if (UNEXPECTED(zend_isnan(Z_DVAL_P(arg)))) { + return 0; + } + if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(arg)))) { + return 0; + } else { + *dest = zend_dval_to_lval(Z_DVAL_P(arg)); + } + } else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) { + double d; + int type; + + if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), dest, &d)) != IS_LONG)) { + if (EXPECTED(type != 0)) { + if (UNEXPECTED(zend_isnan(d))) { + return 0; + } + if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(d))) { + return 0; + } else { + *dest = zend_dval_to_lval(d); + } + } else { + return 0; + } + } + } else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) { + *dest = 0; + } else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) { + *dest = 1; + } else { + return 0; + } + return 1; +} +/* }}} */ + +ZEND_API int ZEND_FASTCALL zend_parse_arg_long_slow(zval *arg, zend_long *dest) /* {{{ */ +{ + if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) { + return 0; + } + return zend_parse_arg_long_weak(arg, dest); +} +/* }}} */ + +ZEND_API int ZEND_FASTCALL zend_parse_arg_long_cap_weak(zval *arg, zend_long *dest) /* {{{ */ +{ + if (EXPECTED(Z_TYPE_P(arg) == IS_DOUBLE)) { + if (UNEXPECTED(zend_isnan(Z_DVAL_P(arg)))) { + return 0; + } + if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(arg)))) { + *dest = (Z_DVAL_P(arg) > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN; + } else { + *dest = zend_dval_to_lval(Z_DVAL_P(arg)); + } + } else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) { + double d; + int type; + + if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), dest, &d)) != IS_LONG)) { + if (EXPECTED(type != 0)) { + if (UNEXPECTED(zend_isnan(d))) { + return 0; + } + if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(d))) { + *dest = (d > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN; + } else { + *dest = zend_dval_to_lval(d); + } + } else { + return 0; + } + } + } else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) { + *dest = 0; + } else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) { + *dest = 1; + } else { + return 0; + } + return 1; +} +/* }}} */ + +ZEND_API int ZEND_FASTCALL zend_parse_arg_long_cap_slow(zval *arg, zend_long *dest) /* {{{ */ +{ + if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) { + return 0; + } + return zend_parse_arg_long_cap_weak(arg, dest); +} +/* }}} */ + +ZEND_API int ZEND_FASTCALL zend_parse_arg_double_weak(zval *arg, double *dest) /* {{{ */ +{ + if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) { + *dest = (double)Z_LVAL_P(arg); + } else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) { + zend_long l; + int type; + + if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), &l, dest)) != IS_DOUBLE)) { + if (EXPECTED(type != 0)) { + *dest = (double)(l); + } else { + return 0; + } + } + } else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) { + *dest = 0.0; + } else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) { + *dest = 1.0; + } else { + return 0; + } + return 1; +} +/* }}} */ + +ZEND_API int ZEND_FASTCALL zend_parse_arg_double_slow(zval *arg, double *dest) /* {{{ */ +{ + if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) { + /* SSTH Exception: IS_LONG may be accepted instead as IS_DOUBLE */ + *dest = (double)Z_LVAL_P(arg); + } else if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) { + return 0; + } + return zend_parse_arg_double_weak(arg, dest); +} +/* }}} */ + +ZEND_API int ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest) /* {{{ */ +{ + if (EXPECTED(Z_TYPE_P(arg) < IS_STRING)) { + convert_to_string(arg); + *dest = Z_STR_P(arg); + } else if (UNEXPECTED(Z_TYPE_P(arg) == IS_OBJECT)) { + if (Z_OBJ_HANDLER_P(arg, cast_object)) { + zval obj; + if (Z_OBJ_HANDLER_P(arg, cast_object)(arg, &obj, IS_STRING) == SUCCESS) { + zval_ptr_dtor(arg); + ZVAL_COPY_VALUE(arg, &obj); + *dest = Z_STR_P(arg); + return 1; + } + } + /* Standard PHP objects */ + if (Z_OBJ_HT_P(arg) == &std_object_handlers || !Z_OBJ_HANDLER_P(arg, cast_object)) { + SEPARATE_ZVAL_NOREF(arg); + if (zend_std_cast_object_tostring(arg, arg, IS_STRING) == SUCCESS) { + *dest = Z_STR_P(arg); + return 1; + } + } + if (!Z_OBJ_HANDLER_P(arg, cast_object) && Z_OBJ_HANDLER_P(arg, get)) { + zval rv; + zval *z = Z_OBJ_HANDLER_P(arg, get)(arg, &rv); + + Z_ADDREF_P(z); + if (Z_TYPE_P(z) != IS_OBJECT) { + zval_dtor(arg); + ZVAL_NULL(arg); + if (!zend_make_printable_zval(z, arg)) { + ZVAL_ZVAL(arg, z, 1, 1); + } + *dest = Z_STR_P(arg); + return 1; + } + zval_ptr_dtor(z); + } + return 0; + } else { + return 0; + } + return 1; +} +/* }}} */ + +ZEND_API int ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest) /* {{{ */ +{ + if (UNEXPECTED(ZEND_ARG_USES_STRICT_TYPES())) { + return 0; + } + return zend_parse_arg_str_weak(arg, dest); +} +/* }}} */ + +static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, const char **spec, char **error, int *severity) /* {{{ */ { const char *spec_walk = *spec; char c = *spec_walk++; @@ -368,7 +532,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons is_null = va_arg(*va, zend_bool *); } - if (!zend_parse_arg_long(arg, p, is_null, check_null, c == 'L', strict)) { + if (!zend_parse_arg_long(arg, p, is_null, check_null, c == 'L')) { return "integer"; } } @@ -383,7 +547,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons is_null = va_arg(*va, zend_bool *); } - if (!zend_parse_arg_double(arg, p, is_null, check_null, strict)) { + if (!zend_parse_arg_double(arg, p, is_null, check_null)) { return "float"; } } @@ -393,7 +557,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons { char **p = va_arg(*va, char **); size_t *pl = va_arg(*va, size_t *); - if (!zend_parse_arg_string(arg, p, pl, check_null, strict)) { + if (!zend_parse_arg_string(arg, p, pl, check_null)) { return "string"; } } @@ -403,7 +567,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons { char **p = va_arg(*va, char **); size_t *pl = va_arg(*va, size_t *); - if (!zend_parse_arg_path(arg, p, pl, check_null, strict)) { + if (!zend_parse_arg_path(arg, p, pl, check_null)) { return "a valid path"; } } @@ -412,7 +576,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons case 'P': { zend_string **str = va_arg(*va, zend_string **); - if (!zend_parse_arg_path_str(arg, str, check_null, strict)) { + if (!zend_parse_arg_path_str(arg, str, check_null)) { return "a valid path"; } } @@ -421,7 +585,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons case 'S': { zend_string **str = va_arg(*va, zend_string **); - if (!zend_parse_arg_str(arg, str, check_null, strict)) { + if (!zend_parse_arg_str(arg, str, check_null)) { return "string"; } } @@ -436,7 +600,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons is_null = va_arg(*va, zend_bool *); } - if (!zend_parse_arg_bool(arg, p, is_null, check_null, strict)) { + if (!zend_parse_arg_bool(arg, p, is_null, check_null)) { return "boolean"; } } @@ -555,7 +719,7 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons break; } else { if (is_callable_error) { - *severity = strict ? (E_EXCEPTION | E_ERROR) : E_WARNING; + *severity = E_EXCEPTION | E_ERROR; zend_spprintf(error, 0, "to be a valid callback, %s", is_callable_error); efree(is_callable_error); return ""; @@ -586,24 +750,24 @@ static const char *zend_parse_arg_impl(int arg_num, zval *arg, va_list *va, cons } /* }}} */ -static int zend_parse_arg(int arg_num, zval *arg, va_list *va, const char **spec, int quiet, zend_bool strict) /* {{{ */ +static int zend_parse_arg(int arg_num, zval *arg, va_list *va, const char **spec, int flags) /* {{{ */ { const char *expected_type = NULL; char *error = NULL; int severity; - expected_type = zend_parse_arg_impl(arg_num, arg, va, spec, &error, &severity, strict); + expected_type = zend_parse_arg_impl(arg_num, arg, va, spec, &error, &severity); if (expected_type) { - if (!quiet && (*expected_type || error)) { + if (!(flags & ZEND_PARSE_PARAMS_QUIET) && (*expected_type || error)) { const char *space; const char *class_name = get_active_class_name(&space); if (error) { - zend_internal_type_error(strict, "%s%s%s() expects parameter %d %s", + zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d %s", class_name, space, get_active_function_name(), arg_num, error); efree(error); } else { - zend_internal_type_error(strict, "%s%s%s() expects parameter %d to be %s, %s given", + zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be %s, %s given", class_name, space, get_active_function_name(), arg_num, expected_type, zend_zval_type_name(arg)); } @@ -621,11 +785,9 @@ ZEND_API int zend_parse_parameter(int flags, int arg_num, zval *arg, const char { va_list va; int ret; - int quiet = flags & ZEND_PARSE_PARAMS_QUIET; - zend_bool strict = (flags & ZEND_PARSE_PARAMS_STRICT) ? 1 : 0; va_start(va, spec); - ret = zend_parse_arg(arg_num, arg, &va, &spec, quiet, strict); + ret = zend_parse_arg(arg_num, arg, &va, &spec, flags); va_end(va); return ret; @@ -640,8 +802,6 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va, int post_varargs = 0; zval *arg; int arg_count; - int quiet = flags & ZEND_PARSE_PARAMS_QUIET; - zend_bool strict = (flags & ZEND_PARSE_PARAMS_STRICT) ? 1 : 0; zend_bool have_varargs = 0; zval **varargs = NULL; int *n_varargs = NULL; @@ -674,7 +834,7 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va, case '*': case '+': if (have_varargs) { - if (!quiet) { + if (!(flags & ZEND_PARSE_PARAMS_QUIET)) { zend_function *active_function = EG(current_execute_data)->func; const char *class_name = active_function->common.scope ? active_function->common.scope->name->val : ""; @@ -695,7 +855,7 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va, break; default: - if (!quiet) { + if (!(flags & ZEND_PARSE_PARAMS_QUIET)) { zend_function *active_function = EG(current_execute_data)->func; const char *class_name = active_function->common.scope ? active_function->common.scope->name->val : ""; zend_error(E_WARNING, "%s%s%s(): bad type specifier while parsing parameters", @@ -718,10 +878,10 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va, } if (num_args < min_num_args || (num_args > max_num_args && max_num_args > 0)) { - if (!quiet) { + if (!(flags & ZEND_PARSE_PARAMS_QUIET)) { zend_function *active_function = EG(current_execute_data)->func; const char *class_name = active_function->common.scope ? active_function->common.scope->name->val : ""; - zend_internal_type_error(strict, "%s%s%s() expects %s %d parameter%s, %d given", + zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects %s %d parameter%s, %d given", class_name, class_name[0] ? "::" : "", active_function->common.function_name->val, @@ -770,7 +930,7 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va, arg = ZEND_CALL_ARG(EG(current_execute_data), i + 1); - if (zend_parse_arg(i+1, arg, va, &type_spec, quiet, strict) == FAILURE) { + if (zend_parse_arg(i+1, arg, va, &type_spec, flags) == FAILURE) { /* clean up varargs array if it was used */ if (varargs && *varargs) { *varargs = NULL; @@ -790,7 +950,7 @@ static int zend_parse_va_args(int num_args, const char *type_spec, va_list *va, if (0 == (type_spec)[0] && 0 != __num_args && !(flags & ZEND_PARSE_PARAMS_QUIET)) { \ const char *__space; \ const char * __class_name = get_active_class_name(&__space); \ - zend_internal_type_error((flags & ZEND_PARSE_PARAMS_STRICT), "%s%s%s() expects exactly 0 parameters, %d given", \ + zend_internal_type_error(ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects exactly 0 parameters, %d given", \ __class_name, __space, \ get_active_function_name(), __num_args); \ return FAILURE; \ @@ -802,10 +962,6 @@ ZEND_API int zend_parse_parameters_ex(int flags, int num_args, const char *type_ va_list va; int retval; - if (ZEND_ARG_USES_STRICT_TYPES()) { - flags |= ZEND_PARSE_PARAMS_STRICT; - } - RETURN_IF_ZERO_ARGS(num_args, type_spec, flags); va_start(va, type_spec); @@ -822,10 +978,6 @@ ZEND_API int zend_parse_parameters(int num_args, const char *type_spec, ...) /* int retval; int flags = 0; - if (ZEND_ARG_USES_STRICT_TYPES()) { - flags |= ZEND_PARSE_PARAMS_STRICT; - } - RETURN_IF_ZERO_ARGS(num_args, type_spec, flags); va_start(va, type_spec); @@ -851,10 +1003,6 @@ ZEND_API int zend_parse_method_parameters(int num_args, zval *this_ptr, const ch * wrong branch here. */ zend_bool is_method = EG(current_execute_data)->func->common.scope != NULL; - if (ZEND_ARG_USES_STRICT_TYPES()) { - flags |= ZEND_PARSE_PARAMS_STRICT; - } - if (!is_method || !this_ptr || Z_TYPE_P(this_ptr) != IS_OBJECT) { RETURN_IF_ZERO_ARGS(num_args, p, flags); @@ -891,10 +1039,6 @@ ZEND_API int zend_parse_method_parameters_ex(int flags, int num_args, zval *this zval **object; zend_class_entry *ce; - if (ZEND_ARG_USES_STRICT_TYPES()) { - flags |= ZEND_PARSE_PARAMS_STRICT; - } - if (!this_ptr) { RETURN_IF_ZERO_ARGS(num_args, p, flags); diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 31b7b054d3..bd90e953fe 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -256,9 +256,7 @@ ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array); /* Parameter parsing API -- andrei */ -#define ZEND_PARSE_PARAMS_QUIET (1<<1) -#define ZEND_PARSE_PARAMS_STRICT (1<<2) - +#define ZEND_PARSE_PARAMS_QUIET (1<<1) ZEND_API int zend_parse_parameters(int num_args, const char *type_spec, ...); ZEND_API int zend_parse_parameters_ex(int flags, int num_args, const char *type_spec, ...); ZEND_API char *zend_zval_type_name(const zval *arg); @@ -297,7 +295,6 @@ ZEND_API int zend_disable_function(char *function_name, size_t function_name_len ZEND_API int zend_disable_class(char *class_name, size_t class_name_length); ZEND_API void zend_wrong_param_count(void); -ZEND_API void zend_wrong_param_count_ex(zend_bool strict); #define IS_CALLABLE_CHECK_SYNTAX_ONLY (1<<0) #define IS_CALLABLE_CHECK_NO_ACCESS (1<<1) @@ -707,10 +704,10 @@ typedef enum _zend_expected_type { Z_EXPECTED_LAST } zend_expected_type; -ZEND_API void zend_wrong_paramers_count_error(int num_args, int min_num_args, int max_num_args, zend_bool strict); -ZEND_API void zend_wrong_paramer_type_error(int num, zend_expected_type expected_type, zval *arg, zend_bool strict); -ZEND_API void zend_wrong_paramer_class_error(int num, char *name, zval *arg, zend_bool strict); -ZEND_API void zend_wrong_callback_error(int severity, int num, char *error, zend_bool strict); +ZEND_API void ZEND_FASTCALL zend_wrong_paramers_count_error(int num_args, int min_num_args, int max_num_args); +ZEND_API void ZEND_FASTCALL zend_wrong_paramer_type_error(int num, zend_expected_type expected_type, zval *arg); +ZEND_API void ZEND_FASTCALL zend_wrong_paramer_class_error(int num, char *name, zval *arg); +ZEND_API void ZEND_FASTCALL zend_wrong_callback_error(int severity, int num, char *error); #define ZPP_ERROR_OK 0 #define ZPP_ERROR_FAILURE 1 @@ -720,8 +717,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error, zend #define ZPP_ERROR_WRONG_COUNT 5 #define ZEND_PARSE_PARAMETERS_START_EX(flags, min_num_args, max_num_args) do { \ - zend_bool _strict = ZEND_ARG_USES_STRICT_TYPES(); \ - const int _flags = (flags) | (_strict ? ZEND_PARSE_PARAMS_STRICT : 0); \ + const int _flags = (flags); \ int _min_num_args = (min_num_args); \ int _max_num_args = (max_num_args); \ int _num_args = EX_NUM_ARGS(); \ @@ -745,7 +741,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error, zend (UNEXPECTED(_num_args > _max_num_args) && \ EXPECTED(_max_num_args >= 0))) { \ if (!(_flags & ZEND_PARSE_PARAMS_QUIET)) { \ - zend_wrong_paramers_count_error(_num_args, _min_num_args, _max_num_args, _strict); \ + zend_wrong_paramers_count_error(_num_args, _min_num_args, _max_num_args); \ } \ error_code = ZPP_ERROR_FAILURE; \ break; \ @@ -761,11 +757,11 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error, zend if (UNEXPECTED(error_code != ZPP_ERROR_OK)) { \ if (!(_flags & ZEND_PARSE_PARAMS_QUIET)) { \ if (error_code == ZPP_ERROR_WRONG_CALLBACK) { \ - zend_wrong_callback_error(E_WARNING, _i, _error, _strict); \ + zend_wrong_callback_error(E_WARNING, _i, _error); \ } else if (error_code == ZPP_ERROR_WRONG_CLASS) { \ - zend_wrong_paramer_class_error(_i, _error, _arg, _strict); \ + zend_wrong_paramer_class_error(_i, _error, _arg); \ } else if (error_code == ZPP_ERROR_WRONG_ARG) { \ - zend_wrong_paramer_type_error(_i, _expected_type, _arg, _strict); \ + zend_wrong_paramer_type_error(_i, _expected_type, _arg); \ } \ } \ failure; \ @@ -818,7 +814,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error, zend /* old "b" */ #define Z_PARAM_BOOL_EX(dest, is_null, check_null, separate) \ Z_PARAM_PROLOGUE(separate); \ - if (UNEXPECTED(!zend_parse_arg_bool(_arg, &dest, &is_null, check_null, _strict))) { \ + if (UNEXPECTED(!zend_parse_arg_bool(_arg, &dest, &is_null, check_null))) { \ _expected_type = Z_EXPECTED_BOOL; \ error_code = ZPP_ERROR_WRONG_ARG; \ break; \ @@ -830,7 +826,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error, zend /* old "C" */ #define Z_PARAM_CLASS_EX(dest, check_null, separate) \ Z_PARAM_PROLOGUE(separate); \ - if (UNEXPECTED(!zend_parse_arg_class(_arg, &dest, _i, check_null, _strict))) { \ + if (UNEXPECTED(!zend_parse_arg_class(_arg, &dest, _i, check_null))) { \ error_code = ZPP_ERROR_FAILURE; \ break; \ } @@ -841,7 +837,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error, zend /* old "d" */ #define Z_PARAM_DOUBLE_EX(dest, is_null, check_null, separate) \ Z_PARAM_PROLOGUE(separate); \ - if (UNEXPECTED(!zend_parse_arg_double(_arg, &dest, &is_null, check_null, _strict))) { \ + if (UNEXPECTED(!zend_parse_arg_double(_arg, &dest, &is_null, check_null))) { \ _expected_type = Z_EXPECTED_DOUBLE; \ error_code = ZPP_ERROR_WRONG_ARG; \ break; \ @@ -863,7 +859,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error, zend break; \ } \ } else if (UNEXPECTED(_error != NULL)) { \ - zend_wrong_callback_error(E_STRICT, _i, _error, _strict); \ + zend_wrong_callback_error(E_STRICT, _i, _error); \ } #define Z_PARAM_FUNC(dest_fci, dest_fcc) \ @@ -896,7 +892,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error, zend /* old "l" */ #define Z_PARAM_LONG_EX(dest, is_null, check_null, separate) \ Z_PARAM_PROLOGUE(separate); \ - if (UNEXPECTED(!zend_parse_arg_long(_arg, &dest, &is_null, check_null, 0, _strict))) { \ + if (UNEXPECTED(!zend_parse_arg_long(_arg, &dest, &is_null, check_null, 0))) { \ _expected_type = Z_EXPECTED_LONG; \ error_code = ZPP_ERROR_WRONG_ARG; \ break; \ @@ -908,7 +904,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error, zend /* old "L" */ #define Z_PARAM_STRICT_LONG_EX(dest, is_null, check_null, separate) \ Z_PARAM_PROLOGUE(separate); \ - if (UNEXPECTED(!zend_parse_arg_long(_arg, &dest, &is_null, check_null, 1, _strict))) { \ + if (UNEXPECTED(!zend_parse_arg_long(_arg, &dest, &is_null, check_null, 1))) { \ _expected_type = Z_EXPECTED_LONG; \ error_code = ZPP_ERROR_WRONG_ARG; \ break; \ @@ -950,7 +946,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error, zend /* old "p" */ #define Z_PARAM_PATH_EX(dest, dest_len, check_null, separate) \ Z_PARAM_PROLOGUE(separate); \ - if (UNEXPECTED(!zend_parse_arg_path(_arg, &dest, &dest_len, check_null, _strict))) { \ + if (UNEXPECTED(!zend_parse_arg_path(_arg, &dest, &dest_len, check_null))) { \ _expected_type = Z_EXPECTED_PATH; \ error_code = ZPP_ERROR_WRONG_ARG; \ break; \ @@ -962,7 +958,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error, zend /* old "P" */ #define Z_PARAM_PATH_STR_EX(dest, check_null, separate) \ Z_PARAM_PROLOGUE(separate); \ - if (UNEXPECTED(!zend_parse_arg_path_str(_arg, &dest, check_null, _strict))) { \ + if (UNEXPECTED(!zend_parse_arg_path_str(_arg, &dest, check_null))) { \ _expected_type = Z_EXPECTED_PATH; \ error_code = ZPP_ERROR_WRONG_ARG; \ break; \ @@ -986,7 +982,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error, zend /* old "s" */ #define Z_PARAM_STRING_EX(dest, dest_len, check_null, separate) \ Z_PARAM_PROLOGUE(separate); \ - if (UNEXPECTED(!zend_parse_arg_string(_arg, &dest, &dest_len, check_null, _strict))) { \ + if (UNEXPECTED(!zend_parse_arg_string(_arg, &dest, &dest_len, check_null))) { \ _expected_type = Z_EXPECTED_STRING; \ error_code = ZPP_ERROR_WRONG_ARG; \ break; \ @@ -998,7 +994,7 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error, zend /* old "S" */ #define Z_PARAM_STR_EX(dest, check_null, separate) \ Z_PARAM_PROLOGUE(separate); \ - if (UNEXPECTED(!zend_parse_arg_str(_arg, &dest, check_null, _strict))) { \ + if (UNEXPECTED(!zend_parse_arg_str(_arg, &dest, check_null))) { \ _expected_type = Z_EXPECTED_STRING; \ error_code = ZPP_ERROR_WRONG_ARG; \ break; \ @@ -1052,34 +1048,37 @@ ZEND_API void zend_wrong_callback_error(int severity, int num, char *error, zend /* Inlined implementations shared by new and old parameter parsing APIs */ -ZEND_API int parse_arg_object_to_str(zval *arg, zend_string **str, int type); -ZEND_API int zend_parse_arg_class(zval *arg, zend_class_entry **pce, int num, int check_null, zend_bool strict); - -static zend_always_inline int zend_parse_arg_bool(zval *arg, zend_bool *dest, zend_bool *is_null, int check_null, zend_bool strict) +ZEND_API int ZEND_FASTCALL zend_parse_arg_class(zval *arg, zend_class_entry **pce, int num, int check_null); +ZEND_API int ZEND_FASTCALL zend_parse_arg_bool_slow(zval *arg, zend_bool *dest); +ZEND_API int ZEND_FASTCALL zend_parse_arg_bool_weak(zval *arg, zend_bool *dest); +ZEND_API int ZEND_FASTCALL zend_parse_arg_long_slow(zval *arg, zend_long *dest); +ZEND_API int ZEND_FASTCALL zend_parse_arg_long_weak(zval *arg, zend_long *dest); +ZEND_API int ZEND_FASTCALL zend_parse_arg_long_cap_slow(zval *arg, zend_long *dest); +ZEND_API int ZEND_FASTCALL zend_parse_arg_long_cap_weak(zval *arg, zend_long *dest); +ZEND_API int ZEND_FASTCALL zend_parse_arg_double_slow(zval *arg, double *dest); +ZEND_API int ZEND_FASTCALL zend_parse_arg_double_weak(zval *arg, double *dest); +ZEND_API int ZEND_FASTCALL zend_parse_arg_str_slow(zval *arg, zend_string **dest); +ZEND_API int ZEND_FASTCALL zend_parse_arg_str_weak(zval *arg, zend_string **dest); + +static zend_always_inline int zend_parse_arg_bool(zval *arg, zend_bool *dest, zend_bool *is_null, int check_null) { if (check_null) { *is_null = 0; } if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) { *dest = 1; - } else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) { - if (check_null) { - *is_null = (Z_TYPE_P(arg) == IS_NULL); - } else if (strict && Z_TYPE_P(arg) == IS_NULL) { - return 0; - } + } else if (EXPECTED(Z_TYPE_P(arg) == IS_FALSE)) { + *dest = 0; + } else if (check_null && Z_TYPE_P(arg) == IS_NULL) { + *is_null = 1; *dest = 0; - } else if (UNEXPECTED(strict)) { - return 0; - } else if (EXPECTED(Z_TYPE_P(arg) <= IS_STRING)) { - *dest = zend_is_true(arg); } else { - return 0; + return zend_parse_arg_bool_slow(arg, dest); } return 1; } -static zend_always_inline int zend_parse_arg_long(zval *arg, zend_long *dest, zend_bool *is_null, int check_null, int cap, zend_bool strict) +static zend_always_inline int zend_parse_arg_long(zval *arg, zend_long *dest, zend_bool *is_null, int check_null, int cap) { if (check_null) { *is_null = 0; @@ -1089,54 +1088,15 @@ static zend_always_inline int zend_parse_arg_long(zval *arg, zend_long *dest, ze } else if (check_null && Z_TYPE_P(arg) == IS_NULL) { *is_null = 1; *dest = 0; - } else if (UNEXPECTED(strict)) { - return 0; - } else if (EXPECTED(Z_TYPE_P(arg) == IS_DOUBLE)) { - if (UNEXPECTED(zend_isnan(Z_DVAL_P(arg)))) { - return 0; - } - if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(Z_DVAL_P(arg)))) { - if (cap) { - *dest = (Z_DVAL_P(arg) > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN; - } else { - return 0; - } - } else { - *dest = zend_dval_to_lval(Z_DVAL_P(arg)); - } - } else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) { - double d; - int type; - - if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), dest, &d)) != IS_LONG)) { - if (EXPECTED(type != 0)) { - if (UNEXPECTED(zend_isnan(d))) { - return 0; - } - if (UNEXPECTED(!ZEND_DOUBLE_FITS_LONG(d))) { - if (cap) { - *dest = (d > 0) ? ZEND_LONG_MAX : ZEND_LONG_MIN; - } else { - return 0; - } - } else { - *dest = zend_dval_to_lval(d); - } - } else { - return 0; - } - } - } else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) { - *dest = 0; - } else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) { - *dest = 1; + } else if (cap) { + return zend_parse_arg_long_cap_slow(arg, dest); } else { - return 0; + return zend_parse_arg_long_slow(arg, dest); } return 1; } -static zend_always_inline int zend_parse_arg_double(zval *arg, double *dest, zend_bool *is_null, int check_null, zend_bool strict) +static zend_always_inline int zend_parse_arg_double(zval *arg, double *dest, zend_bool *is_null, int check_null) { if (check_null) { *is_null = 0; @@ -1144,61 +1104,31 @@ static zend_always_inline int zend_parse_arg_double(zval *arg, double *dest, zen if (EXPECTED(Z_TYPE_P(arg) == IS_DOUBLE)) { *dest = Z_DVAL_P(arg); } else if (check_null && Z_TYPE_P(arg) == IS_NULL) { - *is_null = 0; - *dest = 0.0; - } else if (EXPECTED(Z_TYPE_P(arg) == IS_LONG)) { - /* SSTH Exception: IS_LONG ma be accepted instead as IS_DOUBLE */ - *dest = (double)Z_LVAL_P(arg); - } else if (UNEXPECTED(strict)) { - return 0; - } else if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) { - zend_long l; - int type; - - if (UNEXPECTED((type = is_numeric_str_function(Z_STR_P(arg), &l, dest)) != IS_DOUBLE)) { - if (EXPECTED(type != 0)) { - *dest = (double)(l); - } else { - return 0; - } - } - } else if (EXPECTED(Z_TYPE_P(arg) < IS_TRUE)) { + *is_null = 1; *dest = 0.0; - } else if (EXPECTED(Z_TYPE_P(arg) == IS_TRUE)) { - *dest = 1.0; } else { - return 0; + return zend_parse_arg_double_slow(arg, dest); } return 1; } -static zend_always_inline int zend_parse_arg_str(zval *arg, zend_string **dest, int check_null, zend_bool strict) +static zend_always_inline int zend_parse_arg_str(zval *arg, zend_string **dest, int check_null) { if (EXPECTED(Z_TYPE_P(arg) == IS_STRING)) { *dest = Z_STR_P(arg); } else if (check_null && Z_TYPE_P(arg) == IS_NULL) { *dest = NULL; - } else if (UNEXPECTED(strict)) { - return 0; - } else if (EXPECTED(Z_TYPE_P(arg) < IS_STRING)) { - if (Z_COPYABLE_P(arg) && Z_REFCOUNT_P(arg) > 1) { - Z_DELREF_P(arg); - zval_copy_ctor_func(arg); - } - convert_to_string(arg); - *dest = Z_STR_P(arg); - } else if (UNEXPECTED(Z_TYPE_P(arg) != IS_OBJECT) || - UNEXPECTED(parse_arg_object_to_str(arg, dest, IS_STRING) != SUCCESS)) { - return 0; + } else { + return zend_parse_arg_str_slow(arg, dest); } return 1; } -static zend_always_inline int zend_parse_arg_string(zval *arg, char **dest, size_t *dest_len, int check_null, zend_bool strict) +static zend_always_inline int zend_parse_arg_string(zval *arg, char **dest, size_t *dest_len, int check_null) { zend_string *str; - if (!zend_parse_arg_str(arg, &str, check_null, strict)) { + if (!zend_parse_arg_str(arg, &str, check_null)) { return 0; } if (check_null && UNEXPECTED(!str)) { @@ -1211,20 +1141,20 @@ static zend_always_inline int zend_parse_arg_string(zval *arg, char **dest, size return 1; } -static zend_always_inline int zend_parse_arg_path_str(zval *arg, zend_string **dest, int check_null, zend_bool strict) +static zend_always_inline int zend_parse_arg_path_str(zval *arg, zend_string **dest, int check_null) { - if (!zend_parse_arg_str(arg, dest, check_null, strict) || + if (!zend_parse_arg_str(arg, dest, check_null) || (*dest && UNEXPECTED(CHECK_NULL_PATH((*dest)->val, (*dest)->len)))) { return 0; } return 1; } -static zend_always_inline int zend_parse_arg_path(zval *arg, char **dest, size_t *dest_len, int check_null, zend_bool strict) +static zend_always_inline int zend_parse_arg_path(zval *arg, char **dest, size_t *dest_len, int check_null) { zend_string *str; - if (!zend_parse_arg_path_str(arg, &str, check_null, strict)) { + if (!zend_parse_arg_path_str(arg, &str, check_null)) { return 0; } if (check_null && UNEXPECTED(!str)) { diff --git a/Zend/zend_execute.c b/Zend/zend_execute.c index 41c211c702..0fe2a26e97 100644 --- a/Zend/zend_execute.c +++ b/Zend/zend_execute.c @@ -653,13 +653,11 @@ static int is_null_constant(zval *default_value) static zend_bool zend_verify_weak_scalar_type_hint(zend_uchar type_hint, zval *arg) { - zend_bool strict = 0; - switch (type_hint) { case _IS_BOOL: { zend_bool dest; - if (!zend_parse_arg_bool(arg, &dest, NULL, 0, strict)) { + if (!zend_parse_arg_bool_weak(arg, &dest)) { return 0; } zval_ptr_dtor(arg); @@ -669,7 +667,7 @@ static zend_bool zend_verify_weak_scalar_type_hint(zend_uchar type_hint, zval *a case IS_LONG: { zend_long dest; - if (!zend_parse_arg_long(arg, &dest, NULL, 0, 0, strict)) { + if (!zend_parse_arg_long_weak(arg, &dest)) { return 0; } zval_ptr_dtor(arg); @@ -679,7 +677,7 @@ static zend_bool zend_verify_weak_scalar_type_hint(zend_uchar type_hint, zval *a case IS_DOUBLE: { double dest; - if (!zend_parse_arg_double(arg, &dest, NULL, 0, strict)) { + if (!zend_parse_arg_double_weak(arg, &dest)) { return 0; } zval_ptr_dtor(arg); @@ -690,7 +688,7 @@ static zend_bool zend_verify_weak_scalar_type_hint(zend_uchar type_hint, zval *a zend_string *dest; /* on success "arg" is converted to IS_STRING */ - if (!zend_parse_arg_str(arg, &dest, 0, strict)) { + if (!zend_parse_arg_str_weak(arg, &dest)) { return 0; } return 1; @@ -703,7 +701,7 @@ static zend_bool zend_verify_weak_scalar_type_hint(zend_uchar type_hint, zval *a static zend_bool zend_verify_scalar_type_hint(zend_uchar type_hint, zval *arg, zend_bool strict) { if (UNEXPECTED(strict)) { - /* SSTH Exception: IS_LONG ma be accepted as IS_DOUBLE (converted) */ + /* SSTH Exception: IS_LONG may be accepted as IS_DOUBLE (converted) */ if (type_hint != IS_DOUBLE || Z_TYPE_P(arg) != IS_LONG) { return 0; } diff --git a/Zend/zend_vm_def.h b/Zend/zend_vm_def.h index 9065221b39..c448c299c2 100644 --- a/Zend/zend_vm_def.h +++ b/Zend/zend_vm_def.h @@ -7281,28 +7281,16 @@ ZEND_VM_C_LABEL(try_strlen): strict = EX_USES_STRICT_TYPES(); do { if (EXPECTED(!strict)) { - if (Z_TYPE_P(value) < IS_TRUE) { - ZVAL_LONG(EX_VAR(opline->result.var), 0); - break; - } else if (Z_TYPE_P(value) == IS_TRUE) { - ZVAL_LONG(EX_VAR(opline->result.var), 1); - break; - } else if (Z_TYPE_P(value) <= IS_DOUBLE) { - zend_string *str = zval_get_string(value); + zend_string *str; + zval tmp; + + ZVAL_COPY(&tmp, value); + if (zend_parse_arg_str_weak(&tmp, &str)) { ZVAL_LONG(EX_VAR(opline->result.var), str->len); - zend_string_release(str); + zval_ptr_dtor(&tmp); break; - } else if (Z_TYPE_P(value) == IS_OBJECT) { - zend_string *str; - zval tmp; - - ZVAL_COPY(&tmp, value); - if (parse_arg_object_to_str(&tmp, &str, IS_STRING) == SUCCESS) { - ZVAL_LONG(EX_VAR(opline->result.var), str->len); - zval_dtor(&tmp); - break; - } } + zval_ptr_dtor(&tmp); } zend_internal_type_error(strict, "strlen() expects parameter 1 to be string, %s given", zend_get_type_by_const(Z_TYPE_P(value))); ZVAL_NULL(EX_VAR(opline->result.var)); diff --git a/Zend/zend_vm_execute.h b/Zend/zend_vm_execute.h index df01a3bb4b..ea843faf84 100644 --- a/Zend/zend_vm_execute.h +++ b/Zend/zend_vm_execute.h @@ -3819,28 +3819,16 @@ try_strlen: strict = EX_USES_STRICT_TYPES(); do { if (EXPECTED(!strict)) { - if (Z_TYPE_P(value) < IS_TRUE) { - ZVAL_LONG(EX_VAR(opline->result.var), 0); - break; - } else if (Z_TYPE_P(value) == IS_TRUE) { - ZVAL_LONG(EX_VAR(opline->result.var), 1); - break; - } else if (Z_TYPE_P(value) <= IS_DOUBLE) { - zend_string *str = zval_get_string(value); + zend_string *str; + zval tmp; + + ZVAL_COPY(&tmp, value); + if (zend_parse_arg_str_weak(&tmp, &str)) { ZVAL_LONG(EX_VAR(opline->result.var), str->len); - zend_string_release(str); + zval_ptr_dtor(&tmp); break; - } else if (Z_TYPE_P(value) == IS_OBJECT) { - zend_string *str; - zval tmp; - - ZVAL_COPY(&tmp, value); - if (parse_arg_object_to_str(&tmp, &str, IS_STRING) == SUCCESS) { - ZVAL_LONG(EX_VAR(opline->result.var), str->len); - zval_dtor(&tmp); - break; - } } + zval_ptr_dtor(&tmp); } zend_internal_type_error(strict, "strlen() expects parameter 1 to be string, %s given", zend_get_type_by_const(Z_TYPE_P(value))); ZVAL_NULL(EX_VAR(opline->result.var)); @@ -27353,28 +27341,16 @@ try_strlen: strict = EX_USES_STRICT_TYPES(); do { if (EXPECTED(!strict)) { - if (Z_TYPE_P(value) < IS_TRUE) { - ZVAL_LONG(EX_VAR(opline->result.var), 0); - break; - } else if (Z_TYPE_P(value) == IS_TRUE) { - ZVAL_LONG(EX_VAR(opline->result.var), 1); - break; - } else if (Z_TYPE_P(value) <= IS_DOUBLE) { - zend_string *str = zval_get_string(value); + zend_string *str; + zval tmp; + + ZVAL_COPY(&tmp, value); + if (zend_parse_arg_str_weak(&tmp, &str)) { ZVAL_LONG(EX_VAR(opline->result.var), str->len); - zend_string_release(str); + zval_ptr_dtor(&tmp); break; - } else if (Z_TYPE_P(value) == IS_OBJECT) { - zend_string *str; - zval tmp; - - ZVAL_COPY(&tmp, value); - if (parse_arg_object_to_str(&tmp, &str, IS_STRING) == SUCCESS) { - ZVAL_LONG(EX_VAR(opline->result.var), str->len); - zval_dtor(&tmp); - break; - } } + zval_ptr_dtor(&tmp); } zend_internal_type_error(strict, "strlen() expects parameter 1 to be string, %s given", zend_get_type_by_const(Z_TYPE_P(value))); ZVAL_NULL(EX_VAR(opline->result.var)); @@ -37631,28 +37607,16 @@ try_strlen: strict = EX_USES_STRICT_TYPES(); do { if (EXPECTED(!strict)) { - if (Z_TYPE_P(value) < IS_TRUE) { - ZVAL_LONG(EX_VAR(opline->result.var), 0); - break; - } else if (Z_TYPE_P(value) == IS_TRUE) { - ZVAL_LONG(EX_VAR(opline->result.var), 1); - break; - } else if (Z_TYPE_P(value) <= IS_DOUBLE) { - zend_string *str = zval_get_string(value); + zend_string *str; + zval tmp; + + ZVAL_COPY(&tmp, value); + if (zend_parse_arg_str_weak(&tmp, &str)) { ZVAL_LONG(EX_VAR(opline->result.var), str->len); - zend_string_release(str); + zval_ptr_dtor(&tmp); break; - } else if (Z_TYPE_P(value) == IS_OBJECT) { - zend_string *str; - zval tmp; - - ZVAL_COPY(&tmp, value); - if (parse_arg_object_to_str(&tmp, &str, IS_STRING) == SUCCESS) { - ZVAL_LONG(EX_VAR(opline->result.var), str->len); - zval_dtor(&tmp); - break; - } } + zval_ptr_dtor(&tmp); } zend_internal_type_error(strict, "strlen() expects parameter 1 to be string, %s given", zend_get_type_by_const(Z_TYPE_P(value))); ZVAL_NULL(EX_VAR(opline->result.var)); -- 2.40.0