mirror of
https://github.com/php/php-src.git
synced 2025-08-16 05:58:45 +02:00
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).
This commit is contained in:
parent
bdc37442bf
commit
ace9fe5317
2 changed files with 97 additions and 50 deletions
143
Zend/zend_API.h
143
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) \
|
||||
|
|
|
@ -1035,7 +1035,7 @@ static void php_usort(INTERNAL_FUNCTION_PARAMETERS, compare_func_t compare_func,
|
|||
PHP_ARRAY_CMP_FUNC_BACKUP();
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(2, 2)
|
||||
Z_PARAM_ARRAY(array)
|
||||
Z_PARAM_ARRAY_EX2(array, 0, 1, 0)
|
||||
Z_PARAM_FUNC(BG(user_compare_fci), BG(user_compare_fci_cache))
|
||||
ZEND_PARSE_PARAMETERS_END_EX( PHP_ARRAY_CMP_FUNC_RESTORE(); return );
|
||||
|
||||
|
@ -2467,7 +2467,7 @@ PHP_FUNCTION(extract)
|
|||
zend_array *symbol_table;
|
||||
|
||||
ZEND_PARSE_PARAMETERS_START(1, 3)
|
||||
Z_PARAM_ARRAY(var_array_param)
|
||||
Z_PARAM_ARRAY_EX2(var_array_param, 0, 1, 0)
|
||||
Z_PARAM_OPTIONAL
|
||||
Z_PARAM_LONG(extract_type)
|
||||
Z_PARAM_ZVAL_EX(prefix, 0, 1)
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue