]> granicus.if.org Git - php/commitdiff
Improved ZPP to reduce amount of generated code.
authorDmitry Stogov <dmitry@zend.com>
Fri, 16 Feb 2018 08:37:20 +0000 (11:37 +0300)
committerDmitry Stogov <dmitry@zend.com>
Fri, 16 Feb 2018 08:37:20 +0000 (11:37 +0300)
Zend/zend_API.c
Zend/zend_API.h

index a2638f6f027fb326925449064d6ddf759385b1fc..ca68310bc96858376a10a87caf3cda872b999df1 100644 (file)
@@ -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);
 }
 /* }}} */
index 1db7aef5ae35aacebc3b9eb8eb1eb2f9ce065a3f..17308e3ae8611c522de38dee5d6dbd51ecdfe80f 100644 (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) \