diff options
author | Dmitry Stogov <dmitry@zend.com> | 2017-06-08 13:03:24 +0300 |
---|---|---|
committer | Dmitry Stogov <dmitry@zend.com> | 2017-06-08 13:03:24 +0300 |
commit | ace9fe53173974ec63f9e0357a6e8372ff5adb3b (patch) | |
tree | bdc5bb54c7d989225e307dff1f6aa7f462c62de4 /Zend/zend_API.h | |
parent | bdc37442bf303e2453e3f86388a0c5b88bfd70fd (diff) | |
download | php-git-ace9fe53173974ec63f9e0357a6e8372ff5adb3b.tar.gz |
Improved new Zend Parameter Parsing API to avoid useless dereferences.
This derefernce made sense only for explicit paramter passing by reference, but this feature was removed in PHP-7.
The improvement is 100% backward compatible, only few "tricky" functions may be affected (e.g. extract and usort).
Diffstat (limited to 'Zend/zend_API.h')
-rw-r--r-- | Zend/zend_API.h | 143 |
1 files changed, 95 insertions, 48 deletions
diff --git a/Zend/zend_API.h b/Zend/zend_API.h index fe6e1481ef..69f4d56b62 100644 --- a/Zend/zend_API.h +++ b/Zend/zend_API.h @@ -779,7 +779,7 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(zend_bool throw_ #define ZEND_PARSE_PARAMETERS_END() \ ZEND_PARSE_PARAMETERS_END_EX(return) -#define Z_PARAM_PROLOGUE(separate) \ +#define Z_PARAM_PROLOGUE(deref, separate) \ ++_i; \ ZEND_ASSERT(_i <= _min_num_args || _optional==1); \ ZEND_ASSERT(_i > _min_num_args || _optional==0); \ @@ -788,7 +788,9 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(zend_bool throw_ } \ _real_arg++; \ _arg = _real_arg; \ - ZVAL_DEREF(_arg); \ + if (deref) { \ + ZVAL_DEREF(_arg); \ + } \ if (separate) { \ SEPARATE_ZVAL_NOREF(_arg); \ } @@ -798,67 +800,82 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(zend_bool throw_ _optional = 1; /* old "a" */ -#define Z_PARAM_ARRAY_EX(dest, check_null, separate) \ - Z_PARAM_PROLOGUE(separate); \ +#define Z_PARAM_ARRAY_EX2(dest, check_null, deref, separate) \ + Z_PARAM_PROLOGUE(deref, separate); \ if (UNEXPECTED(!zend_parse_arg_array(_arg, &dest, check_null, 0))) { \ _expected_type = Z_EXPECTED_ARRAY; \ error_code = ZPP_ERROR_WRONG_ARG; \ break; \ } +#define Z_PARAM_ARRAY_EX(dest, check_null, separate) \ + Z_PARAM_ARRAY_EX2(dest, check_null, separate, separate) + #define Z_PARAM_ARRAY(dest) \ Z_PARAM_ARRAY_EX(dest, 0, 0) /* old "A" */ -#define Z_PARAM_ARRAY_OR_OBJECT_EX(dest, check_null, separate) \ - Z_PARAM_PROLOGUE(separate); \ +#define Z_PARAM_ARRAY_OR_OBJECT_EX2(dest, check_null, deref, separate) \ + Z_PARAM_PROLOGUE(deref, separate); \ if (UNEXPECTED(!zend_parse_arg_array(_arg, &dest, check_null, 1))) { \ _expected_type = Z_EXPECTED_ARRAY; \ error_code = ZPP_ERROR_WRONG_ARG; \ break; \ } +#define Z_PARAM_ARRAY_OR_OBJECT_EX(dest, check_null, separate) \ + Z_PARAM_ARRAY_OR_OBJECT_EX2(dest, check_null, separate, separate) + #define Z_PARAM_ARRAY_OR_OBJECT(dest, check_null, separate) \ Z_PARAM_ARRAY_OR_OBJECT_EX(dest, 0, 0) /* old "b" */ -#define Z_PARAM_BOOL_EX(dest, is_null, check_null, separate) \ - Z_PARAM_PROLOGUE(separate); \ +#define Z_PARAM_BOOL_EX2(dest, is_null, check_null, deref, separate) \ + Z_PARAM_PROLOGUE(deref, separate); \ if (UNEXPECTED(!zend_parse_arg_bool(_arg, &dest, &is_null, check_null))) { \ _expected_type = Z_EXPECTED_BOOL; \ error_code = ZPP_ERROR_WRONG_ARG; \ break; \ } +#define Z_PARAM_BOOL_EX(dest, is_null, check_null, separate) \ + Z_PARAM_BOOL_EX2(dest, is_null, check_null, separate, separate) + #define Z_PARAM_BOOL(dest) \ Z_PARAM_BOOL_EX(dest, _dummy, 0, 0) /* old "C" */ -#define Z_PARAM_CLASS_EX(dest, check_null, separate) \ - Z_PARAM_PROLOGUE(separate); \ +#define Z_PARAM_CLASS_EX2(dest, check_null, deref, separate) \ + Z_PARAM_PROLOGUE(deref, separate); \ if (UNEXPECTED(!zend_parse_arg_class(_arg, &dest, _i, check_null))) { \ error_code = ZPP_ERROR_FAILURE; \ break; \ } +#define Z_PARAM_CLASS_EX(dest, check_null, separate) \ + Z_PARAM_CLASS_EX2(dest, check_null, separate, separate) + #define Z_PARAM_CLASS(dest) \ Z_PARAM_CLASS_EX(dest, 0, 0) /* old "d" */ -#define Z_PARAM_DOUBLE_EX(dest, is_null, check_null, separate) \ - Z_PARAM_PROLOGUE(separate); \ +#define Z_PARAM_DOUBLE_EX2(dest, is_null, check_null, deref, separate) \ + Z_PARAM_PROLOGUE(deref, separate); \ if (UNEXPECTED(!zend_parse_arg_double(_arg, &dest, &is_null, check_null))) { \ _expected_type = Z_EXPECTED_DOUBLE; \ error_code = ZPP_ERROR_WRONG_ARG; \ break; \ } +#define Z_PARAM_DOUBLE_EX(dest, is_null, check_null, separate) \ + Z_PARAM_DOUBLE_EX2(dest, is_null, check_null, separate, separate) + #define Z_PARAM_DOUBLE(dest) \ Z_PARAM_DOUBLE_EX(dest, _dummy, 0, 0) /* old "f" */ -#define Z_PARAM_FUNC_EX(dest_fci, dest_fcc, check_null, separate) \ - Z_PARAM_PROLOGUE(separate); \ +#define Z_PARAM_FUNC_EX2(dest_fci, dest_fcc, check_null, deref, separate) \ + Z_PARAM_PROLOGUE(deref, separate); \ if (UNEXPECTED(!zend_parse_arg_func(_arg, &dest_fci, &dest_fcc, check_null, &_error))) { \ if (!_error) { \ _expected_type = Z_EXPECTED_FUNC; \ @@ -872,72 +889,90 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(zend_bool throw_ zend_wrong_callback_error(_flags & ZEND_PARSE_PARAMS_THROW, E_DEPRECATED, _i, _error); \ } +#define Z_PARAM_FUNC_EX(dest_fci, dest_fcc, check_null, separate) \ + Z_PARAM_FUNC_EX2(dest_fci, dest_fcc, check_null, separate, separate) + #define Z_PARAM_FUNC(dest_fci, dest_fcc) \ Z_PARAM_FUNC_EX(dest_fci, dest_fcc, 0, 0) /* old "h" */ -#define Z_PARAM_ARRAY_HT_EX(dest, check_null, separate) \ - Z_PARAM_PROLOGUE(separate); \ +#define Z_PARAM_ARRAY_HT_EX2(dest, check_null, deref, separate) \ + Z_PARAM_PROLOGUE(deref, separate); \ if (UNEXPECTED(!zend_parse_arg_array_ht(_arg, &dest, check_null, 0, separate))) { \ _expected_type = Z_EXPECTED_ARRAY; \ error_code = ZPP_ERROR_WRONG_ARG; \ break; \ } +#define Z_PARAM_ARRAY_HT_EX(dest, check_null, separate) \ + Z_PARAM_ARRAY_HT_EX2(dest, check_null, separate, separate) + #define Z_PARAM_ARRAY_HT(dest) \ Z_PARAM_ARRAY_HT_EX(dest, 0, 0) /* old "H" */ -#define Z_PARAM_ARRAY_OR_OBJECT_HT_EX(dest, check_null, separate) \ - Z_PARAM_PROLOGUE(separate); \ +#define Z_PARAM_ARRAY_OR_OBJECT_HT_EX2(dest, check_null, deref, separate) \ + Z_PARAM_PROLOGUE(deref, separate); \ if (UNEXPECTED(!zend_parse_arg_array_ht(_arg, &dest, check_null, 1, separate))) { \ _expected_type = Z_EXPECTED_ARRAY; \ error_code = ZPP_ERROR_WRONG_ARG; \ break; \ } +#define Z_PARAM_ARRAY_OR_OBJECT_HT_EX(dest, check_null, separate) \ + Z_PARAM_ARRAY_OR_OBJECT_HT_EX2(dest, check_null, separate, separate) + #define Z_PARAM_ARRAY_OR_OBJECT_HT(dest) \ Z_PARAM_ARRAY_OR_OBJECT_HT_EX(dest, 0, 0) /* old "l" */ -#define Z_PARAM_LONG_EX(dest, is_null, check_null, separate) \ - Z_PARAM_PROLOGUE(separate); \ +#define Z_PARAM_LONG_EX2(dest, is_null, check_null, deref, separate) \ + Z_PARAM_PROLOGUE(deref, separate); \ 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; \ } +#define Z_PARAM_LONG_EX(dest, is_null, check_null, separate) \ + Z_PARAM_LONG_EX2(dest, is_null, check_null, separate, separate) + #define Z_PARAM_LONG(dest) \ Z_PARAM_LONG_EX(dest, _dummy, 0, 0) /* old "L" */ -#define Z_PARAM_STRICT_LONG_EX(dest, is_null, check_null, separate) \ - Z_PARAM_PROLOGUE(separate); \ +#define Z_PARAM_STRICT_LONG_EX2(dest, is_null, check_null, deref, separate) \ + Z_PARAM_PROLOGUE(deref, separate); \ 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; \ } +#define Z_PARAM_STRICT_LONG_EX(dest, is_null, check_null, separate) \ + Z_PARAM_STRICT_LONG_EX2(dest, is_null, check_null, separate, separate) + #define Z_PARAM_STRICT_LONG(dest) \ Z_PARAM_STRICT_LONG_EX(dest, _dummy, 0, 0) /* old "o" */ -#define Z_PARAM_OBJECT_EX(dest, check_null, separate) \ - Z_PARAM_PROLOGUE(separate); \ +#define Z_PARAM_OBJECT_EX2(dest, check_null, deref, separate) \ + Z_PARAM_PROLOGUE(deref, separate); \ if (UNEXPECTED(!zend_parse_arg_object(_arg, &dest, NULL, check_null))) { \ _expected_type = Z_EXPECTED_OBJECT; \ error_code = ZPP_ERROR_WRONG_ARG; \ break; \ } +#define Z_PARAM_OBJECT_EX(dest, check_null, separate) \ + Z_PARAM_OBJECT_EX2(dest, check_null, separate, separate) + #define Z_PARAM_OBJECT(dest) \ Z_PARAM_OBJECT_EX(dest, 0, 0) /* old "O" */ -#define Z_PARAM_OBJECT_OF_CLASS_EX(dest, _ce, check_null, separate) \ - Z_PARAM_PROLOGUE(separate); \ +#define Z_PARAM_OBJECT_OF_CLASS_EX2(dest, _ce, check_null, deref, separate) \ + Z_PARAM_PROLOGUE(deref, separate); \ if (UNEXPECTED(!zend_parse_arg_object(_arg, &dest, _ce, check_null))) { \ if (_ce) { \ _error = ZSTR_VAL((_ce)->name); \ @@ -950,89 +985,101 @@ ZEND_API ZEND_COLD void ZEND_FASTCALL zend_wrong_callback_error(zend_bool throw_ } \ } +#define Z_PARAM_OBJECT_OF_CLASS_EX(dest, _ce, check_null, separate) \ + Z_PARAM_OBJECT_OF_CLASS_EX2(dest, _ce, check_null, separate, separate) + #define Z_PARAM_OBJECT_OF_CLASS(dest, _ce) \ Z_PARAM_OBJECT_OF_CLASS_EX(dest, _ce, 0, 0) /* old "p" */ -#define Z_PARAM_PATH_EX(dest, dest_len, check_null, separate) \ - Z_PARAM_PROLOGUE(separate); \ +#define Z_PARAM_PATH_EX2(dest, dest_len, check_null, deref, separate) \ + Z_PARAM_PROLOGUE(deref, separate); \ if (UNEXPECTED(!zend_parse_arg_path(_arg, &dest, &dest_len, check_null))) { \ _expected_type = Z_EXPECTED_PATH; \ error_code = ZPP_ERROR_WRONG_ARG; \ break; \ } +#define Z_PARAM_PATH_EX(dest, dest_len, check_null, separate) \ + Z_PARAM_PATH_EX2(dest, dest_len, check_null, separate, separate) + #define Z_PARAM_PATH(dest, dest_len) \ Z_PARAM_PATH_EX(dest, dest_len, 0, 0) /* old "P" */ -#define Z_PARAM_PATH_STR_EX(dest, check_null, separate) \ - Z_PARAM_PROLOGUE(separate); \ +#define Z_PARAM_PATH_STR_EX2(dest, check_null, deref, separate) \ + Z_PARAM_PROLOGUE(deref, separate); \ if (UNEXPECTED(!zend_parse_arg_path_str(_arg, &dest, check_null))) { \ _expected_type = Z_EXPECTED_PATH; \ error_code = ZPP_ERROR_WRONG_ARG; \ break; \ } +#define Z_PARAM_PATH_STR_EX(dest, check_null, separate) \ + Z_PARAM_PATH_STR_EX2(dest, check_null, separate, separate) + #define Z_PARAM_PATH_STR(dest) \ Z_PARAM_PATH_STR_EX(dest, 0, 0) /* old "r" */ -#define Z_PARAM_RESOURCE_EX(dest, check_null, separate) \ - Z_PARAM_PROLOGUE(separate); \ +#define Z_PARAM_RESOURCE_EX2(dest, check_null, deref, separate) \ + Z_PARAM_PROLOGUE(deref, separate); \ if (UNEXPECTED(!zend_parse_arg_resource(_arg, &dest, check_null))) { \ _expected_type = Z_EXPECTED_RESOURCE; \ error_code = ZPP_ERROR_WRONG_ARG; \ break; \ } +#define Z_PARAM_RESOURCE_EX(dest, check_null, separate) \ + Z_PARAM_RESOURCE_EX2(dest, check_null, separate, separate) + #define Z_PARAM_RESOURCE(dest) \ Z_PARAM_RESOURCE_EX(dest, 0, 0) /* old "s" */ -#define Z_PARAM_STRING_EX(dest, dest_len, check_null, separate) \ - Z_PARAM_PROLOGUE(separate); \ +#define Z_PARAM_STRING_EX2(dest, dest_len, check_null, deref, separate) \ + Z_PARAM_PROLOGUE(deref, separate); \ if (UNEXPECTED(!zend_parse_arg_string(_arg, &dest, &dest_len, check_null))) { \ _expected_type = Z_EXPECTED_STRING; \ error_code = ZPP_ERROR_WRONG_ARG; \ break; \ } +#define Z_PARAM_STRING_EX(dest, dest_len, check_null, separate) \ + Z_PARAM_STRING_EX2(dest, dest_len, check_null, separate, separate) + #define Z_PARAM_STRING(dest, dest_len) \ Z_PARAM_STRING_EX(dest, dest_len, 0, 0) /* old "S" */ -#define Z_PARAM_STR_EX(dest, check_null, separate) \ - Z_PARAM_PROLOGUE(separate); \ +#define Z_PARAM_STR_EX2(dest, check_null, deref, separate) \ + Z_PARAM_PROLOGUE(deref, separate); \ if (UNEXPECTED(!zend_parse_arg_str(_arg, &dest, check_null))) { \ _expected_type = Z_EXPECTED_STRING; \ error_code = ZPP_ERROR_WRONG_ARG; \ break; \ } +#define Z_PARAM_STR_EX(dest, check_null, separate) \ + Z_PARAM_STR_EX2(dest, check_null, separate, separate) + #define Z_PARAM_STR(dest) \ Z_PARAM_STR_EX(dest, 0, 0) /* old "z" */ +#define Z_PARAM_ZVAL_EX2(dest, check_null, deref, separate) \ + Z_PARAM_PROLOGUE(deref, separate); \ + zend_parse_arg_zval_deref(_arg, &dest, check_null); + #define Z_PARAM_ZVAL_EX(dest, check_null, separate) \ - if (separate) { \ - Z_PARAM_PROLOGUE(separate); \ - zend_parse_arg_zval_deref(_arg, &dest, check_null); \ - } else { \ - ++_i; \ - ZEND_ASSERT(_i <= _min_num_args || _optional==1); \ - ZEND_ASSERT(_i > _min_num_args || _optional==0); \ - if (_optional && UNEXPECTED(_i >_num_args)) break; \ - _real_arg++; \ - zend_parse_arg_zval(_real_arg, &dest, check_null); \ - } + Z_PARAM_ZVAL_EX2(dest, check_null, separate, separate) #define Z_PARAM_ZVAL(dest) \ Z_PARAM_ZVAL_EX(dest, 0, 0) /* old "z" (with dereference) */ #define Z_PARAM_ZVAL_DEREF_EX(dest, check_null, separate) \ - Z_PARAM_PROLOGUE(separate); \ + Z_PARAM_PROLOGUE(1, separate); \ zend_parse_arg_zval_deref(_arg, &dest, check_null); #define Z_PARAM_ZVAL_DEREF(dest) \ |