Improved ZPP to reduce amount of generated code.

This commit is contained in:
Dmitry Stogov 2018-02-16 11:37:20 +03:00
parent 6fadb72c0b
commit 7e329a82c7
2 changed files with 154 additions and 31 deletions

View File

@ -171,13 +171,54 @@ 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] ? "::" : "", \
@ -189,7 +230,26 @@ 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_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] ? "::" : "", \
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_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_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(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, 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);
}
/* }}} */

View File

@ -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) \