Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
1 change: 1 addition & 0 deletions Zend/zend_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -4238,6 +4238,7 @@ ZEND_API zend_result zend_fcall_info_init(zval *callable, uint32_t check_flags,
fci->param_count = 0;
fci->params = NULL;
fci->named_params = NULL;
fci->consume_params = 0;

return SUCCESS;
}
Expand Down
2 changes: 2 additions & 0 deletions Zend/zend_API.h
Original file line number Diff line number Diff line change
Expand Up @@ -54,6 +54,7 @@ typedef struct _zend_fcall_info {
* integrate APIs like call_user_func_array(). The usual restriction that
* there may not be position arguments after named arguments applies. */
HashTable *named_params;
uint32_t consume_params;
} zend_fcall_info;

typedef struct _zend_fcall_info_cache {
Expand Down Expand Up @@ -339,6 +340,7 @@ typedef struct _zend_fcall_info_cache {

#define ZEND_FCI_INITIALIZED(fci) ((fci).size != 0)
#define ZEND_FCC_INITIALIZED(fcc) ((fcc).function_handler != NULL)
#define ZEND_FCI_CONSUME_PARAM(arg_num) (1u << ((arg_num) - 1))

ZEND_API int zend_next_free_module(void);

Expand Down
1 change: 1 addition & 0 deletions Zend/zend_closures.c
Original file line number Diff line number Diff line change
Expand Up @@ -155,6 +155,7 @@ ZEND_METHOD(Closure, call)
fci_cache.object = fci.object = newobj;

fci.size = sizeof(fci);
fci.consume_params = 0;
ZVAL_OBJ(&fci.function_name, &closure->std);
ZVAL_UNDEF(&closure_result);
fci.retval = &closure_result;
Expand Down
1 change: 1 addition & 0 deletions Zend/zend_exceptions.c
Original file line number Diff line number Diff line change
Expand Up @@ -687,6 +687,7 @@ ZEND_METHOD(Exception, __toString)
fci.params = NULL;
fci.object = NULL;
fci.named_params = NULL;
fci.consume_params = 0;

zend_fcall_info_cache fcc;
fcc.function_handler = getTraceAsString;
Expand Down
15 changes: 14 additions & 1 deletion Zend/zend_execute_API.c
Original file line number Diff line number Diff line change
Expand Up @@ -797,6 +797,7 @@ zend_result _call_user_function_impl(zval *object, zval *function_name, zval *re
fci.param_count = param_count;
fci.params = params;
fci.named_params = named_params;
fci.consume_params = 0;

return zend_call_function(&fci, NULL);
}
Expand Down Expand Up @@ -864,6 +865,7 @@ zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_

call = zend_vm_stack_push_call_frame(call_info,
func, fci->param_count, object_or_called_scope);
bool has_consume = fci->consume_params != 0;

for (uint32_t i = 0; i < fci->param_count; i++) {
zval *param = ZEND_CALL_ARG(call, i+1);
Expand Down Expand Up @@ -905,7 +907,17 @@ zend_result zend_call_function(zend_fcall_info *fci, zend_fcall_info_cache *fci_
}

if (EXPECTED(!must_wrap)) {
ZVAL_COPY(param, arg);
if (EXPECTED(!has_consume)) {
ZVAL_COPY(param, arg);
} else {
if (UNEXPECTED(i < 32 && (fci->consume_params & (1u << i))
&& !Z_ISREF_P(arg) && arg == &fci->params[i])) {
ZVAL_COPY_VALUE(param, arg);
ZVAL_UNDEF(arg);
} else {
ZVAL_COPY(param, arg);
}
}
} else {
Z_TRY_ADDREF_P(arg);
ZVAL_NEW_REF(param, arg);
Expand Down Expand Up @@ -1091,6 +1103,7 @@ ZEND_API void zend_call_known_function(
fci.param_count = param_count;
fci.params = params;
fci.named_params = named_params;
fci.consume_params = 0;
ZVAL_UNDEF(&fci.function_name); /* Unused */

fcic.function_handler = fn;
Expand Down
1 change: 1 addition & 0 deletions ext/dom/xpath_callbacks.c
Original file line number Diff line number Diff line change
Expand Up @@ -408,6 +408,7 @@ static zend_result php_dom_xpath_callback_dispatch(php_dom_xpath_callbacks *xpat
fci.param_count = param_count;
fci.params = params;
fci.named_params = NULL;
fci.consume_params = 0;
ZVAL_STRINGL(&fci.function_name, function_name, function_name_length);

zend_call_function(&fci, NULL);
Expand Down
1 change: 1 addition & 0 deletions ext/ffi/ffi.c
Original file line number Diff line number Diff line change
Expand Up @@ -950,6 +950,7 @@ static void zend_ffi_callback_trampoline(ffi_cif* cif, void* ret, void** args, v
fci.object = NULL;
fci.param_count = callback_data->arg_count;
fci.named_params = NULL;
fci.consume_params = 0;

if (callback_data->type->func.args) {
int n = 0;
Expand Down
1 change: 1 addition & 0 deletions ext/standard/array.c
Original file line number Diff line number Diff line change
Expand Up @@ -6409,6 +6409,7 @@ PHP_FUNCTION(array_reduce)
fci.retval = return_value;
fci.param_count = 2;
fci.params = args;
fci.consume_params = ZEND_FCI_CONSUME_PARAM(1);

ZEND_HASH_FOREACH_VAL(htbl, operand) {
ZVAL_COPY_VALUE(&args[0], return_value);
Expand Down
Loading