From: Dmitry Stogov Date: Fri, 16 Feb 2018 08:37:20 +0000 (+0300) Subject: Improved ZPP to reduce amount of generated code. X-Git-Tag: php-7.3.0alpha1~412 X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=7e329a82c7b102ca1c2e247e3ebf058383c5d6f2;p=php Improved ZPP to reduce amount of generated code. --- diff --git a/Zend/zend_API.c b/Zend/zend_API.c index a2638f6f02..ca68310bc9 100644 --- a/Zend/zend_API.c +++ b/Zend/zend_API.c @@ -171,13 +171,73 @@ ZEND_API zend_string *zend_zval_get_type(const zval *arg) /* {{{ */ } /* }}} */ -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_error(zend_bool throw_, int num_args, int min_num_args, int max_num_args) /* {{{ */ +ZEND_API ZEND_COLD int ZEND_FASTCALL zend_wrong_parameters_none_error(void) /* {{{ */ { + int num_args = ZEND_CALL_NUM_ARGS(EG(current_execute_data)); zend_function *active_function = EG(current_execute_data)->func; const char *class_name = active_function->common.scope ? ZSTR_VAL(active_function->common.scope->name) : ""; zend_internal_argument_count_error( - throw_ || ZEND_ARG_USES_STRICT_TYPES(), + ZEND_ARG_USES_STRICT_TYPES(), + "%s%s%s() expects %s %d parameter%s, %d given", + class_name, \ + class_name[0] ? "::" : "", \ + ZSTR_VAL(active_function->common.function_name), + "exactly", + 0, + "s", + num_args); + return FAILURE; +} +/* }}} */ + +ZEND_API ZEND_COLD int ZEND_FASTCALL zend_wrong_parameters_none_exception(void) /* {{{ */ +{ + int num_args = ZEND_CALL_NUM_ARGS(EG(current_execute_data)); + zend_function *active_function = EG(current_execute_data)->func; + const char *class_name = active_function->common.scope ? ZSTR_VAL(active_function->common.scope->name) : ""; + + zend_internal_argument_count_error( + 1, + "%s%s%s() expects %s %d parameter%s, %d given", + class_name, \ + class_name[0] ? "::" : "", \ + ZSTR_VAL(active_function->common.function_name), + "exactly", + 0, + "s", + num_args); + return FAILURE; +} +/* }}} */ + +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_error(int min_num_args, int max_num_args) /* {{{ */ +{ + int num_args = ZEND_CALL_NUM_ARGS(EG(current_execute_data)); + zend_function *active_function = EG(current_execute_data)->func; + const char *class_name = active_function->common.scope ? ZSTR_VAL(active_function->common.scope->name) : ""; + + zend_internal_argument_count_error( + ZEND_ARG_USES_STRICT_TYPES(), + "%s%s%s() expects %s %d parameter%s, %d given", + class_name, \ + class_name[0] ? "::" : "", \ + ZSTR_VAL(active_function->common.function_name), + min_num_args == max_num_args ? "exactly" : num_args < min_num_args ? "at least" : "at most", + num_args < min_num_args ? min_num_args : max_num_args, + (num_args < min_num_args ? min_num_args : max_num_args) == 1 ? "" : "s", + num_args); +} +/* }}} */ + +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_exception(int min_num_args, int max_num_args) /* {{{ */ +{ + int num_args = ZEND_CALL_NUM_ARGS(EG(current_execute_data)); + zend_function *active_function = EG(current_execute_data)->func; + const char *class_name = active_function->common.scope ? ZSTR_VAL(active_function->common.scope->name) : ""; + + zend_internal_argument_count_error( + 1, "%s%s%s() expects %s %d parameter%s, %d given", class_name, \ class_name[0] ? "::" : "", \ @@ -189,7 +249,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_error(zend_boo } /* }}} */ -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(zend_bool throw_, int num, zend_expected_type expected_type, zval *arg) /* {{{ */ +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(int num, zend_expected_type expected_type, zval *arg) /* {{{ */ { const char *space; const char *class_name = get_active_class_name(&space); @@ -198,36 +258,74 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(zend_bool NULL }; - zend_internal_type_error(throw_ || ZEND_ARG_USES_STRICT_TYPES(), "%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 ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(zend_bool throw_, int num, char *name, zval *arg) /* {{{ */ +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_exception(int num, zend_expected_type expected_type, zval *arg) /* {{{ */ { const char *space; const char *class_name = get_active_class_name(&space); + static const char * const expected_error[] = { + Z_EXPECTED_TYPES(Z_EXPECTED_TYPE_STR) + NULL + }; + + zend_internal_type_error(1, "%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_internal_type_error(throw_ || ZEND_ARG_USES_STRICT_TYPES(), "%s%s%s() expects parameter %d to be %s, %s given", +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(int num, char *name, zval *arg) /* {{{ */ +{ + const char *space; + const char *class_name = get_active_class_name(&space); + + 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 ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(zend_bool throw_, int severity, int num, char *error) /* {{{ */ +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_exception(int num, char *name, zval *arg) /* {{{ */ { const char *space; const char *class_name = get_active_class_name(&space); - if (severity == E_WARNING) { - zend_internal_type_error(throw_ || 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 if (severity == E_ERROR) { - zend_throw_error(zend_ce_type_error, "%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", - class_name, space, get_active_function_name(), num, error); - } + zend_internal_type_error(1, "%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 ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(int num, char *error) /* {{{ */ +{ + const char *space; + const char *class_name = get_active_class_name(&space); + + 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); + efree(error); +} +/* }}} */ + +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_exception(int num, char *error) /* {{{ */ +{ + const char *space; + const char *class_name = get_active_class_name(&space); + + zend_internal_type_error(1, "%s%s%s() expects parameter %d to be a valid callback, %s", + class_name, space, get_active_function_name(), num, error); + efree(error); +} +/* }}} */ + +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_deprecated(int num, char *error) /* {{{ */ +{ + const char *space; + const char *class_name = get_active_class_name(&space); + + zend_error(E_DEPRECATED, "%s%s%s() expects parameter %d to be a valid callback, %s", + class_name, space, get_active_function_name(), num, error); efree(error); } /* }}} */ diff --git a/Zend/zend_API.h b/Zend/zend_API.h index 1db7aef5ae..17308e3ae8 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -262,9 +262,9 @@ ZEND_API int zend_copy_parameters_array(int param_count, zval *argument_array); #define zend_get_parameters_array_ex(param_count, argument_array) \ _zend_get_parameters_array_ex(param_count, argument_array) #define zend_parse_parameters_none() \ - (EXPECTED(ZEND_NUM_ARGS() == 0) ? SUCCESS : zend_parse_parameters(ZEND_NUM_ARGS(), "")) + (EXPECTED(ZEND_NUM_ARGS() == 0) ? SUCCESS : zend_wrong_parameters_none_error()) #define zend_parse_parameters_none_throw() \ - (EXPECTED(ZEND_NUM_ARGS() == 0) ? SUCCESS : zend_parse_parameters_throw(ZEND_NUM_ARGS(), "")) + (EXPECTED(ZEND_NUM_ARGS() == 0) ? SUCCESS : zend_wrong_parameters_none_exception()) /* Parameter parsing API -- andrei */ @@ -708,10 +708,17 @@ typedef enum _zend_expected_type { Z_EXPECTED_LAST } zend_expected_type; -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_error(zend_bool throw_, int num_args, int min_num_args, int max_num_args); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(zend_bool throw_, int num, zend_expected_type expected_type, zval *arg); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(zend_bool throw_, int num, char *name, zval *arg); -ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(zend_bool throw_, int severity, int num, char *error); +ZEND_API ZEND_COLD int ZEND_FASTCALL zend_wrong_parameters_none_error(void); +ZEND_API ZEND_COLD int ZEND_FASTCALL zend_wrong_parameters_none_exception(void); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_error(int min_num_args, int max_num_args); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameters_count_exception(int min_num_args, int max_num_args); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_error(int num, zend_expected_type expected_type, zval *arg); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_type_exception(int num, zend_expected_type expected_type, zval *arg); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_error(int num, char *name, zval *arg); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_parameter_class_exception(int num, char *name, zval *arg); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(int num, char *error); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_deprecated(int num, char *error); +ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_exception(int num, char *error); #define ZPP_ERROR_OK 0 #define ZPP_ERROR_FAILURE 1 @@ -745,7 +752,11 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(zend_bool throw_ (UNEXPECTED(_num_args > _max_num_args) && \ EXPECTED(_max_num_args >= 0))) { \ if (!(_flags & ZEND_PARSE_PARAMS_QUIET)) { \ - zend_wrong_parameters_count_error(_flags & ZEND_PARSE_PARAMS_THROW, _num_args, _min_num_args, _max_num_args); \ + if (_flags & ZEND_PARSE_PARAMS_THROW) { \ + zend_wrong_parameters_count_exception(_min_num_args, _max_num_args); \ + } else { \ + zend_wrong_parameters_count_error(_min_num_args, _max_num_args); \ + } \ } \ error_code = ZPP_ERROR_FAILURE; \ break; \ @@ -756,20 +767,34 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(zend_bool throw_ #define ZEND_PARSE_PARAMETERS_START(min_num_args, max_num_args) \ ZEND_PARSE_PARAMETERS_START_EX(0, min_num_args, max_num_args) -#define ZEND_PARSE_PARAMETERS_NONE() \ - ZEND_PARSE_PARAMETERS_START(0, 0) \ - ZEND_PARSE_PARAMETERS_END() +#define ZEND_PARSE_PARAMETERS_NONE() do { \ + if (UNEXPECTED(ZEND_NUM_ARGS() != 0)) { \ + zend_wrong_parameters_none_error(); \ + } \ + } while (0) #define ZEND_PARSE_PARAMETERS_END_EX(failure) \ } while (0); \ if (UNEXPECTED(error_code != ZPP_ERROR_OK)) { \ if (!(_flags & ZEND_PARSE_PARAMS_QUIET)) { \ if (error_code == ZPP_ERROR_WRONG_CALLBACK) { \ - zend_wrong_callback_error(_flags & ZEND_PARSE_PARAMS_THROW, E_WARNING, _i, _error); \ + if (_flags & ZEND_PARSE_PARAMS_THROW) { \ + zend_wrong_callback_exception(_i, _error); \ + } else { \ + zend_wrong_callback_error(_i, _error); \ + } \ } else if (error_code == ZPP_ERROR_WRONG_CLASS) { \ - zend_wrong_parameter_class_error(_flags & ZEND_PARSE_PARAMS_THROW, _i, _error, _arg); \ + if (_flags & ZEND_PARSE_PARAMS_THROW) { \ + zend_wrong_parameter_class_exception(_i, _error, _arg); \ + } else { \ + zend_wrong_parameter_class_error(_i, _error, _arg); \ + } \ } else if (error_code == ZPP_ERROR_WRONG_ARG) { \ - zend_wrong_parameter_type_error(_flags & ZEND_PARSE_PARAMS_THROW, _i, _expected_type, _arg); \ + if (_flags & ZEND_PARSE_PARAMS_THROW) { \ + zend_wrong_parameter_type_exception(_i, _expected_type, _arg); \ + } else { \ + zend_wrong_parameter_type_error(_i, _expected_type, _arg); \ + } \ } \ } \ failure; \ @@ -886,7 +911,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(zend_bool throw_ break; \ } \ } else if (UNEXPECTED(_error != NULL)) { \ - zend_wrong_callback_error(_flags & ZEND_PARSE_PARAMS_THROW, E_DEPRECATED, _i, _error); \ + zend_wrong_callback_deprecated(_i, _error); \ } #define Z_PARAM_FUNC_EX(dest_fci, dest_fcc, check_null, separate) \